ReC98/th01/formats/bos.hpp

81 lines
2.6 KiB
C++
Raw Normal View History

/// 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.
/// ---------------------------------------------------------------------