This commit is contained in:
t. boddy 2026-02-14 19:31:58 -05:00
parent ab73e04b32
commit 0b905f2690
26 changed files with 1210 additions and 0 deletions

142
src/global.h Normal file
View file

@ -0,0 +1,142 @@
u32 clock;
#define CLOCK_LIMIT 32000
#define COUNT_INT 4
#define GAME_H_F FIX32(224)
// Section-based world size
#define SECTION_SIZE FIX32(512) // Size of one section (512px)
#define SECTION_COUNT 4 // Number of sections (N = 2, 4, 8, etc.)
#define GAME_WRAP (SECTION_SIZE * SECTION_COUNT) // Total world width
u32 score, highScore;
#define SCORE_LENGTH 8
#define FIRST_ROTATING_BULLET 3
#define CAMERA_Y_MOD FIX32(112)
// Screen bounds for visibility (screen is 320x224)
// VDP wraps sprites every 512px, so we must hide sprites outside screen
#define VISIBLE_X_MIN 0
#define VISIBLE_X_MAX 512
#define VISIBLE_Y_MIN -32
#define VISIBLE_Y_MAX 256
char debugStr[8];
s16 emptyI;
void EMPTY(s16 i){emptyI = i;}
bool gameOver, paused, started;
s16 enemyCount;
// controls
struct controls {
bool left, right, up, down, a, b, c, start;
};
struct controls ctrl;
void updateControls(u16 joy, u16 changed, u16 state){
if(changed){}
if(joy == JOY_1){
ctrl.left = (state & BUTTON_LEFT);
ctrl.right = (state & BUTTON_RIGHT);
ctrl.up = (state & BUTTON_UP);
ctrl.down = (state & BUTTON_DOWN);
ctrl.a = (state & BUTTON_A);
ctrl.b = (state & BUTTON_B);
ctrl.c = (state & BUTTON_C);
ctrl.start = (state & BUTTON_START);
}
}
// player
struct playerStruct {
Vect2D_f32 pos, vel, last;
s16 shotAngle;
u8 lives;
fix32 camera;
Sprite* image;
};
struct playerStruct player;
// bullets
#define BULLET_COUNT 64
struct bulletSpawner {
fix32 x, y, speed;
Vect2D_f32 vel;
s16 angle, anim;
bool top, player;
bool bools[COUNT_INT];
s16 ints[COUNT_INT];
fix32 fixes[COUNT_INT];
};
struct bullet {
bool active, player, explosion, top, vFlip, hFlip;
fix32 speed;
Vect2D_f32 pos, vel;
Sprite* image;
s16 clock, angle, anim, frame;
s16 dist;
void (*updater)(s16);
bool bools[COUNT_INT];
s16 ints[COUNT_INT];
fix32 fixes[COUNT_INT];
};
struct bullet bullets[BULLET_COUNT];
// enemies
#define ENEMY_COUNT 16
struct enemy {
bool active;
s16 clock, angle, anim, frame, off;
fix32 speed;
u8 type;
Vect2D_f32 vel, pos;
s16 dist;
Sprite* image;
void (*updater)(s16);
bool bools[COUNT_INT];
s16 ints[COUNT_INT];
fix32 fixes[COUNT_INT];
};
struct enemy enemies[ENEMY_COUNT];
void killBullet(u8 i){
bullets[i].active = FALSE;
SPR_releaseSprite(bullets[i].image);
}
void killEnemy(u8 i){
enemies[i].active = FALSE;
SPR_releaseSprite(enemies[i].image);
}
// Calculate shortest X distance accounting for world wrap
// Returns distance in the range [-GAME_WRAP/2, GAME_WRAP/2]
static fix32 getWrappedDelta(fix32 a, fix32 b) {
fix32 delta = a - b;
// If distance is more than half the world, go the other way
if (delta > GAME_WRAP / 2) {
delta -= GAME_WRAP;
} else if (delta < -GAME_WRAP / 2) {
delta += GAME_WRAP;
}
return delta;
}
// Safe screen X calculation handling wrap edge cases
// Returns screen coordinate for an entity, accounting for entities that just wrapped
static s16 getScreenX(fix32 worldX, fix32 camera) {
fix32 screenX = worldX - camera;
// Handle entity that just wrapped (temporarily far off-screen)
if (screenX < FIX32(-256)) {
screenX += GAME_WRAP;
} else if (screenX > FIX32(256)) {
screenX -= GAME_WRAP;
}
return fix32ToInt(screenX);
}