ReC98/th01/main/boss/entity_a.hpp

236 lines
7.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// Entities
/// --------
// Slot count for unique .BOS files associated with CBossEntity instances.
// *Not* CBossEntity instances themselves!
#define BOS_ENTITY_SLOT_COUNT 4
// An individual entity rendered with sprites from a .BOS file. May or may not
// be animated, and may or may not have a hitbox for collision with the Orb.
class CBossEntity {
public:
screen_x_t cur_left;
screen_y_t cur_top;
screen_x_t prev_left;
screen_y_t prev_top;
vram_byte_amount_t vram_w;
pixel_t h;
area_t<screen_x_t, screen_y_t> move_clamp; // Relative to VRAM
area_t<pixel_t, pixel_t> hitbox_orb; // Relative to [cur_left] and [cur_top]
// Never actually read outside of the functions that set them...
pixel_t prev_delta_y;
pixel_t prev_delta_x;
int bos_image_count;
int zero_1;
int bos_image;
int unknown;
bool16 hitbox_orb_inactive;
bool16 loading;
int move_lock_frame;
int zero_2;
char zero_3;
unsigned char bos_slot;
// Loads all images from the .BOS file with the given [fn] inside the
// currently active packfile into the given CBossEntity .BOS [slot], and
// keeps the .BOS metadata in this CBossEntity instance. Always returns 0.
void load(const char fn[PF_FN_LEN], int slot) {
loading = true;
load_inner(fn, slot);
loading = false;
}
int load_inner(const char fn[PF_FN_LEN], int slot);
// Copies the .BOS header data of this instance to the given variables. In
// practice, only used to copy these values from one CBossEntity to
// another.
void metadata_get(
int &image_count,
unsigned char &slot,
vram_byte_amount_t &vram_w,
pixel_t &h
) const;
/// Blitting
/// --------
// All functions with an [image] parameter use that image from [bos_slot],
// *not* the [bos_image] of this instance.
// Like CPlayerAnim, all of these also make an attempt at clipping the
// sprite at the left and right edges of VRAM. This only really works if
// [left] is a multiple of 16 and inside the [-RES_X, RES_X[ range,
// though, and is pretty much broken otherwise.
// Blits [image] to (⌊left/8⌋*8, top).
// Additionally clips at the bottom edge of VRAM.
void put_8(screen_x_t left, vram_y_t top, int image) const;
// Precisely restores pixels according to the alpha mask of [image] from
// VRAM page 1, starting at (⌊left/8⌋*8, top).
// Additionally clips at the top and bottom edges of VRAM.
void unput_8(screen_x_t left, vram_y_t top, int image) const;
// Like put_8(), but restores all pixels in the blitted sprite
// rectangle from VRAM page 1 prior to blitting.
// Additionally clips at the top and bottom edges of VRAM.
void unput_and_put_8(screen_x_t left, vram_y_t top, int image) const;
// Blits line #[row] of [image] to (left, top).
// Additionally clips at the bottom edge of VRAM.
void put_1line(screen_x_t left, vram_y_t y, int image, pixel_t row) const;
// Like put_1line(), but restores all pixels along the line from VRAM page
// 1 prior to blitting the line.
void unput_and_put_1line(
screen_x_t left, vram_y_t y, int image, pixel_t row
) const;
// Blits [image] with a wave function applied to the starting X coordinate
// for each row, based at the given (left, top) point. Used for Elis'
// entrance animation.
// Calls put_1line() for each row, and clips the sprite accordingly.
void wave_put(
screen_x_t left,
vram_y_t top,
int image,
int len,
pixel_t amp,
int phase
) const;
// Like wave_put(), but calls unput_and_put_1line() for each line instead.
// For a sloppy, EGC-accelerated unblitter function, see egc_wave_unput().
void wave_unput_and_put(
screen_x_t left,
vram_y_t top,
int image,
int len,
pixel_t amp,
int phase
) const;
// Tries to unblit the two sprites at (left_1, top) and (left_2, top) that
// were previously blitted with the given wave function using the EGC, but
// fails.
void egc_sloppy_wave_unput_double_broken(
screen_x_t left_1, vram_y_t top, int unused,
int len_1, pixel_t amp_1, int phase_1,
screen_x_t left_2,
int len_2, pixel_t amp_2, int phase_2
) const;
// Blits the 16×8 pixels of [bos_image] in [bos_slot] starting at
// (bos_left, bos_top), relative to the top-left corner of the sprite, to
// ((⌊cur_left/8⌋ + bos_left/8⌋) * 8, (cur_top + bos_top))
// after precisely restoring pixels according to the alpha mask of the
// pixels to be blitted from VRAM page 1.
// Additionally clips at the top and bottom edges of VRAM.
void unput_and_put_16x8_8(pixel_t bos_left, pixel_t bos_top) const;
// Restores the pixels inside the entire ([vram_w]*8)×[h] rectangle
// starting at (cur_left, cur_top) from VRAM page 1.
void sloppy_unput(void) const;
/// --------
/// Movement
/// --------
protected:
void move(const pixel_t &delta_x, const pixel_t &delta_y) {
prev_delta_x = delta_x;
prev_delta_y = delta_y;
prev_left = cur_left;
prev_top = cur_top;
cur_left += prev_delta_x;
if(move_clamp.left > cur_left) {
cur_left = move_clamp.left;
}
if(move_clamp.right < cur_left) {
cur_left = move_clamp.right;
}
cur_top += prev_delta_y;
if(cur_top < move_clamp.top) {
cur_top = move_clamp.top;
}
if(cur_top > move_clamp.bottom) {
cur_top = move_clamp.bottom;
}
}
public:
// Sets [cur_left], [cur_top], [unknown], and the [move_clamp] area.
void pos_set(
screen_x_t left,
screen_y_t top,
int unknown,
screen_x_t move_clamp_left,
screen_x_t move_clamp_right,
screen_y_t move_clamp_top,
screen_y_t move_clamp_bottom
);
// (Just read the actual function code, it's impossible to summarize these
// without spelling out every single line here.)
void move_lock_and_put_8(
int unused, pixel_t delta_x, pixel_t delta_y, int lock_frames
);
void move_lock_unput_and_put_8(
int unused, pixel_t delta_x, pixel_t delta_y, int lock_frames
);
/// --------
/// Collision detection
/// -------------------
public:
// Simply returns whether the orb collided with this entity on the last
// frame. (TODO: Last frame???)
bool16 hittest_orb(void) const;
/// -------------------
};
// Frees all images in the given [slot].
void bos_entity_free(int slot);
extern CBossEntity boss_entities[5];
/// --------
/// Non-entity animations
/// ---------------------
// Slot count for unique .BOS files associated with CBossAnim instances.
// *Not* CBossAnim instances themselves!
#define BOS_ANIM_SLOT_COUNT 2
// Stripped-down version of CBossEntity, with just animation support. These
// only have functions for direct byte-aligned blitting onto page 0, in
// exchange for the alpha plane being pre-negated at load time? No idea why.
// That 1-instruction negation is certainly not what makes the original code
// slow.
class CBossAnim {
public:
screen_x_t left;
screen_y_t top;
vram_byte_amount_t vram_w;
pixel_t h;
unsigned char bos_image_count;
unsigned char bos_image;
unsigned char bos_slot;
// Loads all images from the .BOS file with the given [fn] inside the
// currently active packfile into the given CBossAnim .BOS [slot], and
// keeps the .BOS metadata in this CBossEntity instance. Always returns 0.
// Identical to CBossEntity::load() with an added alpha negation loop.
int load(const char fn[PF_FN_LEN], int slot);
// Blits [bos_image] to (⌊left/8⌋*8, top).
// Additionally clips at the bottom edge of VRAM.
void put_8(void) const;
};
// Frees all images in the given [slot].
void bos_anim_free(int slot);
/// ---------------------