hot-path perf: skip off-screen enemies in bullet collision; null-check bullet updaters; dedupe wrapped delta in updateEnemy

This commit is contained in:
t. boddy 2026-05-04 18:29:32 -04:00
parent 86935184b2
commit d317938047
5 changed files with 41 additions and 45 deletions

View file

@ -95,7 +95,8 @@ void updateBulletVel(u8 i){
s32 bulletDist; s32 bulletDist;
static void collideWithEnemy(u8 i){ static void collideWithEnemy(u8 i){
for(s16 j = 0; j < ENEMY_COUNT; j++) { for(s16 j = 0; j < ENEMY_COUNT; j++) {
if(enemies[j].active && bullets[i].active){ 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 deltaX = getWrappedDelta(bullets[i].pos.x, enemies[j].pos.x);
fix32 deltaY = bullets[i].pos.y - enemies[j].pos.y; fix32 deltaY = bullets[i].pos.y - enemies[j].pos.y;
if(deltaY >= -BULLET_CHECK && deltaY <= BULLET_CHECK && if(deltaY >= -BULLET_CHECK && deltaY <= BULLET_CHECK &&
@ -112,7 +113,6 @@ static void collideWithEnemy(u8 i){
} }
} }
} }
}
static void collideWithPlayer(u8 i){ static void collideWithPlayer(u8 i){
if(player.recoveringClock > 0 || player.respawnClock > 0) return; if(player.recoveringClock > 0 || player.respawnClock > 0) return;
@ -194,7 +194,7 @@ static void updateBullet(u8 i){
killBullet(i, FALSE); killBullet(i, FALSE);
return; 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); if(bullets[i].player) collideWithEnemy(i);
else if(!gameOver) collideWithPlayer(i); else if(!gameOver) collideWithPlayer(i);
if(bullets[i].active){ if(bullets[i].active){

View file

@ -355,8 +355,7 @@ static void doGameOver(){
.x = treasures[i].pos.x, .y = treasures[i].pos.y, .x = treasures[i].pos.x, .y = treasures[i].pos.y,
.anim = 0, .speed = 0, .angle = 0, .player = TRUE .anim = 0, .speed = 0, .angle = 0, .player = TRUE
}; };
void noop(s16 j){ (void)j; } spawnBullet(spawner, NULL);
spawnBullet(spawner, noop);
for(s16 j = BULLET_COUNT - 1; j >= 0; j--){ for(s16 j = BULLET_COUNT - 1; j >= 0; j--){
if(bullets[j].active if(bullets[j].active
&& bullets[j].pos.x == treasures[i].pos.x && bullets[j].pos.y == treasures[i].pos.y){ && bullets[j].pos.x == treasures[i].pos.x && bullets[j].pos.y == treasures[i].pos.y){

View file

@ -315,11 +315,10 @@ static void updateEnemy(u8 i){
break; 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){ 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; 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(); sfxExplosion();
// spawn big explosion at player position // spawn big explosion at player position
spawnExplosion(player.pos.x, player.pos.y, 3, TRUE); // yellow spawnExplosion(player.pos.x, player.pos.y, 3, TRUE); // yellow

View file

@ -41,7 +41,7 @@ void updateEnemyOne(u8 i){
.speed = FIX32(5), .speed = FIX32(5),
.angle = enemyHoneAngle(i) .angle = enemyHoneAngle(i)
}; };
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
} }
void loadEnemyTwo(u8 i){ void loadEnemyTwo(u8 i){
@ -65,7 +65,7 @@ void updateEnemyTwo(u8 i){
.speed = FIX32(4), .speed = FIX32(4),
.angle = enemies[i].fixes[0] - FIX16(15) + FIX16(random() % 30) .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) .angle = enemies[i].fixes[0] - FIX16(30)
}; };
for(u8 j = 0; j < 3; j++){ for(u8 j = 0; j < 3; j++){
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
spawner.angle += FIX16(30); spawner.angle += FIX16(30);
} }
} else if(enemies[i].clock % 60 == enemies[i].ints[2]){ } else if(enemies[i].clock % 60 == enemies[i].ints[2]){
@ -104,7 +104,7 @@ void updateEnemyThree(u8 i){
.angle = FIX16(random() % 72) .angle = FIX16(random() % 72)
}; };
for(u8 j = 0; j < 5; j++){ for(u8 j = 0; j < 5; j++){
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
spawner.angle += FIX16(72); 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.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)); spawner.y = enemies[i].pos.y + F32_mul(F32_sin(spawner.angle), FIX32(32));
for(u8 j = 0; j < 8; j++){ for(u8 j = 0; j < 8; j++){
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
spawner.angle = F16_normalizeAngle(spawner.angle + FIX16(45)); spawner.angle = F16_normalizeAngle(spawner.angle + FIX16(45));
} }
} }
@ -178,7 +178,7 @@ static void bossOnePatternOne(u8 i){
.speed = FIX32(5), .speed = FIX32(5),
.angle = enemies[i].fixes[0] .angle = enemies[i].fixes[0]
}; };
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
} }
} }
static void bossOnePatternTwo(u8 i){ static void bossOnePatternTwo(u8 i){
@ -226,7 +226,7 @@ static void bossOnePatternTwo(u8 i){
.speed = FIX32(5), .speed = FIX32(5),
.angle = enemies[i].fixes[0] - FIX16(20) + FIX16(random() % 40) .angle = enemies[i].fixes[0] - FIX16(20) + FIX16(random() % 40)
}; };
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
} }
} }
static void bossOnePatternThree(u8 i){ static void bossOnePatternThree(u8 i){
@ -243,7 +243,7 @@ static void bossOnePatternThree(u8 i){
.speed = FIX32(6), .speed = FIX32(6),
.angle = enemies[i].fixes[0] - FIX16(5) + FIX16(random() % 10) .angle = enemies[i].fixes[0] - FIX16(5) + FIX16(random() % 10)
}; };
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
} else if(enemies[i].clock % 5 == 2){ } else if(enemies[i].clock % 5 == 2){
struct bulletSpawner spawner = { struct bulletSpawner spawner = {
.x = enemies[i].pos.x, .x = enemies[i].pos.x,
@ -253,7 +253,7 @@ static void bossOnePatternThree(u8 i){
.angle = enemies[i].fixes[0] - FIX16(30) + FIX16(random() % 10) .angle = enemies[i].fixes[0] - FIX16(30) + FIX16(random() % 10)
}; };
for(u8 j = 0; j < 2; j++){ for(u8 j = 0; j < 2; j++){
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
spawner.angle += FIX16(50); spawner.angle += FIX16(50);
} }
} }
@ -278,7 +278,7 @@ static void bossTwoPatternOne(u8 i){
.speed = FIX32(5), .speed = FIX32(5),
.angle = enemies[i].fixes[0] - FIX16(10) + FIX16(random() % 20) .angle = enemies[i].fixes[0] - FIX16(10) + FIX16(random() % 20)
}; };
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
} else { } else {
struct bulletSpawner spawner = { struct bulletSpawner spawner = {
.x = enemies[i].pos.x, .x = enemies[i].pos.x,
@ -343,7 +343,7 @@ void updateEnemyFive(u8 i){
}; };
for(u8 j = 0; j < 3; j++){ for(u8 j = 0; j < 3; j++){
spawner.anim = j == 1 ? 1 : 0; spawner.anim = j == 1 ? 1 : 0;
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
spawner.angle += FIX16(25); 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.x = F32_mul(FIX32(4), F32_cos(enemies[i].fixes[0]));
spawner.vel.y = F32_mul(FIX32(5), F32_sin(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)); 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), .speed = FIX32(enemies[i].clock % 4 == 0 ? 4 : 3),
.angle = FIX16(random() % 360) .angle = FIX16(random() % 360)
}; };
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
} }
} }
@ -430,7 +430,7 @@ void updateEnemyEight(u8 i){
} else { } else {
spawner.angle = bullets[j].angle - FIX16(20 + (random() % 20)); spawner.angle = bullets[j].angle - FIX16(20 + (random() % 20));
} }
spawnBullet(spawner, EMPTY); spawnBullet(spawner, NULL);
} }
} }
spawnBullet(spawner, updater); spawnBullet(spawner, updater);
@ -668,7 +668,7 @@ void updateBoss(u8 i){
// .angle = enemies[i].fixes[0] // .angle = enemies[i].fixes[0]
// }; // };
// for(u8 j = 0; j < 5; j++){ // for(u8 j = 0; j < 5; j++){
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// spawner.angle += FIX16(72); // spawner.angle += FIX16(72);
// } // }
// sfxEnemyShotA(); // sfxEnemyShotA();
@ -685,7 +685,7 @@ void updateBoss(u8 i){
// }; // };
// for(u8 j = 0; j < 6; j++){ // for(u8 j = 0; j < 6; j++){
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// spawner.angle += FIX16(60); // spawner.angle += FIX16(60);
// } // }
// sfxEnemyShotB(); // sfxEnemyShotB();
@ -712,7 +712,7 @@ void updateBoss(u8 i){
// .angle = FIX16(bullets[j].ints[0]), // .angle = FIX16(bullets[j].ints[0]),
// .speed = FIX32(4) // .speed = FIX32(4)
// }; // };
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// if(bullets[j].ints[1] == 1){ // if(bullets[j].ints[1] == 1){
// bullets[j].ints[0] += 72; // bullets[j].ints[0] += 72;
// if(bullets[j].ints[0] >= 360) // if(bullets[j].ints[0] >= 360)
@ -746,7 +746,7 @@ void updateBoss(u8 i){
// } else { // } else {
// spawner.anim = j % 2 == 0 ? 9 : 10; // spawner.anim = j % 2 == 0 ? 9 : 10;
// } // }
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// spawner.angle += FIX16(90); // spawner.angle += FIX16(90);
// } // }
// if(enemies[i].clock % 120 < 60){ // if(enemies[i].clock % 120 < 60){
@ -766,7 +766,7 @@ void updateBoss(u8 i){
// }; // };
// for(u8 j = 0; j < 8; j++){ // for(u8 j = 0; j < 8; j++){
// spawner.frame = j % 2 == 0 ? 0 : 1; // spawner.frame = j % 2 == 0 ? 0 : 1;
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// spawner.angle += FIX16(45); // spawner.angle += FIX16(45);
// } // }
// } // }
@ -848,7 +848,7 @@ void updateBoss(u8 i){
// .speed = FIX32(3) // .speed = FIX32(3)
// }; // };
// for(u8 j = 0; j < 8; j++){ // for(u8 j = 0; j < 8; j++){
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// spawner.angle += FIX16(45); // spawner.angle += FIX16(45);
// } // }
// } // }
@ -890,7 +890,7 @@ void updateBoss(u8 i){
// .speed = FIX32(4) // .speed = FIX32(4)
// }; // };
// for(u8 j = 0; j < 8; j++){ // for(u8 j = 0; j < 8; j++){
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// spawner.angle += FIX16(45); // spawner.angle += FIX16(45);
// } // }
// } // }
@ -938,7 +938,7 @@ void updateBoss(u8 i){
// .speed = FIX32(2.5) + F16_toFix32(enemies[i].fixes[2]) // .speed = FIX32(2.5) + F16_toFix32(enemies[i].fixes[2])
// }; // };
// for(u8 j = 0; j < 3; j++){ // for(u8 j = 0; j < 3; j++){
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// spawner.angle += FIX16(30); // spawner.angle += FIX16(30);
// } // }
// enemies[i].fixes[2] += FIX16(0.5); // enemies[i].fixes[2] += FIX16(0.5);
@ -952,7 +952,7 @@ void updateBoss(u8 i){
// .speed = FIX32(3) // .speed = FIX32(3)
// }; // };
// for(u8 j = 0; j < 8; j++){ // for(u8 j = 0; j < 8; j++){
// spawnBullet(spawner, EMPTY); // spawnBullet(spawner, NULL);
// spawner.angle += FIX16(45); // spawner.angle += FIX16(45);
// } // }
// } // }

View file

@ -63,8 +63,6 @@ static void saveHighScore(){
#define MAP_H 3 #define MAP_H 3
#define MAP_SCALE (F32_toInt(GAME_WRAP) / MAP_W) #define MAP_SCALE (F32_toInt(GAME_WRAP) / MAP_W)
void EMPTY(s16 i){(void)i;}
bool started; bool started;
bool gameOver; bool gameOver;
bool paused, isPausing; bool paused, isPausing;