#include #include #include "global.h" #include "background.h" #include "bullets.h" #include "enemies.h" #include "treasure.h" #include "player.h" #include "stage.h" #include "chrome.h" #include "start.h" #include "starfield.h" #include "sfx.h" static void loadInternals(){ JOY_init(); JOY_setEventHandler(&updateControls); VDP_setPlaneSize(128, 32, TRUE); SPR_init(); VDP_loadFont(font.tileset, DMA); PAL_setPalette(PAL0, font.palette->data, DMA); PAL_setPalette(PAL1, shadow.palette->data, CPU); PAL_setPalette(PAL2, shadow.palette->data, CPU); VDP_setTextPriority(1); } static bool attractEnding; static void startLevelFadeIn(){ u16 ft[48]; memcpy(ft, font.palette->data, 16 * sizeof(u16)); memcpy(ft + 16, shadow.palette->data, 16 * sizeof(u16)); memcpy(ft + 32, bgPal, 16 * sizeof(u16)); PAL_setColors(0, palette_black, 48, CPU); PAL_fadeIn(0, 47, ft, 20, TRUE); } void clearLevel(){ for(s16 i = 0; i < BULLET_COUNT; i++) if(bullets[i].active) killBullet(i, FALSE); for(s16 i = 0; i < ENEMY_COUNT; i++) if(enemies[i].active){ enemies[i].hp = 0; killEnemy(i); } for(s16 i = 0; i < TREASURE_COUNT; i++) if(treasures[i].active) killTreasure(i); treasureBeingCarried = FALSE; collectedCount = 0; allTreasureCollected = FALSE; treasureCollectedClock = 0; levelEnemiesKilled = 0; // black out everything SPR_setVisibility(player.image, HIDDEN); VDP_clearTileMapRect(BG_A, 0, 0, 128, 32); VDP_clearTileMapRect(BG_B, 0, 0, 128, 32); } void loadGame(){ VDP_setVerticalScroll(BG_A, 0); score = 0; nextExtendScore = EXTEND_SCORE; loadBackground(); loadPlayer(); loadChrome(); loadLevel(isAttract ? ATTRACT_LEVEL : START_LEVEL); #if MUSIC_VOLUME > 0 if(!isAttract) XGM2_play(isBossLevel(level) ? bossMusic : stageMusic); #endif player.recoveringClock = 240; player.recoverFlash = FALSE; killBullets = TRUE; attractEnding = FALSE; started = TRUE; startLevelFadeIn(); } static void updateGame(){ if(isAttract){ if(!attractEnding){ if(ctrlHW.start || ctrlHW.a || ctrlHW.b || ctrlHW.c){ attractEnding = TRUE; PAL_fadeOut(0, 47, 20, TRUE); } if(attractClock > 0){ attractClock--; if(attractClock == 20) PAL_fadeOut(0, 47, 20, TRUE); } else { SYS_hardReset(); } } else if(!PAL_isDoingFade()){ SYS_hardReset(); } } updateChrome(); if(levelClearing){ levelClearClock++; if(levelClearClock == 73) XGM2_stop(); if(levelClearClock == 1){ clearLevel(); loadStarfield(level % 3); u16 transPal[32]; memcpy(transPal, font.palette->data, 16 * sizeof(u16)); memcpy(transPal + 16, shadow.palette->data, 16 * sizeof(u16)); PAL_fadeIn(0, 31, transPal, 20, TRUE); } if(levelClearClock == 220) PAL_fadeOut(0, 31, 20, TRUE); if(levelClearClock >= 240){ levelClearing = FALSE; player.pos.y = FIX32(112); player.camera = player.pos.x - FIX32(160); playerVelX = 0; clearStarfield(); loadBackground(); loadChrome(); loadLevel(level + 1); startLevelFadeIn(); player.pendingShow = TRUE; player.recoveringClock = 240; player.recoverFlash = FALSE; killBullets = TRUE; XGM2_stop(); #if MUSIC_VOLUME > 0 if(!isAttract) XGM2_play(isBossLevel(level) ? bossMusic : stageMusic); #endif } if(levelClearing) updateStarfield(); return; } if(levelWaitClock > 0){ levelWaitClock--; #if MUSIC_VOLUME > 0 if(levelWaitClock == 209 && !isAttract) XGM2_play(treasureMusic); #endif if(levelWaitClock == 20) PAL_fadeOut(0, 47, 20, TRUE); if(levelWaitClock == 0){ statEnemiesKilled = levelEnemiesKilled; statTreasures = collectedCount; levelClearing = TRUE; levelClearClock = 0; return; } } if(!paused){ updatePlayer(); updateBackground(); if(clock % 2 == 0){ updateEnemies(); if(!gameOver && enemyCount == 0 && levelWaitClock == 0){ if(level >= LEVEL_COUNT - 1){ gameOver = TRUE; XGM2_stop(); } else { levelWaitClock = 210; killBullets = TRUE; if(paused){ paused = FALSE; clearPause(); } XGM2_stop(); } } updateTreasures(); } else { updateBullets(); } } } int main(bool hardReset){ loadInternals(); if(SKIP_START) loadGame(); else loadStart(); while(1){ if(started) updateGame(); else updateStart(); clock++; if(clock >= CLOCK_LIMIT) clock = 600; SPR_update(); SYS_doVBlankProcess(); } return(0); }