2020-08-06 17:02:02 +00:00
|
|
|
|
#include "ReC98.h"
|
2020-08-16 13:54:32 +00:00
|
|
|
|
#include "th01/math/area.hpp"
|
2020-08-08 18:12:22 +00:00
|
|
|
|
#include "th01/math/wave.hpp"
|
2020-08-08 18:52:23 +00:00
|
|
|
|
#include "th01/hardware/egc.h"
|
2020-08-05 14:07:21 +00:00
|
|
|
|
#include "th01/hardware/graph.h"
|
2020-10-10 13:03:04 +00:00
|
|
|
|
#include "th01/hardware/planar.h"
|
2020-08-05 11:30:55 +00:00
|
|
|
|
#include "th01/formats/sprfmt_h.hpp"
|
|
|
|
|
#include "th01/formats/pf.hpp"
|
2020-08-05 10:34:38 +00:00
|
|
|
|
#include "th01/formats/bos.hpp"
|
2020-09-22 19:45:41 +00:00
|
|
|
|
#include "th01/main/playfld.hpp"
|
|
|
|
|
#include "th01/main/player/orb.hpp"
|
2020-09-23 21:28:50 +00:00
|
|
|
|
#include "th01/main/boss/entity_a.hpp"
|
2020-08-05 10:34:38 +00:00
|
|
|
|
|
2020-10-10 13:03:04 +00:00
|
|
|
|
// Slot structures
|
|
|
|
|
// ---------------
|
|
|
|
|
// Both CBossEntity and CBossAnim choose to restrict themselves to
|
|
|
|
|
// word-aligned / 16w×h image sizes, even though .BOS itself is byte-aligned.
|
|
|
|
|
|
|
|
|
|
#define BOS_IMAGES_PER_SLOT 8
|
|
|
|
|
|
|
|
|
|
struct bos_image_t {
|
|
|
|
|
Planar<dots16_t *> planes;
|
|
|
|
|
dots16_t *alpha;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct bos_t {
|
|
|
|
|
bos_image_t image[BOS_IMAGES_PER_SLOT];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#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); \
|
|
|
|
|
}
|
|
|
|
|
// ---------------
|
2020-08-05 14:07:21 +00:00
|
|
|
|
|
2020-09-23 21:28:50 +00:00
|
|
|
|
/// Entities
|
|
|
|
|
/// --------
|
|
|
|
|
extern bos_t bos_entity_images[BOS_ENTITY_SLOT_COUNT];
|
|
|
|
|
extern bool bos_header_only;
|
|
|
|
|
|
2020-08-05 10:34:38 +00:00
|
|
|
|
void bos_reset_all_broken(void)
|
|
|
|
|
{
|
2020-09-23 21:28:50 +00:00
|
|
|
|
for(int slot = 0; slot < 10; slot++) { // should be BOS_ENTITY_SLOT_COUNT
|
2020-08-05 10:34:38 +00:00
|
|
|
|
for(int image = 0; image < BOS_IMAGES_PER_SLOT; image++) {
|
2020-09-23 21:28:50 +00:00
|
|
|
|
bos_entity_images[slot].image[image].alpha = NULL;
|
|
|
|
|
bos_entity_images[slot].image[image].planes.B = NULL;
|
|
|
|
|
bos_entity_images[slot].image[image].planes.R = NULL;
|
|
|
|
|
bos_entity_images[slot].image[image].planes.G = NULL;
|
|
|
|
|
bos_entity_images[slot].image[image].planes.E = NULL;
|
2020-08-05 10:34:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-05 11:30:55 +00:00
|
|
|
|
|
2020-09-23 21:28:50 +00:00
|
|
|
|
int CBossEntity::load(const char fn[PF_FN_LEN], int slot)
|
2020-08-05 11:30:55 +00:00
|
|
|
|
{
|
2020-09-25 12:52:38 +00:00
|
|
|
|
int plane_size;
|
2020-08-05 11:30:55 +00:00
|
|
|
|
|
2020-10-08 10:55:30 +00:00
|
|
|
|
bos_header_load(this, plane_size, fn, true);
|
2020-08-05 11:30:55 +00:00
|
|
|
|
if(!bos_header_only) {
|
2020-09-23 19:48:48 +00:00
|
|
|
|
bos_entity_free(slot);
|
2020-08-05 11:30:55 +00:00
|
|
|
|
for(int i = 0; bos_image_count > i; i++) {
|
2020-09-25 12:52:38 +00:00
|
|
|
|
#define image bos_entity_images[slot].image[i]
|
|
|
|
|
bos_image_new(image, plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.alpha), plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.planes.B), plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.planes.R), plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.planes.G), plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.planes.E), plane_size);
|
|
|
|
|
#undef image
|
2020-08-05 11:30:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bos_slot = slot;
|
|
|
|
|
arc_file_free();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2020-08-05 13:37:35 +00:00
|
|
|
|
|
2020-09-23 21:28:50 +00:00
|
|
|
|
void CBossEntity::metadata_get(
|
2020-08-21 18:13:08 +00:00
|
|
|
|
int &image_count,
|
|
|
|
|
unsigned char &slot,
|
|
|
|
|
vram_byte_amount_t &vram_w,
|
|
|
|
|
pixel_t &h
|
2020-08-05 13:37:35 +00:00
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
image_count = this->bos_image_count;
|
|
|
|
|
slot = this->bos_slot;
|
|
|
|
|
h = this->h;
|
|
|
|
|
vram_w = this->vram_w;
|
|
|
|
|
}
|
2020-08-05 14:07:21 +00:00
|
|
|
|
|
|
|
|
|
/// Blitting
|
|
|
|
|
/// --------
|
2020-08-20 19:59:45 +00:00
|
|
|
|
void CBossEntity::put_8(screen_x_t left, vram_y_t top, int image) const
|
2020-08-05 14:07:21 +00:00
|
|
|
|
{
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset_row = vram_offset_divmul(left, top);
|
|
|
|
|
vram_offset_t vram_offset;
|
2020-08-05 14:07:21 +00:00
|
|
|
|
size_t bos_p = 0;
|
2020-08-21 18:13:08 +00:00
|
|
|
|
pixel_t bos_y;
|
|
|
|
|
vram_word_amount_t bos_word_x;
|
2020-08-20 19:59:45 +00:00
|
|
|
|
vram_y_t intended_y;
|
2020-08-05 14:07:21 +00:00
|
|
|
|
|
2020-09-23 21:28:50 +00:00
|
|
|
|
bos_image_t &bos = bos_entity_images[bos_slot].image[image];
|
2020-08-05 14:07:21 +00:00
|
|
|
|
if(bos_image_count <= image) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(bos_y = 0; h > bos_y; bos_y++) {
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset = vram_offset_row;
|
2020-08-05 14:07:21 +00:00
|
|
|
|
intended_y = vram_intended_y_for(vram_offset_row, left);
|
|
|
|
|
for(bos_word_x = 0; (vram_w / 2) > bos_word_x; bos_word_x++) {
|
|
|
|
|
if((vram_offset / ROW_SIZE) == intended_y) {
|
|
|
|
|
if(~bos.alpha[bos_p]) {
|
2020-10-10 13:03:04 +00:00
|
|
|
|
vram_erase(vram_offset, ~bos.alpha[bos_p], 16);
|
2020-08-05 14:07:21 +00:00
|
|
|
|
vram_or_emptyopt(B, vram_offset, bos.planes.B[bos_p], 16);
|
|
|
|
|
vram_or_emptyopt(R, vram_offset, bos.planes.R[bos_p], 16);
|
|
|
|
|
vram_or_emptyopt(G, vram_offset, bos.planes.G[bos_p], 16);
|
|
|
|
|
vram_or_emptyopt(E, vram_offset, bos.planes.E[bos_p], 16);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
vram_offset += 2;
|
|
|
|
|
bos_p++;
|
|
|
|
|
}
|
|
|
|
|
vram_offset_row += ROW_SIZE;
|
|
|
|
|
if(vram_offset_row >= PLANE_SIZE) { // Clip at the bottom edge
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-20 19:59:45 +00:00
|
|
|
|
void CBossEntity::put_1line(
|
2020-08-21 18:13:08 +00:00
|
|
|
|
screen_x_t left, vram_y_t y, int image, pixel_t row
|
2020-08-20 19:59:45 +00:00
|
|
|
|
) const
|
2020-08-06 17:02:02 +00:00
|
|
|
|
{
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset_row = vram_offset_shift(left, y);
|
2020-08-21 18:13:08 +00:00
|
|
|
|
vram_word_amount_t bos_word_x;
|
2020-08-06 17:02:02 +00:00
|
|
|
|
size_t bos_p = 0;
|
2020-08-20 19:59:45 +00:00
|
|
|
|
vram_y_t intended_y;
|
2020-08-06 17:02:02 +00:00
|
|
|
|
char first_bit = (left & (BYTE_DOTS - 1));
|
|
|
|
|
char other_shift = ((1 * BYTE_DOTS) - first_bit);
|
|
|
|
|
|
2020-09-23 21:28:50 +00:00
|
|
|
|
bos_image_t &bos = bos_entity_images[bos_slot].image[image];
|
2020-08-06 17:02:02 +00:00
|
|
|
|
if(bos_image_count <= image) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset = vram_offset_row;
|
2020-08-06 17:02:02 +00:00
|
|
|
|
intended_y = vram_intended_y_for(vram_offset_row, left);
|
|
|
|
|
|
|
|
|
|
bos_p = ((vram_w / 2) * row);
|
|
|
|
|
for(bos_word_x = 0; (vram_w / 2) > bos_word_x; bos_word_x++) {
|
|
|
|
|
if((vram_offset / ROW_SIZE) == intended_y) {
|
|
|
|
|
struct {
|
|
|
|
|
twobyte_t alpha, B, R, G, E;
|
|
|
|
|
} cur;
|
|
|
|
|
|
|
|
|
|
cur.alpha.v = ~bos.alpha[bos_p];
|
|
|
|
|
cur.B.v = bos.planes.B[bos_p];
|
|
|
|
|
cur.R.v = bos.planes.R[bos_p];
|
|
|
|
|
cur.G.v = bos.planes.G[bos_p];
|
|
|
|
|
cur.E.v = bos.planes.E[bos_p];
|
|
|
|
|
|
|
|
|
|
#define vram_byte(plane, byte) \
|
|
|
|
|
(VRAM_PLANE_##plane + vram_offset)[byte]
|
2020-08-21 18:13:08 +00:00
|
|
|
|
register vram_byte_amount_t byte;
|
2020-08-06 17:02:02 +00:00
|
|
|
|
if(first_bit == 0) {
|
2020-08-21 18:13:08 +00:00
|
|
|
|
for(byte = 0; byte < sizeof(dots16_t); byte++) {
|
2020-08-06 17:02:02 +00:00
|
|
|
|
grcg_setcolor_rmw(0);
|
|
|
|
|
vram_byte(B, byte) = cur.alpha.u[byte];
|
|
|
|
|
grcg_off();
|
|
|
|
|
|
|
|
|
|
vram_byte(B, byte) |= cur.B.u[byte];
|
|
|
|
|
vram_byte(R, byte) |= cur.R.u[byte];
|
|
|
|
|
vram_byte(G, byte) |= cur.G.u[byte];
|
|
|
|
|
vram_byte(E, byte) |= cur.E.u[byte];
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2020-08-21 18:13:08 +00:00
|
|
|
|
for(byte = 0; byte < sizeof(dots16_t); byte++) {
|
2020-08-06 17:02:02 +00:00
|
|
|
|
grcg_setcolor_rmw(0);
|
|
|
|
|
vram_byte(B, byte + 0) = (cur.alpha.u[byte] >> first_bit);
|
|
|
|
|
vram_byte(B, byte + 1) = (cur.alpha.u[byte] << other_shift);
|
|
|
|
|
grcg_off();
|
|
|
|
|
|
|
|
|
|
vram_byte(B, byte + 0) |= (cur.B.u[byte] >> first_bit);
|
|
|
|
|
vram_byte(R, byte + 0) |= (cur.R.u[byte] >> first_bit);
|
|
|
|
|
vram_byte(G, byte + 0) |= (cur.G.u[byte] >> first_bit);
|
|
|
|
|
vram_byte(E, byte + 0) |= (cur.E.u[byte] >> first_bit);
|
|
|
|
|
vram_byte(B, byte + 1) |= (cur.B.u[byte] << other_shift);
|
|
|
|
|
vram_byte(R, byte + 1) |= (cur.R.u[byte] << other_shift);
|
|
|
|
|
vram_byte(G, byte + 1) |= (cur.G.u[byte] << other_shift);
|
|
|
|
|
vram_byte(E, byte + 1) |= (cur.E.u[byte] << other_shift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#undef vram_byte
|
|
|
|
|
}
|
|
|
|
|
vram_offset += 2;
|
|
|
|
|
bos_p++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-06 18:23:52 +00:00
|
|
|
|
void pascal near vram_snap_masked(
|
2020-08-21 17:18:28 +00:00
|
|
|
|
dots16_t &dst, dots8_t plane[], vram_offset_t vram_offset, dots16_t mask
|
2020-08-06 18:23:52 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
dst = (reinterpret_cast<dots16_t &>(plane[vram_offset]) & mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pascal near vram_put_bg_fg(
|
2020-08-21 17:18:28 +00:00
|
|
|
|
sdots16_t fg, dots8_t plane[], vram_offset_t vram_offset, sdots16_t bg_masked
|
2020-08-06 18:23:52 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
reinterpret_cast<dots16_t &>(plane[vram_offset]) = (fg | bg_masked);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pascal near vram_put_unaligned_bg_fg(
|
|
|
|
|
sdots16_t fg,
|
|
|
|
|
dots8_t plane[],
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset,
|
2020-08-06 18:23:52 +00:00
|
|
|
|
uint16_t bg_masked,
|
|
|
|
|
char first_bit
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
sdots16_t fg_shifted = (fg >> first_bit) + (fg << (16 - first_bit));
|
|
|
|
|
reinterpret_cast<dots16_t &>(plane[vram_offset]) = (fg_shifted | bg_masked);
|
|
|
|
|
}
|
2020-08-07 20:58:08 +00:00
|
|
|
|
|
|
|
|
|
#define vram_snap_masked_planar(dst, vram_offset, mask) \
|
|
|
|
|
vram_snap_masked(dst.B, VRAM_PLANE_B, vram_offset, mask); \
|
|
|
|
|
vram_snap_masked(dst.R, VRAM_PLANE_R, vram_offset, mask); \
|
|
|
|
|
vram_snap_masked(dst.G, VRAM_PLANE_G, vram_offset, mask); \
|
|
|
|
|
vram_snap_masked(dst.E, VRAM_PLANE_E, vram_offset, mask);
|
|
|
|
|
|
|
|
|
|
#define vram_put_bg_fg_planar(vram_offset, bg, fg) \
|
|
|
|
|
vram_put_bg_fg(fg.B, VRAM_PLANE_B, vram_offset, bg.B); \
|
|
|
|
|
vram_put_bg_fg(fg.R, VRAM_PLANE_R, vram_offset, bg.R); \
|
|
|
|
|
vram_put_bg_fg(fg.G, VRAM_PLANE_G, vram_offset, bg.G); \
|
|
|
|
|
vram_put_bg_fg(fg.E, VRAM_PLANE_E, vram_offset, bg.E);
|
|
|
|
|
|
2020-08-08 21:11:38 +00:00
|
|
|
|
#define vram_put_bg_word_planar(vram_offset, bg, planes, p) \
|
|
|
|
|
vram_put_bg_fg(planes.B[p], VRAM_PLANE_B, vram_offset, bg.B); \
|
|
|
|
|
vram_put_bg_fg(planes.R[p], VRAM_PLANE_R, vram_offset, bg.R); \
|
|
|
|
|
vram_put_bg_fg(planes.G[p], VRAM_PLANE_G, vram_offset, bg.G); \
|
|
|
|
|
vram_put_bg_fg(planes.E[p], VRAM_PLANE_E, vram_offset, bg.E);
|
|
|
|
|
|
2020-08-07 20:58:08 +00:00
|
|
|
|
#define vram_put_unaligned_bg_fg_planar(vram_offset, bg, fg, first_bit) \
|
|
|
|
|
vram_put_unaligned_bg_fg(fg.B, VRAM_PLANE_B, vram_offset, bg.B, first_bit); \
|
|
|
|
|
vram_put_unaligned_bg_fg(fg.R, VRAM_PLANE_R, vram_offset, bg.R, first_bit); \
|
|
|
|
|
vram_put_unaligned_bg_fg(fg.G, VRAM_PLANE_G, vram_offset, bg.G, first_bit); \
|
|
|
|
|
vram_put_unaligned_bg_fg(fg.E, VRAM_PLANE_E, vram_offset, bg.E, first_bit);
|
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
|
void CBossEntity::unput_and_put_1line(
|
2020-08-21 18:13:08 +00:00
|
|
|
|
screen_x_t left, vram_y_t y, int image, pixel_t row
|
2020-08-20 19:59:45 +00:00
|
|
|
|
) const
|
2020-08-07 20:58:08 +00:00
|
|
|
|
{
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset_row = vram_offset_shift(left, y);
|
2020-08-21 18:13:08 +00:00
|
|
|
|
vram_word_amount_t bos_word_x;
|
2020-08-07 20:58:08 +00:00
|
|
|
|
size_t bos_p = 0;
|
2020-08-20 19:59:45 +00:00
|
|
|
|
vram_y_t intended_y;
|
2020-08-07 20:58:08 +00:00
|
|
|
|
char first_bit = (left & (BYTE_DOTS - 1));
|
|
|
|
|
char other_shift = ((2 * BYTE_DOTS) - first_bit);
|
|
|
|
|
Planar<dots16_t> bg_masked;
|
|
|
|
|
dots16_t mask_unaligned;
|
|
|
|
|
|
2020-09-23 21:28:50 +00:00
|
|
|
|
bos_image_t &bos = bos_entity_images[bos_slot].image[image];
|
2020-08-07 20:58:08 +00:00
|
|
|
|
if(bos_image_count <= image) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset = vram_offset_row;
|
2020-08-07 20:58:08 +00:00
|
|
|
|
intended_y = vram_intended_y_for(vram_offset_row, left);
|
|
|
|
|
|
|
|
|
|
bos_p = ((vram_w / 2) * row);
|
|
|
|
|
for(bos_word_x = 0; (vram_w / 2) > bos_word_x; bos_word_x++) {
|
|
|
|
|
if((vram_offset / ROW_SIZE) == intended_y) {
|
|
|
|
|
Planar<dots16_t> fg;
|
|
|
|
|
|
|
|
|
|
dots16_t alpha = bos.alpha[bos_p];
|
|
|
|
|
fg.B = bos.planes.B[bos_p];
|
|
|
|
|
fg.R = bos.planes.R[bos_p];
|
|
|
|
|
fg.G = bos.planes.G[bos_p];
|
|
|
|
|
fg.E = bos.planes.E[bos_p];
|
|
|
|
|
if(first_bit == 0) {
|
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
|
vram_snap_masked_planar(bg_masked, vram_offset, alpha);
|
|
|
|
|
graph_accesspage_func(0);
|
|
|
|
|
vram_put_bg_fg_planar(vram_offset, bg_masked, fg);
|
|
|
|
|
} else {
|
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
|
mask_unaligned = (
|
|
|
|
|
(alpha >> first_bit) + (alpha << other_shift)
|
|
|
|
|
);
|
|
|
|
|
vram_snap_masked_planar(bg_masked, vram_offset, mask_unaligned);
|
|
|
|
|
graph_accesspage_func(0);
|
|
|
|
|
vram_put_unaligned_bg_fg_planar(
|
|
|
|
|
vram_offset, bg_masked, fg, first_bit
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
vram_offset += 2;
|
|
|
|
|
bos_p++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-07 21:44:18 +00:00
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
|
void CBossEntity::unput_and_put_8(
|
|
|
|
|
screen_x_t left, vram_y_t top, int image
|
|
|
|
|
) const
|
2020-08-07 21:44:18 +00:00
|
|
|
|
{
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset_row = vram_offset_divmul(left, top);
|
|
|
|
|
vram_offset_t vram_offset;
|
2020-08-07 21:44:18 +00:00
|
|
|
|
size_t bos_p = 0;
|
2020-08-21 18:13:08 +00:00
|
|
|
|
pixel_t bos_y;
|
|
|
|
|
vram_word_amount_t bos_word_x;
|
2020-08-20 19:59:45 +00:00
|
|
|
|
vram_y_t intended_y;
|
2020-08-07 21:44:18 +00:00
|
|
|
|
Planar<dots16_t> bg_masked;
|
|
|
|
|
|
2020-09-23 21:28:50 +00:00
|
|
|
|
bos_image_t &bos = bos_entity_images[bos_slot].image[image];
|
2020-08-07 21:44:18 +00:00
|
|
|
|
if(bos_image_count <= image) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(bos_y = 0; h > bos_y; bos_y++) {
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset = vram_offset_row;
|
2020-08-07 21:44:18 +00:00
|
|
|
|
intended_y = vram_intended_y_for(vram_offset_row, left);
|
|
|
|
|
for(bos_word_x = 0; (vram_w / 2) > bos_word_x; bos_word_x++) {
|
|
|
|
|
if(
|
|
|
|
|
vram_offset_at_intended_y_16(vram_offset, intended_y) &&
|
|
|
|
|
(vram_offset >= 0) // Clip at the top edge
|
|
|
|
|
) {
|
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
|
if(bos.alpha[bos_p]) {
|
|
|
|
|
vram_snap_planar_masked(
|
|
|
|
|
bg_masked, vram_offset, 16, bos.alpha[bos_p]
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
bg_masked.B = bg_masked.R = bg_masked.G = bg_masked.E = 0;
|
|
|
|
|
}
|
|
|
|
|
graph_accesspage_func(0);
|
|
|
|
|
VRAM_PUT(B, vram_offset, bos.planes.B[bos_p] | bg_masked.B, 16);
|
|
|
|
|
VRAM_PUT(R, vram_offset, bos.planes.R[bos_p] | bg_masked.R, 16);
|
|
|
|
|
VRAM_PUT(G, vram_offset, bos.planes.G[bos_p] | bg_masked.G, 16);
|
|
|
|
|
VRAM_PUT(E, vram_offset, bos.planes.E[bos_p] | bg_masked.E, 16);
|
|
|
|
|
}
|
|
|
|
|
vram_offset += 2;
|
|
|
|
|
bos_p++;
|
|
|
|
|
}
|
|
|
|
|
vram_offset_row += ROW_SIZE;
|
|
|
|
|
if(vram_offset_row >= PLANE_SIZE) { // Clip at the bottom edge
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-08 16:46:17 +00:00
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
|
void CBossEntity::unput_8(screen_x_t left, vram_y_t top, int image) const
|
2020-08-08 16:46:17 +00:00
|
|
|
|
{
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset_row = vram_offset_divmul(left, top);
|
|
|
|
|
vram_offset_t vram_offset;
|
2020-08-21 18:13:08 +00:00
|
|
|
|
pixel_t bos_y;
|
|
|
|
|
vram_word_amount_t bos_word_x;
|
2020-08-08 16:46:17 +00:00
|
|
|
|
size_t bos_p = 0;
|
2020-08-20 19:59:45 +00:00
|
|
|
|
vram_y_t intended_y;
|
2020-08-08 16:46:17 +00:00
|
|
|
|
|
2020-09-23 21:28:50 +00:00
|
|
|
|
bos_image_t &bos = bos_entity_images[bos_slot].image[image];
|
2020-08-08 16:46:17 +00:00
|
|
|
|
if(bos_image_count <= image) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(bos_y = 0; h > bos_y; bos_y++) {
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset = vram_offset_row;
|
2020-08-08 16:46:17 +00:00
|
|
|
|
intended_y = vram_intended_y_for(vram_offset_row, left);
|
|
|
|
|
for(bos_word_x = 0; (vram_w / 2) > bos_word_x; bos_word_x++) {
|
|
|
|
|
if(
|
|
|
|
|
vram_offset_at_intended_y_16(vram_offset, intended_y) &&
|
|
|
|
|
(vram_offset >= 0) // Clip at the top edge
|
|
|
|
|
) {
|
2020-10-10 13:03:04 +00:00
|
|
|
|
vram_erase_on_0(vram_offset, ~bos.alpha[bos_p], 16);
|
2020-08-08 16:46:17 +00:00
|
|
|
|
|
|
|
|
|
if(~bos.alpha[bos_p]) {
|
|
|
|
|
dots16_t bg_dots;
|
|
|
|
|
vram_unput_masked_emptyopt_planar(
|
|
|
|
|
vram_offset, 16, ~bos.alpha[bos_p], bg_dots
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
vram_offset += 2;
|
|
|
|
|
bos_p++;
|
|
|
|
|
}
|
|
|
|
|
vram_offset_row += ROW_SIZE;
|
|
|
|
|
if(vram_offset_row >= PLANE_SIZE) { // Clip at the bottom edge
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
graph_accesspage_func(0);
|
|
|
|
|
}
|
2020-08-08 18:12:22 +00:00
|
|
|
|
|
|
|
|
|
#define wave_func(func, left, top, image, len, amp, phase) \
|
|
|
|
|
int t = phase; \
|
2020-08-21 18:13:08 +00:00
|
|
|
|
for(pixel_t bos_y = 0; h > bos_y; bos_y++) { \
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t x = (wave_x(amp, t) + left); \
|
2020-08-08 18:12:22 +00:00
|
|
|
|
t += (0x100 / len); \
|
|
|
|
|
func(x, (top + bos_y), image, bos_y); \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBossEntity::wave_put(
|
2020-08-21 18:13:08 +00:00
|
|
|
|
screen_x_t left, vram_y_t top, int image, int len, pixel_t amp, int phase
|
2020-08-08 18:12:22 +00:00
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
wave_func(put_1line, left, top, image, len, amp, phase);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBossEntity::wave_unput_and_put(
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t left, vram_y_t top, int image, int len, int amp, int phase
|
2020-08-08 18:12:22 +00:00
|
|
|
|
) const
|
|
|
|
|
{
|
|
|
|
|
wave_func(unput_and_put_1line, left, top, image, len, amp, phase);
|
|
|
|
|
}
|
2020-08-08 18:52:23 +00:00
|
|
|
|
|
|
|
|
|
inline int word_align(int v) {
|
|
|
|
|
return (((v / 16) * 16) + 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CBossEntity::egc_sloppy_wave_unput_double_broken(
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t left_1, vram_y_t top, int,
|
2020-08-21 18:13:08 +00:00
|
|
|
|
int len_1, pixel_t amp_1, int phase_1,
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t left_2,
|
2020-08-21 18:13:08 +00:00
|
|
|
|
int len_2, pixel_t amp_2, int phase_2
|
2020-08-08 18:52:23 +00:00
|
|
|
|
) const
|
|
|
|
|
{
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t x_1;
|
2020-08-08 18:52:23 +00:00
|
|
|
|
int t_1 = phase_1;
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t x_2;
|
2020-08-08 18:52:23 +00:00
|
|
|
|
int t_2 = phase_2;
|
2020-08-21 18:13:08 +00:00
|
|
|
|
for(pixel_t bos_y = 0; h > bos_y; bos_y++) {
|
2020-08-08 18:52:23 +00:00
|
|
|
|
x_1 = wave_x(amp_1, t_1) + left_1;
|
|
|
|
|
x_2 = wave_x(amp_2, t_2) + left_2;
|
|
|
|
|
t_1 += (0x100 / len_1);
|
|
|
|
|
t_2 += (0x100 / len_2);
|
|
|
|
|
// ZUN bug: Shouldn't the [h] parameter be 1?
|
|
|
|
|
if(x_1 > x_2) {
|
|
|
|
|
egc_copy_rect_1_to_0_16(
|
|
|
|
|
x_2, (top + bos_y), word_align(x_1 - x_2), bos_y
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
egc_copy_rect_1_to_0_16(
|
|
|
|
|
(x_1 - vram_w), (top + bos_y), word_align(x_2 - x_1), bos_y
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-08 21:11:38 +00:00
|
|
|
|
|
2020-08-21 18:13:08 +00:00
|
|
|
|
void CBossEntity::unput_and_put_16x8_8(pixel_t bos_left, pixel_t bos_top) const
|
2020-08-08 21:11:38 +00:00
|
|
|
|
{
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset_row = vram_offset_shift(cur_left, cur_top);
|
2020-08-21 18:13:08 +00:00
|
|
|
|
pixel_t bos_row;
|
2020-08-08 21:11:38 +00:00
|
|
|
|
size_t bos_p = 0;
|
2020-08-20 19:59:45 +00:00
|
|
|
|
vram_y_t intended_y;
|
2020-08-08 21:11:38 +00:00
|
|
|
|
int image = bos_image;
|
|
|
|
|
Planar<dots16_t> bg_masked;
|
2020-09-23 21:28:50 +00:00
|
|
|
|
bos_image_t &bos = bos_entity_images[bos_slot].image[image];
|
2020-08-08 21:11:38 +00:00
|
|
|
|
|
|
|
|
|
// Yes, the macro form. Out of all places that could have required it, it
|
|
|
|
|
// had to be an originally unused function…
|
|
|
|
|
vram_offset_row += VRAM_OFFSET_SHIFT(bos_left, bos_top);
|
|
|
|
|
bos_p = (((vram_w / 2) * bos_top) + (bos_left / 16));
|
|
|
|
|
|
|
|
|
|
if(bos_image_count <= image) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(bos_row = 0; bos_row < 8; bos_row++) {
|
2020-08-21 17:18:28 +00:00
|
|
|
|
vram_offset_t vram_offset = vram_offset_row;
|
2020-08-08 21:11:38 +00:00
|
|
|
|
// Note the difference between this and vram_offset_at_intended_y_16()!
|
|
|
|
|
intended_y = (bos_left < 0)
|
|
|
|
|
? ((vram_offset_row / ROW_SIZE) - 1)
|
|
|
|
|
: ((vram_offset_row / ROW_SIZE) - 0);
|
|
|
|
|
if(
|
|
|
|
|
(((vram_offset + 1) / ROW_SIZE) == intended_y) &&
|
|
|
|
|
(vram_offset >= 0) // Clip at the top edge
|
|
|
|
|
) {
|
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
|
vram_snap_masked_planar(bg_masked, vram_offset, bos.alpha[bos_p]);
|
|
|
|
|
graph_accesspage_func(0);
|
|
|
|
|
vram_put_bg_word_planar(vram_offset, bg_masked, bos.planes, bos_p);
|
|
|
|
|
vram_offset += 2;
|
|
|
|
|
}
|
|
|
|
|
bos_p += (vram_w / 2);
|
|
|
|
|
vram_offset_row += ROW_SIZE;
|
|
|
|
|
if(vram_offset_row >= PLANE_SIZE) { // Clip at the bottom edge
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-05 14:07:21 +00:00
|
|
|
|
/// --------
|
2020-08-08 22:14:08 +00:00
|
|
|
|
|
|
|
|
|
void CBossEntity::pos_set(
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t left,
|
|
|
|
|
screen_y_t top,
|
2020-08-08 22:14:08 +00:00
|
|
|
|
int unknown,
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t move_clamp_left,
|
|
|
|
|
screen_x_t move_clamp_right,
|
|
|
|
|
screen_y_t move_clamp_top,
|
|
|
|
|
screen_y_t move_clamp_bottom
|
2020-08-08 22:14:08 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
this->cur_left = left;
|
|
|
|
|
this->cur_top = top;
|
|
|
|
|
this->unknown = unknown;
|
|
|
|
|
this->move_clamp.left = move_clamp_left;
|
|
|
|
|
this->move_clamp.right = move_clamp_right;
|
|
|
|
|
this->move_clamp.top = move_clamp_top;
|
|
|
|
|
this->move_clamp.bottom = move_clamp_bottom;
|
|
|
|
|
this->zero_2 = 0;
|
|
|
|
|
}
|
2020-08-08 22:23:35 +00:00
|
|
|
|
|
|
|
|
|
void CBossEntity::sloppy_unput() const
|
|
|
|
|
{
|
|
|
|
|
egc_copy_rect_1_to_0_16(cur_left, cur_top, (vram_w * BYTE_DOTS), h);
|
|
|
|
|
}
|
2020-08-09 10:23:29 +00:00
|
|
|
|
|
|
|
|
|
void CBossEntity::move_lock_unput_and_put_8(
|
2020-08-21 18:13:08 +00:00
|
|
|
|
int, pixel_t delta_x, pixel_t delta_y, int lock_frames
|
2020-08-09 10:23:29 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
if(move_lock_frame == 0) {
|
|
|
|
|
move(delta_x, delta_y);
|
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
|
screen_x_t unput_left = (prev_delta_x > 0)
|
2020-08-09 10:23:29 +00:00
|
|
|
|
? ((prev_left / BYTE_DOTS) * BYTE_DOTS)
|
|
|
|
|
: (((cur_left / BYTE_DOTS) * BYTE_DOTS) + (vram_w * BYTE_DOTS));
|
|
|
|
|
egc_copy_rect_1_to_0_16(unput_left, prev_top, 8, h);
|
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
|
vram_y_t unput_top = (cur_top > prev_top)
|
2020-08-09 10:23:29 +00:00
|
|
|
|
? prev_top
|
|
|
|
|
: (cur_top + h);
|
|
|
|
|
egc_copy_rect_1_to_0_16(
|
|
|
|
|
prev_left, unput_top, (vram_w << 3), abs(cur_top - prev_top)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
unput_and_put_8(cur_left, cur_top, bos_image);
|
|
|
|
|
|
|
|
|
|
move_lock_frame = 1;
|
|
|
|
|
} else if(move_lock_frame >= lock_frames) {
|
|
|
|
|
move_lock_frame = 0;
|
|
|
|
|
} else {
|
|
|
|
|
move_lock_frame++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-10 13:17:51 +00:00
|
|
|
|
|
|
|
|
|
void CBossEntity::move_lock_and_put_8(
|
2020-08-21 18:13:08 +00:00
|
|
|
|
int, pixel_t delta_x, pixel_t delta_y, int lock_frames
|
2020-08-10 13:17:51 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
if(move_lock_frame == 0) {
|
|
|
|
|
move(delta_x, delta_y);
|
|
|
|
|
put_8(cur_left, cur_top, bos_image);
|
|
|
|
|
move_lock_frame = 1;
|
|
|
|
|
} else if(move_lock_frame >= lock_frames) {
|
|
|
|
|
move_lock_frame = 0;
|
|
|
|
|
} else {
|
|
|
|
|
move_lock_frame++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-22 19:45:41 +00:00
|
|
|
|
|
|
|
|
|
static const pixel_t ORB_HITBOX_LEFT = ((ORB_W / 2) - (ORB_W / 4));
|
|
|
|
|
static const pixel_t ORB_HITBOX_TOP = ((ORB_H / 2) - (ORB_H / 4));
|
|
|
|
|
static const pixel_t ORB_HITBOX_RIGHT = ((ORB_W / 2) + (ORB_W / 4));
|
|
|
|
|
static const pixel_t ORB_HITBOX_BOTTOM = ((ORB_H / 2) + (ORB_H / 4));
|
|
|
|
|
|
|
|
|
|
bool16 CBossEntity::hittest_orb(void) const
|
|
|
|
|
{
|
|
|
|
|
if(hitbox_orb_inactive == true) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(
|
|
|
|
|
((hitbox_orb.left + cur_left - ORB_HITBOX_RIGHT) <= orb_prev_left) &&
|
|
|
|
|
((hitbox_orb.right + cur_left - ORB_HITBOX_LEFT) >= orb_prev_left) &&
|
|
|
|
|
((cur_top + hitbox_orb.top - ORB_HITBOX_BOTTOM) <= orb_prev_top) &&
|
|
|
|
|
((cur_top + hitbox_orb.bottom - ORB_HITBOX_TOP) >= orb_prev_top)
|
|
|
|
|
) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-09-23 19:48:48 +00:00
|
|
|
|
|
|
|
|
|
void bos_entity_free(int slot)
|
|
|
|
|
{
|
|
|
|
|
for(int image = 0; image < BOS_IMAGES_PER_SLOT; image++) {
|
|
|
|
|
bos_image_ptr_free(bos_entity_images[slot].image[image].alpha);
|
|
|
|
|
bos_image_ptr_free(bos_entity_images[slot].image[image].planes.B);
|
|
|
|
|
bos_image_ptr_free(bos_entity_images[slot].image[image].planes.R);
|
|
|
|
|
bos_image_ptr_free(bos_entity_images[slot].image[image].planes.G);
|
|
|
|
|
bos_image_ptr_free(bos_entity_images[slot].image[image].planes.E);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-23 21:28:50 +00:00
|
|
|
|
/// --------
|
|
|
|
|
|
|
|
|
|
/// Non-entity animations
|
|
|
|
|
/// ---------------------
|
|
|
|
|
extern bos_t bos_anim_images[BOS_ANIM_SLOT_COUNT];
|
2020-09-24 19:22:58 +00:00
|
|
|
|
|
|
|
|
|
int CBossAnim::load(const char fn[PF_FN_LEN], int slot)
|
|
|
|
|
{
|
|
|
|
|
int plane_size;
|
|
|
|
|
|
2020-10-08 10:55:30 +00:00
|
|
|
|
bos_header_load(this, plane_size, fn, true);
|
2020-09-24 19:22:58 +00:00
|
|
|
|
if(!bos_header_only) {
|
2020-09-24 20:16:08 +00:00
|
|
|
|
bos_anim_free(slot);
|
2020-09-24 19:22:58 +00:00
|
|
|
|
for(int i = 0; bos_image_count > i; i++) {
|
|
|
|
|
#define image bos_anim_images[slot].image[i]
|
|
|
|
|
bos_image_new(image, plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.alpha), plane_size);
|
|
|
|
|
for(int bos_p = 0; bos_p < (plane_size / 2); bos_p++) {
|
|
|
|
|
image.alpha[bos_p] = ~image.alpha[bos_p];
|
|
|
|
|
}
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.planes.B), plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.planes.R), plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.planes.G), plane_size);
|
|
|
|
|
arc_file_get(reinterpret_cast<char *>(image.planes.E), plane_size);
|
|
|
|
|
#undef image
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bos_slot = slot;
|
|
|
|
|
arc_file_free();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2020-09-24 20:01:33 +00:00
|
|
|
|
|
|
|
|
|
void CBossAnim::put_8(void) const
|
|
|
|
|
{
|
|
|
|
|
vram_offset_t vram_offset_row = vram_offset_divmul(left, top);
|
|
|
|
|
vram_offset_t vram_offset;
|
|
|
|
|
size_t bos_p = 0;
|
|
|
|
|
pixel_t bos_y;
|
|
|
|
|
vram_word_amount_t bos_word_x;
|
|
|
|
|
vram_y_t intended_y;
|
|
|
|
|
|
|
|
|
|
bos_image_t &bos = bos_anim_images[bos_slot].image[bos_image];
|
|
|
|
|
if(bos_image >= bos_image_count) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(bos_y = 0; h > bos_y; bos_y++) {
|
|
|
|
|
vram_offset_t vram_offset = vram_offset_row;
|
|
|
|
|
intended_y = vram_intended_y_for(vram_offset_row, left);
|
|
|
|
|
for(bos_word_x = 0; (vram_w / 2) > bos_word_x; bos_word_x++) {
|
|
|
|
|
if((vram_offset / ROW_SIZE) == intended_y) {
|
|
|
|
|
if(bos.alpha[bos_p]) {
|
2020-10-10 13:03:04 +00:00
|
|
|
|
vram_erase(vram_offset, bos.alpha[bos_p], 16);
|
2020-09-24 20:01:33 +00:00
|
|
|
|
}
|
|
|
|
|
vram_or_emptyopt(B, vram_offset, bos.planes.B[bos_p], 16);
|
|
|
|
|
vram_or_emptyopt(R, vram_offset, bos.planes.R[bos_p], 16);
|
|
|
|
|
vram_or_emptyopt(G, vram_offset, bos.planes.G[bos_p], 16);
|
|
|
|
|
vram_or_emptyopt(E, vram_offset, bos.planes.E[bos_p], 16);
|
|
|
|
|
}
|
|
|
|
|
vram_offset += 2;
|
|
|
|
|
bos_p++;
|
|
|
|
|
}
|
|
|
|
|
vram_offset_row += ROW_SIZE;
|
|
|
|
|
if(vram_offset_row >= PLANE_SIZE) { // Clip at the bottom edge
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-24 20:16:08 +00:00
|
|
|
|
|
|
|
|
|
void bos_anim_free(int slot)
|
|
|
|
|
{
|
|
|
|
|
for(int image = 0; image < BOS_IMAGES_PER_SLOT; image++) { \
|
|
|
|
|
bos_image_ptr_free(bos_anim_images[slot].image[image].alpha);
|
|
|
|
|
|
|
|
|
|
// How do you even?!
|
|
|
|
|
#undef bos_image_ptr_free
|
|
|
|
|
#define bos_image_ptr_free(ptr) \
|
|
|
|
|
delete[] ptr; \
|
|
|
|
|
ptr = NULL;
|
|
|
|
|
|
|
|
|
|
bos_image_ptr_free(bos_anim_images[slot].image[image].planes.B);
|
|
|
|
|
bos_image_ptr_free(bos_anim_images[slot].image[image].planes.R);
|
|
|
|
|
bos_image_ptr_free(bos_anim_images[slot].image[image].planes.G);
|
|
|
|
|
bos_image_ptr_free(bos_anim_images[slot].image[image].planes.E);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-23 21:28:50 +00:00
|
|
|
|
/// ---------------------
|