ReC98/th01/formats/bos.hpp

88 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];
// Yes, this means that the *format* itself isn't actually restricted to
// word-aligned / 16w×h sizes, …
uint8_t vram_w;
int8_t zero;
uint8_t h;
int8_t unknown;
spriteformat_header_inner_t inner;
};
#define BOS_IMAGES_PER_SLOT 8
// In-memory slot structures
struct bos_image_t {
// … as these types would suggest. That's purely an implementation choice.
Planar<dots16_t *> planes;
dots16_t *alpha;
};
struct bos_t {
bos_image_t image[BOS_IMAGES_PER_SLOT];
};
// Shared loading and freeing 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);
#define bos_image_new(image, plane_size) \
image.alpha = new dots16_t[plane_size / 2]; \
image.planes.B = new dots16_t[plane_size / 2]; \
image.planes.R = new dots16_t[plane_size / 2]; \
image.planes.G = new dots16_t[plane_size / 2]; \
image.planes.E = new dots16_t[plane_size / 2];
// Always setting the pointer to NULL, for a change...
#define bos_image_ptr_free(ptr) \
if(ptr) { \
delete[] ptr; \
} \
ptr = NULL;
#define bos_free(slot_ptr) \
for(int image = 0; image < BOS_IMAGES_PER_SLOT; image++) { \
bos_image_ptr_free(slot_ptr.image[image].alpha); \
bos_image_ptr_free(slot_ptr.image[image].planes.B); \
bos_image_ptr_free(slot_ptr.image[image].planes.R); \
bos_image_ptr_free(slot_ptr.image[image].planes.G); \
bos_image_ptr_free(slot_ptr.image[image].planes.E); \
}
// ---------------------------------------
/// All functions that operate on this format are implemented redundantly for
/// both CBossEntity and CBossAnim, with their own respective entity arrays.
/// ---------------------------------------------------------------------