mirror of https://github.com/nmlgc/ReC98.git
81 lines
2.6 KiB
C++
81 lines
2.6 KiB
C++
/// Uncompressed, 5-plane, 16-color + alpha, arbitrary-size sprite format
|
|
/// ---------------------------------------------------------------------
|
|
#define BOS_MAGIC "BOSS"
|
|
|
|
// On-disk per-file header. Not the same as for .GRC!
|
|
struct bos_header_t {
|
|
char magic[sizeof(BOS_MAGIC) - 1];
|
|
uint8_t vram_w;
|
|
int8_t zero;
|
|
uint8_t h;
|
|
int8_t unknown;
|
|
spriteformat_header_inner_t inner;
|
|
};
|
|
|
|
// Shared loading subfunctions
|
|
// ---------------------------
|
|
|
|
// Separate function to work around the `Condition is always true/false` and
|
|
// `Unreachable code` warnings
|
|
inline void bos_header_load_palette(Palette4 &pal, bool load) {
|
|
if(load) {
|
|
arc_file_get_far(pal);
|
|
} else {
|
|
arc_file_seek(sizeof(spriteformat_header_t<bos_header_t>));
|
|
}
|
|
}
|
|
|
|
#define bos_header_load(that, plane_size, fn, needlessly_load_the_palette) \
|
|
union { \
|
|
bos_header_t outer; \
|
|
Palette4 pal; \
|
|
int8_t space[50]; \
|
|
} header; \
|
|
\
|
|
arc_file_load(fn); \
|
|
\
|
|
arc_file_get_far(header.outer); \
|
|
that->vram_w = header.outer.vram_w; \
|
|
that->h = header.outer.h; \
|
|
that->bos_image_count = header.outer.inner.image_count; \
|
|
plane_size = (that->vram_w * that->h); \
|
|
bos_header_load_palette(header.pal, needlessly_load_the_palette);
|
|
// ---------------------------
|
|
|
|
/// Shared blitting subfunctions
|
|
/// ----------------------------
|
|
|
|
// Part of ZUN's attempt at clipping at the left or right edges of VRAM, by
|
|
// comparing [vram_offset] against the value returned from this function.
|
|
inline vram_y_t vram_intended_y_for(
|
|
vram_offset_t vram_offset, screen_x_t first_x
|
|
) {
|
|
return (first_x < 0)
|
|
? ((vram_offset / ROW_SIZE) + 1)
|
|
: ((vram_offset / ROW_SIZE) + 0);
|
|
}
|
|
|
|
#define vram_offset_at_intended_y_16(vram_offset, intended_y) \
|
|
(((vram_offset + 0) / ROW_SIZE) == intended_y) && \
|
|
(((vram_offset + 1) / ROW_SIZE) == intended_y)
|
|
|
|
#define vram_unput_masked_emptyopt(plane, offset, bit_count, mask, tmp_dots) \
|
|
graph_accesspage_func(1); \
|
|
VRAM_SNAP(tmp_dots, plane, offset, bit_count); \
|
|
if(tmp_dots) { \
|
|
graph_accesspage_func(0); \
|
|
VRAM_CHUNK(plane, offset, bit_count) |= (mask & tmp_dots); \
|
|
}
|
|
|
|
#define vram_unput_masked_emptyopt_planar(offset, bit_count, mask, tmp_dots) \
|
|
vram_unput_masked_emptyopt(B, offset, bit_count, mask, tmp_dots); \
|
|
vram_unput_masked_emptyopt(R, offset, bit_count, mask, tmp_dots); \
|
|
vram_unput_masked_emptyopt(G, offset, bit_count, mask, tmp_dots); \
|
|
vram_unput_masked_emptyopt(E, offset, bit_count, mask, tmp_dots);
|
|
/// ----------------------------
|
|
|
|
/// All functions that operate on this format are implemented redundantly for
|
|
/// both CBossEntity, CBossAnim, and CPlayerAnim with their own respective
|
|
/// entity arrays.
|
|
/// ---------------------------------------------------------------------
|