/** * Switch the current map */ static GFraMe_ret ps_switchMap() { GFraMe_ret rv; #if !defined(DEBUG) || !defined(FAST_TRANSITION) GFraMe_event_update_begin(); int tmp; // Store whether the game was running tmp = gl_running; // Make it stop on any error gl_running = 0; switch (switchState) { /** Simply start the transition */ case 0: transition_initFadeOut(); switchState++; break; /** Fade out */ case 1: { if (transition_fadeOut(GFraMe_event_elapsed) == TR_COMPLETE) switchState++; } break; /** Load the map */ case 2: { int map; map = gv_getValue(MAP); rv = map_loadi(m, map); ASSERT(rv == GFraMe_ret_ok, rv); if (map >= 20) { audio_playBoss(); } else if (map >= 15) { audio_playTensionGoesUp(); } else if (map >= 4) { audio_playMovingOn(); } else { audio_playIntro(); } switchState++; } break; /** Tween players to their new position */ case 3: { int x, y; // Get their destiny position x = gv_getValue(DOOR_X) * 8; y = gv_getValue(DOOR_Y) * 8; // Tween the players rv = player_tweenTo(p1, x, y, GFraMe_event_elapsed, PL_TWEEN_DELAY); rv = player_tweenTo(p2, x, y, GFraMe_event_elapsed, PL_TWEEN_DELAY); // Update camera cam_setPositionSt(p1, p2); if (rv == GFraMe_ret_ok) switchState++; } break; /** Init fade in animation */ case 4: transition_initFadeIn(); switchState++; break; /** Fade in */ case 5: { if (transition_fadeIn(GFraMe_event_elapsed) == TR_COMPLETE) switchState++; } break; /** Finish the transition */ default: { int map; map = gv_getValue(MAP); if (map == 1) { if (gl_lang == EN_US) { ps_showText(_ps_map001_textEN, sizeof(_ps_map001_textEN), 0, 0, 40, 6); } else if (gl_lang == PT_BR) { ps_showText(_ps_map001_textPT, sizeof(_ps_map001_textPT), 0, 0, 40, 6); } } else if (map == 8 || map == 13) { if (gl_lang == EN_US) { ps_showText(_ps_map_afterItemEN, sizeof(_ps_map_afterItemEN), 0, 0, 40, 6); } else if (gl_lang == PT_BR) { ps_showText(_ps_map_afterItemPT, sizeof(_ps_map_afterItemPT), 0, 0, 40, 6); } } gv_setValue(SWITCH_MAP, 0); switchState = 0; signal_release(); // Set the update time (for using on events) gv_setValue(GAME_UPS, GFraMe_event_elapsed); // Save the current state if (player_isAlive(p1) && player_isAlive(p2)) { gv_setValue(GAME_TIME, timer_getTime()); rv = gv_save(SAVEFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error saving file!", __ret); } # if defined(DEBUG) && defined(RESET_GV) gv_init(); # endif /* RESET_GV */ } } gl_running = tmp; GFraMe_event_update_end(); #else /* FAST_TRANSITION */ int tmp, x, y; int map; // Store whether the game was running tmp = gl_running; // Make it stop on any error gl_running = 0; map = gv_getValue(MAP); rv = map_loadi(m, map); ASSERT(rv == GFraMe_ret_ok, rv); // Get their destiny position x = gv_getValue(DOOR_X) * 8; y = gv_getValue(DOOR_Y) * 8; // Tween the players rv = player_tweenTo(p1, x, y, GFraMe_event_elapsed, 0); rv = player_tweenTo(p2, x, y, GFraMe_event_elapsed, 0); // Update camera cam_setPositionSt(p1, p2); gv_setValue(SWITCH_MAP, 0); # ifdef RESET_GV gv_init(); # endif /* RESET_GV */ gl_running = tmp; // Set the update time (for using on events) gv_setValue(GAME_UPS, GFraMe_event_elapsed); // Save the current state if (player_isAlive(p1) && player_isAlive(p2)) { gv_setValue(GAME_TIME, timer_getTime()); rv = gv_save(SAVEFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error saving file!", __ret); } #endif /* FAST_TRANSITION */ // Set return variable rv = GFraMe_ret_ok; __ret: return rv; }
/** * Update the current frame, as many times as it's accumulated */ static void ps_update() { GFraMe_event_update_begin(); GFraMe_object *pObj; GFraMe_ret rv; int h, w; if (gv_getValue(BOSS_ISDEAD) >= 4) { if (_timerTilCredits == 0) { timer_stop(); audio_playVictory(); } else if (_timerTilCredits > 5000) { _psRunning = 0; } _timerTilCredits += GFraMe_event_elapsed; if (_timerTilCredits >= 2000) return; } else if (gv_nIsZero(SWITCH_MAP)) { return; } else if (_ps_text) { textWnd_update(GFraMe_event_elapsed); return; } #ifdef DEBUG _updCalls++; #endif pObj = 0; // Check if any player should teleport player_checkTeleport(p1); player_checkTeleport(p2); // Update everything map_update(m, GFraMe_event_elapsed); rg_updateMobs(GFraMe_event_elapsed); rg_updateObjects(GFraMe_event_elapsed); rg_updateBullets(GFraMe_event_elapsed); player_update(p1, GFraMe_event_elapsed); player_update(p2, GFraMe_event_elapsed); ui_update(GFraMe_event_elapsed); signal_update(GFraMe_event_elapsed); // Collide everythin against everything else map_getDimensions(m, &w, &h); rv = qt_initCol(-8, -8, w + 16, h + 16); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error initializing collision", __err_ret); rv = rg_qtAddWalls(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error adding map to collision", __err_ret); rv = rg_qtAddObjects(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error adding object to quadtree", __err_ret); rv = rg_qtAddMob(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error adding mob to quadtree", __err_ret); rv = rg_qtAddEvents(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error adding events to quadtree", __err_ret); rv = rg_qtAddBullets(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error adding bullets to quadtree", __err_ret); rv = qt_addPl(p1); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error adding player to quadtree", __err_ret); rv = qt_addPl(p2); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error adding player to quadtree", __err_ret); // Collide both players, manually col_onPlayer(p1, p2); col_onPlayer(p2, p1); // Collide the carried player (if any) against the map if (player_isBeingCarried(p1)) player_getObject(&pObj, p1); else if (player_isBeingCarried(p2)) player_getObject(&pObj, p2); // Fix a bug that would let players clip into ceilings if (pObj) rg_collideObjWall(pObj); // Update camera cam_setPosition(); // If the player is trying to switch maps, do it if (player_cmpDestMap(p1, p2) == GFraMe_ret_ok) { gv_setValue(SWITCH_MAP, 1); return; } if (!player_isAlive(p1) && !player_isInsideMap(p1)) { GFraMe_ret rv; // Recover previous state rv = gv_load(SAVEFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error loading map", __err_ret); // Increase death counter gv_inc(PL1_DEATH); // Save death counter gv_setValue(GAME_TIME, timer_getTime()); rv = gv_save(SAVEFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error saving map", __err_ret); // Force reload gv_setValue(SWITCH_MAP, 1); } if (!player_isAlive(p2) && !player_isInsideMap(p2)) { GFraMe_ret rv; // Recover previous state rv = gv_load(SAVEFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error loading map", __err_ret); // Increase death counter gv_inc(PL2_DEATH); // Save death counter gv_setValue(GAME_TIME, timer_getTime()); rv = gv_save(SAVEFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error saving map", __err_ret); // Force reload gv_setValue(SWITCH_MAP, 1); } GFraMe_event_update_end(); return; __err_ret: gl_running = 0; return; }
/** * Update the state * * @param pGame The game's context * @return GFMRV_OK, GFMRV_ARGUMENTS_BAD, ... */ gfmRV intro_update_game(gameCtx *pGame) { gfmRV rv; introCtx *pIntro; gfmInputState reset; int nreset; // Sanitize arguments ASSERT(pGame, GFMRV_ARGUMENTS_BAD); ASSERT(pGame->pState, GFMRV_ARGUMENTS_BAD); // Get the current state pIntro = (introCtx*)(pGame->pState); if (player_isAlive(pIntro->pPl) == GFMRV_FALSE) { pIntro->state = intro_gameover; rv = gfmText_setText(pGame->common.pText, docWin, strlen(docWin), 1/*doCopy*/); ASSERT_NR(rv == GFMRV_OK); } else if (doc_isAlive(pIntro->pDoc) == GFMRV_FALSE) { pIntro->state = intro_gameover; rv = gfmText_setText(pGame->common.pText, dinoWin, strlen(dinoWin), 1/*doCopy*/); ASSERT_NR(rv == GFMRV_OK); } rv = gfm_getKeyState(&reset, &nreset, pGame->pCtx, pGame->resetHnd); ASSERT_NR(rv == GFMRV_OK); if ((reset & gfmInput_justPressed) == gfmInput_justPressed) { pGame->state = state_reset; return GFMRV_OK; } // Update the player rv = player_update(pIntro->pPl, pGame); ASSERT_NR(rv == GFMRV_OK); // Update the doc rv = doc_update(pIntro->pDoc, pGame); ASSERT_NR(rv == GFMRV_OK); // Update the bullet rv = gfmSprite_update(pIntro->pBullet1, pGame->pCtx); ASSERT_NR(rv == GFMRV_OK); rv = gfmSprite_update(pIntro->pBullet2, pGame->pCtx); ASSERT_NR(rv == GFMRV_OK); // Collide everything do { int height, width; // Initialize the quadtree, making it a little bigger than the screen rv = gfm_getCameraDimensions(&width, &height, pGame->pCtx); ASSERT_NR(rv == GFMRV_OK); rv = gfmQuadtree_initRoot(pGame->common.pQt, -2/*x*/, -2/*y*/, width + 4, height + 4, 4/*maxDepth*/, 6/*maxNodes*/); ASSERT_NR(rv == GFMRV_OK); // Populate the quadtree with the tilemap's hitboxes rv = gfmQuadtree_populateTilemap(pGame->common.pQt, pGame->common.pTMap); ASSERT_NR(rv == GFMRV_OK); // Collides the player against the world rv = player_collide(pIntro->pPl, pGame); ASSERT_NR(rv == GFMRV_OK); // Collides the doc against the world rv = doc_collide(pIntro->pDoc, pGame); ASSERT_NR(rv == GFMRV_OK); // Collide the bullet against the world rv = gfmQuadtree_collideSprite(pGame->common.pQt, pIntro->pBullet1); ASSERT_NR(rv == GFMRV_QUADTREE_OVERLAPED || rv == GFMRV_QUADTREE_DONE); // If a collision was detected, handle it and continue the operation if (rv == GFMRV_QUADTREE_OVERLAPED) { rv = collide(pGame->common.pQt); ASSERT_NR(rv == GFMRV_OK); } rv = gfmQuadtree_collideSprite(pGame->common.pQt, pIntro->pBullet2); ASSERT_NR(rv == GFMRV_QUADTREE_OVERLAPED || rv == GFMRV_QUADTREE_DONE); // If a collision was detected, handle it and continue the operation if (rv == GFMRV_QUADTREE_OVERLAPED) { rv = collide(pGame->common.pQt); ASSERT_NR(rv == GFMRV_OK); } } while (0); rv = GFMRV_OK; __ret: return rv; }