ReC98/th02/main/player/player.hpp

91 lines
3.0 KiB
C++

#include "pc98.h"
#define PLAYER_W 32
#define PLAYER_H 48
static const pixel_t PLAYER_OPTION_W = 16;
static const pixel_t PLAYER_OPTION_H = 16;
// Center-to-center distance. Only directly used in TH04 and TH05, since TH02
// doesn't use center coordinates internally.
static const pixel_t PLAYER_OPTION_DISTANCE = (
(PLAYER_W / 2) + (PLAYER_OPTION_W / 2)
);
static const pixel_t PLAYER_OPTION_TO_OPTION_DISTANCE = (
PLAYER_OPTION_DISTANCE * 2
);
#if (GAME == 2)
#include "th02/main/playfld.hpp"
// Coordinates
// -----------
static const screen_x_t PLAYER_LEFT_START = (
PLAYFIELD_LEFT + (PLAYFIELD_W / 2) - (PLAYER_W / 2)
);
static const screen_y_t PLAYER_TOP_START = (PLAYFIELD_BOTTOM - PLAYER_H);
static const pixel_t PLAYER_LEFT_TO_OPTION_LEFT_LEFT = (
PLAYER_OPTION_DISTANCE - (PLAYER_W / 2) + (PLAYER_OPTION_W / 2)
);
// -----------
// Current position
// ----------------
// ZUN bloat: It's tracked quite redundantly in this game:
//
// 1) [player_(left|top)_on_page] contains the authoritative coordinates on
// both VRAM pages, just like every other entity in this game.
// 2) [player_(left|top)_on_back_page] is set in player_invalidate() to
// avoid repeated address calculations of the back page element in 1).
// 3) [player_topleft] is a set to 2)'s value in player_move(), probably to
// then avoid dereferencing a pointer whenever the position is needed?
//
// For the most part, game logic can just use 3), which is why its name
// didn't receive any further qualifiers. However, the miss animation
// prevents player_move() from running and therefore needs to access the
// position through 2) after all, especially since it also calculates the
// spawn position of the sparks by temporarily mutating the position. This
// can definitely be done in a cleaner and less redundant way.
extern screen_x_t player_left_on_page[2];
extern screen_y_t player_top_on_page[2];
extern screen_x_t near* player_left_on_back_page;
extern screen_y_t near* player_top_on_back_page;
extern screen_point_t player_topleft;
extern screen_point_t player_option_left_topleft[2];
extern screen_x_t near* player_option_left_left_on_back_page;
extern screen_y_t near* player_option_left_top_on_back_page;
// ----------------
#endif
extern bool player_is_hit;
// Grants invincibility when >0. Decrements by 1 each frame in that case.
// In TH02, this works independently from [player_invincible_via_bomb].
extern unsigned char player_invincibility_time;
static const uint8_t POWER_MIN = 1;
#if (GAME == 2)
static const uint8_t POWER_MAX = 80;
// Grants invincibility as long as it's true. Works independently from
// [player_invincibility_time].
extern bool player_invincible_via_bomb;
#endif
static const int SHOT_LEVEL_MAX = 9;
extern uint8_t power;
// Amount of power past POWER_MAX, capped to POWER_OVERFLOW_MAX. Determines the
// point value of any further power items collected.
extern int power_overflow;
extern uint8_t shot_level;
void near player_invalidate();