/** * Playstate implementation. Must initialize it, run the loop and clean it up */ state playstate(int doLoad) { GFraMe_ret rv; state ret; ret = -1; rv = ps_init(doLoad); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init playstate", __ret); GFraMe_event_init(_maxUfps, _maxDfps); _ps_pause = 0; _psRunning = 1; while (gl_running && _psRunning) { #ifdef DEBUG unsigned int t; #endif ps_event(); timer_update(); if (_ps_pause) { ps_doPause(); if (_ps_onOptions) { options(); _ps_onOptions = 0; _ps_lastPress = 300; } } else { if (gv_isZero(SWITCH_MAP)) ps_update(); else { rv = ps_switchMap(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to switch maps", __ret); } } ps_draw(); #ifdef DEBUG t = SDL_GetTicks(); if (t >= _time) { GFraMe_log("t=%04i, U=%03i/%03i D=%03i/%03i", _time - _ltime, _updCalls, _maxUfps, _drwCalls, _maxDfps); _updCalls = 0; _drwCalls = 0; _ltime = _time; _time = SDL_GetTicks() + 1000; } #endif } if (_timerTilCredits >= 5000) ret = CREDITS; else ret = MENUSTATE; __ret: ps_clean(); return ret; }
/** * Converts a point from screen space to world space * @param *x Position with horizontal screen position and * that will return the horizontal world position * @param *y Position with vertical screen position and * that will return the vertical world position */ void GFraMe_screen_point_to_world(int *x, int *y) { GFraMe_assertRet(x != NULL, "Invalid 'x' parameter", _exit); GFraMe_assertRet(y != NULL, "Invalid 'y' parameter", _exit); *x = (int)((*x - GFraMe_buffer_x) / GFraMe_screen_ratio_h); *y = (int)((*y - GFraMe_buffer_y) / GFraMe_screen_ratio_v); return; _exit: *x = -1; *y = -1; }
/** * Menustate implementation. Must initialize it, run the loop and clean it up * * @return To which state it's switching */ state menustate() { GFraMe_ret rv; state ret; struct stMenustate ms; ret = -1; rv = ms_init(&ms); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init menustate", __ret); GFraMe_event_init(GAME_UFPS, GAME_DFPS); // Run the menu while (gl_running && ms.runMenu) { ms_event(&ms); ms_update(&ms); ms_draw(&ms); } // Set the next menu if (ms.curOpt == OPT_CONTINUE) ret = CNT_PLAYSTATE; else if (ms.curOpt == OPT_NEWGAME) ret = NEW_PLAYSTATE; else if (ms.curOpt == OPT_OPTIONS) ret = OPTIONS; else if (ms.curOpt == OPT_MAX) ret = DEMO; __ret: ms_clean(&ms); return ret; }
int main(int argc, char *argv[]) { GFraMe_ret rv; GFraMe_wndext ext; ext.atlas = "new-atlas-2"; ext.atlasWidth = 256; ext.atlasHeight = 256; ext.flags = 0; // Init the framework rv = GFraMe_init(320, 240, 640, 480, "com.gfmgamecorner", "BugSquasher", GFraMe_window_resizable, &ext, 60, 1, 0); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init the framework", _exit); #ifndef GFRAME_MOBILE setIcon(); #endif // Init the audio player rv = GFraMe_audio_player_init(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init the audio", _exit); // Load the textures rv = global_init(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to create global stuff", _exit); GFraMe_audio_player_play_bgm(&gl_song, 0.625); // TODO clear events (there may be a few frames issued) // Run the main loop gl_running = 1; while (gl_running) { ms_loop(); ps_loop(); gos_loop(); } _exit: #ifdef GFRAME_MOBILE GFraMe_log("asd"); GFraMe_log_close(); GFraMe_log("qwe"); #endif GFraMe_audio_player_clear(); global_clear(); GFraMe_quit(); return rv; }
/** * Initialize SDL, already creating a window and a backbuffer. * @param vw Buffer's width (virtual width) * @param vh Buffer's height (virtual height) * @param sw Window's width (screen width); if 0, uses the device width * @param sh Window's height(screen height);if 0, uses the device height * @param name Window's title * @param flags Window creation flags * @return 0 - Success; Anything else - Failure */ GFraMe_ret GFraMe_screen_init(int vw, int vh, int sw, int sh, char *name, GFraMe_window_flags flags, GFraMe_wndext *ext) { GFraMe_ret rv = GFraMe_ret_ok; int w = 0, h = 0; // Get the device dimensions, in case it's needed rv = GFraMe_getDevDimensions(&w, &h); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to get device dimensions", _ret); // If no valid width was passed, use default one if (sw == 0) sw = w; // If no valid height was passed, use default one if (sh == 0) sh = h; #if defined(GFRAME_OPENGL) GFraMe_opengl_setAtt(); // Force OpenGL flags |= SDL_WINDOW_OPENGL; #endif // Create a window GFraMe_window = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, sw, sh, flags); GFraMe_SDLassertRV(GFraMe_window, "Couldn't create a window", rv = GFraMe_ret_window_creation_failed, _ret); // Store window dimensions GFraMe_window_w = sw; GFraMe_window_h = sh; // Store backbuffer dimensions GFraMe_screen_w = vw; GFraMe_screen_h = vh; #if defined(GFRAME_OPENGL) rv = GFraMe_opengl_init(ext->atlas, ext->atlasWidth, ext->atlasHeight, sw, sh, sw / vw, sh / vh, ext->flags); GFraMe_assertRV(rv == GFraMe_ret_ok, "Failed to init opengl", rv = rv, _ret); #else // Create a renderer GFraMe_renderer = SDL_CreateRenderer(GFraMe_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); GFraMe_SDLassertRV(GFraMe_renderer, "Couldn't create renderer", rv = GFraMe_ret_renderer_creation_failed, _ret); // Create a backbuffer GFraMe_screen = SDL_CreateTexture(GFraMe_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, vw, vh); GFraMe_SDLassertRV(GFraMe_screen, "Couldn't create backbuffer", rv = GFraMe_ret_backbuffer_creation_failed, _ret); #endif GFraMe_screen_log_format(); // Set backbuffer dimensions and position GFraMe_set_screen_ratio(); _ret: return rv; }
/** * Adds a mob and collides against everything * * @param pMob The mob * @return GFraMe error code */ GFraMe_ret qt_addMob(mob *pMob) { GFraMe_ret rv; qtNode *pNode; quadtree *pRoot; // Get a new node with the object rv = qt_getMobNode(&pNode, pMob); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to alloc mob's node", __ret); // Get the tree's root qt_getRoot(&pRoot); // Add the node to the quadtree and collide against everything else rv = qt_addNodeCollide(pRoot, pNode); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to insert wall into tree", __ret); rv = GFraMe_ret_ok; __ret: return rv; }
/** * Adds an event and collides against everything else * * @param pEv The event * @return GFraMe error code */ GFraMe_ret qt_addEv(event *pEv) { GFraMe_ret rv; qtNode *pNode; quadtree *pRoot; // Get a new node with the event rv = qt_getEvNode(&pNode, pEv); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to alloc event's node", __ret); // Get the tree's root qt_getRoot(&pRoot); // Add the node to the quadtree and collide against everything else rv = qt_addNodeCollide(pRoot, pNode); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to insert event into tree", __ret); rv = GFraMe_ret_ok; __ret: return rv; }
/** * Adds a player and collides against everything else * * @param pPl The player * @return GFraMe error code */ GFraMe_ret qt_addPl(player *pPl) { GFraMe_ret rv; qtNode *pNode; quadtree *pRoot; // Get a new node with the player rv = qt_getPlNode(&pNode, pPl); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to alloc player's node", __ret); // Get the tree's root qt_getRoot(&pRoot); // Add the node to the quadtree and collide against everything else rv = qt_addNodeCollide(pRoot, pNode); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to insert player into tree", __ret); rv = GFraMe_ret_ok; __ret: return rv; }
/** * Adds a bullet and collides against everything * * @param pBul The bullet * @return GFraMe error code */ GFraMe_ret qt_addBul(bullet *pBul) { GFraMe_ret rv; qtNode *pNode; quadtree *pRoot; // Get a new node with the object rv = qt_getBulNode(&pNode, pBul); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to alloc bullet's node", __ret); // Get the tree's root qt_getRoot(&pRoot); // Add the node to the quadtree and collide against everything else rv = qt_addNodeCollide(pRoot, pNode); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to insert bullet into tree", __ret); rv = GFraMe_ret_ok; __ret: return rv; }
/** * Get the dimensions of the first connected display * @param *ret_width Integer where the width is returned * @param *ret_height Integer where the height is returned * @return 0 - Success; Anything else - Failure */ GFraMe_ret GFraMe_getDevDimensions(int *ret_width, int *ret_height) { GFraMe_ret rv = GFraMe_ret_ok; SDL_DisplayMode mode; // Check if there's at least one display connected GFraMe_assertRV(SDL_GetNumVideoDisplays() > 0, "Couldn't find any displays", rv = GFraMe_ret_num_display_failed, _ret); // Check if there's at least one display mode GFraMe_assertRV(SDL_GetNumDisplayModes(0) > 0, "Couldn't get any display modes", rv = GFraMe_ret_display_modes_failed, _ret); // Try to get it's dimensions rv = SDL_GetDisplayMode(0, 0, &mode); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to get the main display mode", _ret); // Return gotten dimensions *ret_width = mode.w; *ret_height = mode.h; _ret: return rv; }
GFraMe_ret GFraMe_tilemap_draw(GFraMe_tilemap *tmap) { int i; GFraMe_ret rv = GFraMe_ret_ok; // TODO check which rect is inside the screen and draw only that! /* // stupid way to use only one loop and no if *inside* the loop i = 0; int x = 0; int y = 0; while (i < tmap->num_tiles) { rv = GFraMe_spriteset_draw(tmap->sset, tmap->data[i], tmap->x + x*tmap->sset->tw, tmap->y + y); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to draw tilemap", _ret); x++; y += tmap->sset->th * (x >= width_in_tiles); x -= width_in_tiles * (x >= width_in_tiles); i++; } */ // Loop each row i = 0; while (i < tmap->width_in_tiles) { int j; // Loop each column j = 0; while (j < tmap->height_in_tiles) { char tile = tmap->data[i + j*tmap->width_in_tiles]; if (tile > 0) rv = GFraMe_spriteset_draw(tmap->sset, tmap->data[i + j*tmap->width_in_tiles], tmap->x + i*tmap->sset->tw, tmap->y + j*tmap->sset->th, 0); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to draw tilemap", _ret); j++; } i++; } _ret: return rv; }
/** * Set a text to be shown * * @param text Text (the pointer will be copied) * @param textLen Text's length * @param x Window's horizontal position (in tiles) * @param y Window's vertical position (in tiles) * @param w Window's width (in tiles) * @param h Window's height (in tiles) */ void ps_showText(char *text, int textLen, int x, int y, int w, int h) { GFraMe_ret rv; GFraMe_save sv, *pSv; int hint; hint = 1; pSv = 0; // Open the configurations rv = GFraMe_save_bind(&sv, CONFFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error reading config file", __ret); pSv = &sv; // Check if the user disabled it GFraMe_save_read_int(&sv, "hint", &hint); if (hint) { textWnd_init(x, y, w, h, text, textLen); _ps_text = 1; } __ret: if (pSv) GFraMe_save_close(pSv); }
/** * Initialize the quadtree for collision * * @param ox Horizontal offset from the center * @param oy Vertical offset from the center * @param w World's width * @param h World's height * @return GFraMe error code */ GFraMe_ret qt_initCol(int ox, int oy, int w, int h) { GFraMe_ret rv; quadtree *pRoot; // Reset any "used" node/qt qt_resetAll(); // Get the tree's root rv = qt_getNewRoot(&pRoot); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to alloc quadtree's root", __ret); // Init the root qt_init(pRoot, 0, QT_MAX); // Set its dimensions pRoot->hb.cx = w / 2 + ox; pRoot->hb.cy = h / 2 + oy; pRoot->hb.hw = w / 2; pRoot->hb.hh = h / 2; rv = GFraMe_ret_ok; __ret: return rv; }
/** * Resize the game while keeping the original aspect ratio * @param max_zoom Maximum zoom value or a value equal to or less than 0 *for any zoom * @param update_window Whether the windows dimensions should be updated * @return The new zoom level or 0 on failure */ double GFraMe_screen_set_keep_ratio(int max_zoom, int update_window) { int w = 0, h = 0; double zoom, hratio, vratio; // Get the actual window's dimension if (update_window) { SDL_GetWindowSize(GFraMe_window, &w, &h); GFraMe_window_w = w; GFraMe_window_h = h; } else { w = GFraMe_window_w; h = GFraMe_window_h; } // Check each possible ratio hratio = (double)w / (double)GFraMe_screen_w; vratio = (double)h / (double)GFraMe_screen_h; if (vratio * GFraMe_screen_w <= w) zoom = vratio; else if (hratio * GFraMe_screen_h <= h) zoom = hratio; else zoom = 0; if (max_zoom > 0 && zoom > max_zoom) zoom = max_zoom; GFraMe_assertRet(zoom, "Invalid aspect ratio", _ret); // Letterbox the game GFraMe_buffer_x = (w - GFraMe_screen_w * zoom) / 2; GFraMe_buffer_y = (h - GFraMe_screen_h * zoom) / 2; GFraMe_buffer_w = GFraMe_screen_w * zoom; GFraMe_buffer_h = GFraMe_screen_h * zoom; GFraMe_screen_ratio_h = zoom; GFraMe_screen_ratio_v= zoom; GFraMe_screen_log_dimensions(zoom); GFraMe_screen_cache_dimensions(); _ret: return zoom; }
/** * Set the destination dimensions keeping a perfect (i.e, integer) aspect ratio * @param max_zoom Maximum zoom value or a value equal to or less than 0 *for any zoom * @param update_window Whether the windows dimensions should be updated * @return The new zoom level or 0 on failure */ int GFraMe_screen_set_pixel_perfect(int max_zoom, int update_window) { int w = 0, h = 0, zoom, hratio, vratio; // Get the actual window's dimension if (update_window) { SDL_GetWindowSize(GFraMe_window, &w, &h); GFraMe_window_w = w; GFraMe_window_h = h; } else { w = GFraMe_window_w; h = GFraMe_window_h; } // Check each possible ratio hratio = (int)( (double)w / (double)GFraMe_screen_w ); vratio = (int)( (double)h / (double)GFraMe_screen_h ); // Get the lesser one if (hratio < vratio) zoom = hratio; else zoom = vratio; // Check if it's a valid zoom if (max_zoom > 0 && zoom > max_zoom) zoom = max_zoom; GFraMe_assertRet(zoom != 0, "Invalid aspect ratio", _ret); // Letterbox the game GFraMe_buffer_x = (w - GFraMe_screen_w * zoom) / 2; GFraMe_buffer_y = (h - GFraMe_screen_h * zoom) / 2; GFraMe_buffer_w = GFraMe_screen_w * zoom; GFraMe_buffer_h = GFraMe_screen_h * zoom; GFraMe_screen_ratio_h = zoom; GFraMe_screen_ratio_v = zoom; GFraMe_screen_log_dimensions(zoom); GFraMe_screen_cache_dimensions(); _ret: return zoom; }
/** * Initialize the playstate * * @return GFraMe error code */ static GFraMe_ret ps_init(int isLoading) { GFraMe_ret rv; GFraMe_save sv, *pSv; int map, plX, plY, time; // Open the configurations rv = GFraMe_save_bind(&sv, CONFFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error reading config file", __ret); pSv = &sv; // Read the desired fps (for update and drawing) rv = GFraMe_save_read_int(&sv, "ufps", &_maxUfps); if (rv != GFraMe_ret_ok) _maxUfps = GAME_UFPS; rv = GFraMe_save_read_int(&sv, "dfps", &_maxDfps); if (rv != GFraMe_ret_ok) _maxDfps = GAME_DFPS; rv = GFraMe_save_read_int(&sv, "speedrun", &_ps_isSpeedrun); if (rv != GFraMe_ret_ok) _ps_isSpeedrun = 0; GFraMe_save_close(&sv); pSv = 0; if (!isLoading) { gv_init(); plX = 16; plY = 184; map = 0; } else { rv = gv_load(SAVEFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to load state", __ret); plX = gv_getValue(DOOR_X) * 8; plY = gv_getValue(DOOR_Y) * 8; map = gv_getValue(MAP); } time = gv_getValue(GAME_TIME); timer_init(time); if (map >= 20) { audio_playBoss(); } else if (map >= 15) { audio_playTensionGoesUp(); } else if (map >= 4) { audio_playMovingOn(); } else { audio_playIntro(); } rv = ui_init(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init ui", __ret); rv = rg_init(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to registry ui", __ret); rv = map_init(&m); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init map", __ret); rv = player_init(&p1, ID_PL1, 224, plX, plY); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init player", __ret); rv = player_init(&p2, ID_PL2, 240, plX, plY); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init player", __ret); rv = map_loadi(m, map); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to init map", __ret); signal_init(); _timerTilCredits = 0; _ps_onOptions = 0; _ps_text = 0; switchState = 0; transition_initFadeOut(); #ifdef DEBUG _updCalls = 0; _drwCalls = 0; _time = 0; _ltime = 0; #endif rv = GFraMe_ret_ok; __ret: if (pSv) GFraMe_save_close(pSv); return rv; }
/** * Initialize the menustate * * @return GFraMe error code */ static GFraMe_ret ms_init(struct stMenustate *ms) { GFraMe_ret rv; GFraMe_save sv; int tmp, ctrPl1, ctrPl2; ms->pO = 0; ms->pM = 0; // Check if there's already a saved game rv = GFraMe_save_bind(&sv, SAVEFILE); ASSERT_NR(rv == GFraMe_ret_ok); // Check if something other than the version is written if (sv.size > 50) ms->hasSave = 1; else ms->hasSave = 0; GFraMe_save_close(&sv); // Check the configurations rv = GFraMe_save_bind(&sv, CONFFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error reading config file", __ret); // Try to read both players control mode ctrPl1 = -1; ctrPl2 = -1; rv = GFraMe_save_read_int(&sv, "ctr_pl1", &tmp); if (rv == GFraMe_ret_ok) ctrPl1 = tmp; rv = GFraMe_save_read_int(&sv, "ctr_pl2", &tmp); if (rv == GFraMe_ret_ok) ctrPl2 = tmp; // set the control scheme if (ctrPl1 != -1 && ctrPl2 != -1) { tmp = ctr_setModeForce(ID_PL1, ctrPl1); if (tmp) tmp = ctr_setModeForce(ID_PL2, ctrPl2); // In case any error happened, set the default if (!tmp) ctr_setDef(); } else ctr_setDef(); // Set the song volume rv = GFraMe_save_read_int(&sv, "music", &tmp); if (rv == GFraMe_ret_ok) audio_setVolume(tmp); else audio_setVolume(60); // Set the sfx volume rv = GFraMe_save_read_int(&sv, "sfx", &tmp); if (rv == GFraMe_ret_ok) sfx_setVolume(tmp); else sfx_setVolume(50); GFraMe_save_close(&sv); // Zero some variables ms->lastPressedTime = 0; ms->firstPress = 0; // Set the selected option if (ms->hasSave) ms->curOpt = 0; else ms->curOpt = 1; // Set text position ms->textX = 112; ms->textY = 176; // Set the dev icon position ms->iconX = 35 * 8; ms->iconY = 25 * 8; // Start the menu ms->runMenu = 1; // Set the title position ms->isTitleSet = 0; ms->j1X = 82; ms->j1Yf = -32.0f; ms->j1Y = -32; ms->j2X = 122; ms->j2Yf = -40.0f; ms->j2Y = -40; ms->aX = 154; ms->aYf = -48.0f; ms->aY = -48; ms->tX = 194; ms->tYf = -54.0f; ms->tY = -54; ms->idleTime = 0; rv = map_init(&ms->pM); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to load background", __ret); rv = map_loadf(ms->pM, "maps/mainmenu.gfm"); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to load background", __ret); rv = obj_getNew(&ms->pO); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to load background", __ret); obj_setZero(ms->pO); obj_setBounds(ms->pO, 8*8, 17*8, 2*8, 2*8); obj_setID(ms->pO, ID_HEARTUP); obj_setCommonEvent(ms->pO, CE_NONE); cam_x = 0; cam_y = 0; cam_setMapDimension(40, 30); audio_playMenu(); 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; }
/** * 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; }
int main(int argc, char *argv[]) { GFraMe_ret rv; GFraMe_save sv, *pSv; GFraMe_wndext ext; int zoom, lang; state st; ext.atlas = "atlas"; ext.atlasWidth = 256; ext.atlasHeight = 256; ext.flags = GFraMe_wndext_none; //ext.flags = GFraMe_wndext_scanline; rv = GFraMe_init ( SCR_W, SCR_H, WND_W, WND_H, ORG, NAME, GFraMe_window_none, // GFraMe_window_fullscreen &ext, FPS, 1, // Log to file 0 // Log append ); GFraMe_assertRet(rv == GFraMe_ret_ok, "Init failed", __ret); setIcon(); // Set the bg color GFraMe_set_bg_color(0x22, 0x20, 0x34, 0xff); // Set the actual game dimensions pSv = 0; rv = GFraMe_save_bind(&sv, CONFFILE); GFraMe_assertRet(rv == GFraMe_ret_ok, "Error opening file", __ret); pSv = &sv; rv = GFraMe_save_read_int(&sv, "zoom", &zoom); if (rv == GFraMe_ret_ok) { // Switch the resolution if (zoom != 0 && zoom != 2) { GFraMe_ret rv; rv = GFraMe_screen_set_window_size(SCR_W*zoom, SCR_H*zoom); if (rv == GFraMe_ret_ok) GFraMe_screen_set_pixel_perfect(0, 1); } else if (zoom == 0) { GFraMe_ret rv; rv = GFraMe_screen_setFullscreen(); if (rv == GFraMe_ret_ok) GFraMe_screen_set_pixel_perfect(0, 1); } } // Check if the language was stored (and load it) rv = GFraMe_save_read_int(&sv, "lang", &lang); if (rv == GFraMe_ret_ok) { if (lang == EN_US) { gl_lang = EN_US; } else if (lang == PT_BR) { gl_lang = PT_BR; } } else { gl_lang = EN_US; } GFraMe_save_close(&sv); pSv = 0; rv = GFraMe_audio_player_init(); GFraMe_assertRet(rv == GFraMe_ret_ok, "Audio player init failed", __ret); rv = gl_init(); GFraMe_assertRet(rv == GFraMe_ret_ok, "global init failed", __ret); GFraMe_controller_init(1); st = MENUSTATE; // st = CREDITS; while (gl_running) { switch (st) { case MENUSTATE: st = menustate(); break; case NEW_PLAYSTATE: st = playstate(0); break; case CNT_PLAYSTATE: st = playstate(1); break; case OPTIONS: st = options(); break; case DEMO: st = demo(); break; case CREDITS: st = credits(); break; default: rv = 123; GFraMe_assertRet(0, "Invalid state!", __ret); } } rv = 0; __ret: if (pSv) GFraMe_save_close(pSv); GFraMe_audio_player_pause(); GFraMe_audio_player_clear(); gl_clean(); GFraMe_controller_close(); GFraMe_quit(); return rv; }
/** * Add a new node to the quadtree, subdivide it as necessary and collide against * every other node * * @param pQt Tree where the collision should be done * @param pNode The node * @return GFraMe error code */ GFraMe_ret qt_addNodeCollide(quadtree *pQt, qtNode *pNode) { GFraMe_ret rv; // Check that the node intersects the tree ASSERT(qtHbIntersect(&pNode->hb, &pQt->hb), GFraMe_ret_ok); if (pQt->children[NW]) { // If there're any children, add into those qtPosition i; // Add the node into each child i = 0; while (i < QT_MAX) { rv = qt_addNodeCollide(pQt->children[i], pNode); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to insert node into child", __ret); i++; } } else if (pQt->nodesCount + 1 > NODES_MAX && pQt->hb.hw * 2 > MIN_WIDTH && pQt->hb.hh * 2 > MIN_HEIGHT) { // If the tree should subdivide qtPosition i; struct stQTNodeLL *tmp; // Subdivide the tree into each subtree i = 0; while (i < QT_MAX) { quadtree *tmp; // Get a new subtree rv = qt_getQuadtree(&tmp); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to alloc tree's child", __ret); // Initialize the child and add it qt_init(tmp, pQt, i); pQt->children[i] = tmp; i++; } // Incremeant the child count pQt->nodesCount++; // Add every node into the children tmp = pQt->nodes; pQt->nodes = 0; while (tmp) { rv = qt_addNodeCollide(pQt, tmp->self); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to insert node into child", __ret); tmp = tmp->next; } // Add this object rv = qt_addNodeCollide(pQt, pNode); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to insert node into child", __ret); } else { // If the node will be added and collided struct stQTNodeLL *newNode, *tmp; // Get a new node, to add into rv = qt_getNodeLL(&newNode); GFraMe_assertRet(rv == GFraMe_ret_ok, "Failed to alloc LL node", __ret); // Initialize the node newNode->self = pNode; newNode->next = 0; // Collides this node against every other on the current subtree if (pQt->nodes) { tmp = pQt->nodes; while (1) { // Check if this intersects the current node if (qtHbIntersect(&pNode->hb, &tmp->self->hb)) checkCollision(pNode, tmp->self); if (tmp->next) // Go to the next node tmp = tmp->next; else // Stop iterating break; } // Add the new node at the end of the linked list tmp->next = newNode; } else pQt->nodes = newNode; // Update the tree's list pQt->nodesCount++; } rv = GFraMe_ret_ok; __ret: return rv; }