From d31793804747ec2b4e4225bcdca57679ef26b82b Mon Sep 17 00:00:00 2001 From: Trevor Boddy Date: Mon, 4 May 2026 18:29:32 -0400 Subject: [PATCH] hot-path perf: skip off-screen enemies in bullet collision; null-check bullet updaters; dedupe wrapped delta in updateEnemy --- src/bullets.h | 30 +++++++++++++++--------------- src/chrome.h | 3 +-- src/enemies.h | 5 ++--- src/enemytypes.h | 46 +++++++++++++++++++++++----------------------- src/global.h | 2 -- 5 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/bullets.h b/src/bullets.h index 0e69339..c431d5d 100644 --- a/src/bullets.h +++ b/src/bullets.h @@ -95,20 +95,20 @@ void updateBulletVel(u8 i){ s32 bulletDist; static void collideWithEnemy(u8 i){ for(s16 j = 0; j < ENEMY_COUNT; j++) { - if(enemies[j].active && bullets[i].active){ - fix32 deltaX = getWrappedDelta(bullets[i].pos.x, enemies[j].pos.x); - fix32 deltaY = bullets[i].pos.y - enemies[j].pos.y; - if(deltaY >= -BULLET_CHECK && deltaY <= BULLET_CHECK && - deltaX >= -BULLET_CHECK && deltaX <= BULLET_CHECK){ - bulletDist = getApproximatedDistance(F32_toInt(deltaX), F32_toInt(deltaY)); - if(bulletDist <= bullets[i].dist){ - u32 pts = (enemies[j].carriedTreasure >= 0) ? 512 : 256; - score += pts; - spawnPopup(enemies[j].pos.x, enemies[j].pos.y, pts); - killBullet(i, enemies[j].hp > 1); - killEnemy(j); - sfxExplosion(); - } + if(!bullets[i].active) break; + if(!enemies[j].active || !enemies[j].onScreen) continue; + fix32 deltaX = getWrappedDelta(bullets[i].pos.x, enemies[j].pos.x); + fix32 deltaY = bullets[i].pos.y - enemies[j].pos.y; + if(deltaY >= -BULLET_CHECK && deltaY <= BULLET_CHECK && + deltaX >= -BULLET_CHECK && deltaX <= BULLET_CHECK){ + bulletDist = getApproximatedDistance(F32_toInt(deltaX), F32_toInt(deltaY)); + if(bulletDist <= bullets[i].dist){ + u32 pts = (enemies[j].carriedTreasure >= 0) ? 512 : 256; + score += pts; + spawnPopup(enemies[j].pos.x, enemies[j].pos.y, pts); + killBullet(i, enemies[j].hp > 1); + killEnemy(j); + sfxExplosion(); } } } @@ -194,7 +194,7 @@ static void updateBullet(u8 i){ killBullet(i, FALSE); return; } - if(bullets[i].clock > 0) bullets[i].updater(i); + if(bullets[i].clock > 0 && bullets[i].updater) bullets[i].updater(i); if(bullets[i].player) collideWithEnemy(i); else if(!gameOver) collideWithPlayer(i); if(bullets[i].active){ diff --git a/src/chrome.h b/src/chrome.h index 0f7eb45..6312715 100644 --- a/src/chrome.h +++ b/src/chrome.h @@ -355,8 +355,7 @@ static void doGameOver(){ .x = treasures[i].pos.x, .y = treasures[i].pos.y, .anim = 0, .speed = 0, .angle = 0, .player = TRUE }; - void noop(s16 j){ (void)j; } - spawnBullet(spawner, noop); + spawnBullet(spawner, NULL); for(s16 j = BULLET_COUNT - 1; j >= 0; j--){ if(bullets[j].active && bullets[j].pos.x == treasures[i].pos.x && bullets[j].pos.y == treasures[i].pos.y){ diff --git a/src/enemies.h b/src/enemies.h index ed99058..24966bf 100644 --- a/src/enemies.h +++ b/src/enemies.h @@ -315,11 +315,10 @@ static void updateEnemy(u8 i){ break; } - // enemy->player collision + // enemy->player collision (reuses dx from above — position unchanged this frame) if(enemies[i].onScreen && !gameOver && player.recoveringClock == 0 && player.respawnClock == 0){ - fix32 edx = getWrappedDelta(enemies[i].pos.x, player.pos.x); fix32 edy = enemies[i].pos.y - player.pos.y; - if(edx >= FIX32(-16) && edx <= FIX32(16) && edy >= FIX32(-16) && edy <= FIX32(16)){ + if(dx >= FIX32(-16) && dx <= FIX32(16) && edy >= FIX32(-16) && edy <= FIX32(16)){ sfxExplosion(); // spawn big explosion at player position spawnExplosion(player.pos.x, player.pos.y, 3, TRUE); // yellow diff --git a/src/enemytypes.h b/src/enemytypes.h index e64ecc1..3c6564f 100644 --- a/src/enemytypes.h +++ b/src/enemytypes.h @@ -41,7 +41,7 @@ void updateEnemyOne(u8 i){ .speed = FIX32(5), .angle = enemyHoneAngle(i) }; - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); } void loadEnemyTwo(u8 i){ @@ -65,7 +65,7 @@ void updateEnemyTwo(u8 i){ .speed = FIX32(4), .angle = enemies[i].fixes[0] - FIX16(15) + FIX16(random() % 30) }; - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); } } @@ -92,7 +92,7 @@ void updateEnemyThree(u8 i){ .angle = enemies[i].fixes[0] - FIX16(30) }; for(u8 j = 0; j < 3; j++){ - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); spawner.angle += FIX16(30); } } else if(enemies[i].clock % 60 == enemies[i].ints[2]){ @@ -104,7 +104,7 @@ void updateEnemyThree(u8 i){ .angle = FIX16(random() % 72) }; for(u8 j = 0; j < 5; j++){ - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); spawner.angle += FIX16(72); } } @@ -166,7 +166,7 @@ static void bossOnePatternOne(u8 i){ spawner.x = enemies[i].pos.x + F32_mul(F32_cos(spawner.angle), FIX32(32)); spawner.y = enemies[i].pos.y + F32_mul(F32_sin(spawner.angle), FIX32(32)); for(u8 j = 0; j < 8; j++){ - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); spawner.angle = F16_normalizeAngle(spawner.angle + FIX16(45)); } } @@ -178,7 +178,7 @@ static void bossOnePatternOne(u8 i){ .speed = FIX32(5), .angle = enemies[i].fixes[0] }; - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); } } static void bossOnePatternTwo(u8 i){ @@ -226,7 +226,7 @@ static void bossOnePatternTwo(u8 i){ .speed = FIX32(5), .angle = enemies[i].fixes[0] - FIX16(20) + FIX16(random() % 40) }; - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); } } static void bossOnePatternThree(u8 i){ @@ -243,7 +243,7 @@ static void bossOnePatternThree(u8 i){ .speed = FIX32(6), .angle = enemies[i].fixes[0] - FIX16(5) + FIX16(random() % 10) }; - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); } else if(enemies[i].clock % 5 == 2){ struct bulletSpawner spawner = { .x = enemies[i].pos.x, @@ -253,7 +253,7 @@ static void bossOnePatternThree(u8 i){ .angle = enemies[i].fixes[0] - FIX16(30) + FIX16(random() % 10) }; for(u8 j = 0; j < 2; j++){ - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); spawner.angle += FIX16(50); } } @@ -278,7 +278,7 @@ static void bossTwoPatternOne(u8 i){ .speed = FIX32(5), .angle = enemies[i].fixes[0] - FIX16(10) + FIX16(random() % 20) }; - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); } else { struct bulletSpawner spawner = { .x = enemies[i].pos.x, @@ -343,7 +343,7 @@ void updateEnemyFive(u8 i){ }; for(u8 j = 0; j < 3; j++){ spawner.anim = j == 1 ? 1 : 0; - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); spawner.angle += FIX16(25); } } @@ -369,7 +369,7 @@ void updateEnemySix(u8 i){ }; spawner.vel.x = F32_mul(FIX32(4), F32_cos(enemies[i].fixes[0])); spawner.vel.y = F32_mul(FIX32(5), F32_sin(enemies[i].fixes[0])); - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); enemies[i].fixes[0] = F16_normalizeAngle(enemies[i].fixes[0] + FIX16(enemies[i].clock % 120 < 60 ? 25 : -25)); } } @@ -394,7 +394,7 @@ void updateEnemySeven(u8 i){ .speed = FIX32(enemies[i].clock % 4 == 0 ? 4 : 3), .angle = FIX16(random() % 360) }; - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); } } @@ -430,7 +430,7 @@ void updateEnemyEight(u8 i){ } else { spawner.angle = bullets[j].angle - FIX16(20 + (random() % 20)); } - spawnBullet(spawner, EMPTY); + spawnBullet(spawner, NULL); } } spawnBullet(spawner, updater); @@ -668,7 +668,7 @@ void updateBoss(u8 i){ // .angle = enemies[i].fixes[0] // }; // for(u8 j = 0; j < 5; j++){ -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // spawner.angle += FIX16(72); // } // sfxEnemyShotA(); @@ -685,7 +685,7 @@ void updateBoss(u8 i){ // }; // for(u8 j = 0; j < 6; j++){ -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // spawner.angle += FIX16(60); // } // sfxEnemyShotB(); @@ -712,7 +712,7 @@ void updateBoss(u8 i){ // .angle = FIX16(bullets[j].ints[0]), // .speed = FIX32(4) // }; -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // if(bullets[j].ints[1] == 1){ // bullets[j].ints[0] += 72; // if(bullets[j].ints[0] >= 360) @@ -746,7 +746,7 @@ void updateBoss(u8 i){ // } else { // spawner.anim = j % 2 == 0 ? 9 : 10; // } -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // spawner.angle += FIX16(90); // } // if(enemies[i].clock % 120 < 60){ @@ -766,7 +766,7 @@ void updateBoss(u8 i){ // }; // for(u8 j = 0; j < 8; j++){ // spawner.frame = j % 2 == 0 ? 0 : 1; -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // spawner.angle += FIX16(45); // } // } @@ -848,7 +848,7 @@ void updateBoss(u8 i){ // .speed = FIX32(3) // }; // for(u8 j = 0; j < 8; j++){ -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // spawner.angle += FIX16(45); // } // } @@ -890,7 +890,7 @@ void updateBoss(u8 i){ // .speed = FIX32(4) // }; // for(u8 j = 0; j < 8; j++){ -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // spawner.angle += FIX16(45); // } // } @@ -938,7 +938,7 @@ void updateBoss(u8 i){ // .speed = FIX32(2.5) + F16_toFix32(enemies[i].fixes[2]) // }; // for(u8 j = 0; j < 3; j++){ -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // spawner.angle += FIX16(30); // } // enemies[i].fixes[2] += FIX16(0.5); @@ -952,7 +952,7 @@ void updateBoss(u8 i){ // .speed = FIX32(3) // }; // for(u8 j = 0; j < 8; j++){ -// spawnBullet(spawner, EMPTY); +// spawnBullet(spawner, NULL); // spawner.angle += FIX16(45); // } // } diff --git a/src/global.h b/src/global.h index c42f39f..03c78b9 100644 --- a/src/global.h +++ b/src/global.h @@ -63,8 +63,6 @@ static void saveHighScore(){ #define MAP_H 3 #define MAP_SCALE (F32_toInt(GAME_WRAP) / MAP_W) -void EMPTY(s16 i){(void)i;} - bool started; bool gameOver; bool paused, isPausing;