From baf1203cfec2cefd83a58148baa328568ee724e4 Mon Sep 17 00:00:00 2001 From: Josh K Date: Tue, 17 Jul 2018 23:30:35 -0400 Subject: [PATCH] Initial state of codebase refactor. --- lmdave.c => game.c | 307 +++++++++++++++++++++++---------------------- lmdave.h => game.h | 6 +- util/levels.c | 10 +- util/tiles.c | 20 +-- util/util.h | 16 +-- 5 files changed, 183 insertions(+), 176 deletions(-) rename lmdave.c => game.c (57%) rename lmdave.h => game.h (96%) diff --git a/lmdave.c b/game.c similarity index 57% rename from lmdave.c rename to game.c index 58bb1b9..69f23c6 100644 --- a/lmdave.c +++ b/game.c @@ -1,4 +1,4 @@ -#include "lmdave.h" +#include "game.h" // global game state game_state_t* gs = NULL; @@ -6,22 +6,28 @@ game_state_t* gs = NULL; game_assets_t* g_assets = NULL; // initialize a new game state -void init_game() { - gs->quit = 0; - gs->current_level = 0; +static void G_Init() { + gs = malloc( sizeof(game_state_t) ); + memset( gs, 0, sizeof(game_state_t) ); - // clean dave state - memset( &gs->ds, 0, sizeof(dave_state_t) ); - - // copy all levels loaded from exe by util - for ( int i = 0; i < NUM_EXE_LEVELS; ++i ) - GetLevel( i, &gs->levels[i] ); + // clean player state + memset( &gs->ps, 0, sizeof(player_state_t) ); } // initialize game assets -void init_assets( SDL_Renderer* r ) { +static void G_InitAssets( SDL_Renderer* r ) { + // load resources from DAVE.EXE + Util_LoadTiles(); + Util_LoadLevels(); + + g_assets = malloc( sizeof(game_assets_t) ); + + // copy all levels loaded from exe by util + for ( int i = 0; i < NUM_EXE_LEVELS; ++i ) + Util_GetLevel( i, &gs->levels[i] ); + // get loaded tile surface array from util lib - SDL_Surface** tileSfcs = GetTileSurfaces(); + SDL_Surface** tileSfcs = Util_GetTileSurfaces(); // convert each surface from util's array to g_asset texture array for ( int i = 0; i < NUM_EXE_TILES; ++i ) { @@ -31,40 +37,43 @@ void init_assets( SDL_Renderer* r ) { SDL_SetColorKey( tileSfcs[i], 1, SDL_MapRGB( tileSfcs[i]->format, 0, 0, 0 ) ); g_assets->tile_tx[i] = SDL_CreateTextureFromSurface( r, tileSfcs[i] ); } + + // tile surfaces should be converted as textures inside g_assets now + Util_FreeTileSurfaces(); } // sets new beginning state based on current level -void start_level() { +void W_StartLevel() { gs->view_x = 0; gs->view_y = 0; gs->scroll_x = 0; - gs->ds.jump_timer = 0; - gs->ds.on_ground = 0; - gs->ds.do_jump = 0; + gs->ps.jump_timer = 0; + gs->ps.on_ground = 0; + gs->ps.do_jump = 0; // hardcoded player starts switch ( gs->current_level ) { - case 0: case 4: case 5: case 7: case 9: gs->ds.tx = 2; gs->ds.ty = 8; break; - case 1: gs->ds.tx = 1; gs->ds.ty = 8; break; - case 2: gs->ds.tx = 2; gs->ds.ty = 5; break; - case 3: gs->ds.tx = 1; gs->ds.ty = 5; break; - case 6: gs->ds.tx = 1; gs->ds.ty = 2; break; - case 8: gs->ds.tx = 6; gs->ds.ty = 1; break; + case 0: case 4: case 5: case 7: case 9: gs->ps.tx = 2; gs->ps.ty = 8; break; + case 1: gs->ps.tx = 1; gs->ps.ty = 8; break; + case 2: gs->ps.tx = 2; gs->ps.ty = 5; break; + case 3: gs->ps.tx = 1; gs->ps.ty = 5; break; + case 6: gs->ps.tx = 1; gs->ps.ty = 2; break; + case 8: gs->ps.tx = 6; gs->ps.ty = 1; break; default: break; } - gs->ds.px = gs->ds.tx * TILE_SIZE; - gs->ds.py = gs->ds.ty * TILE_SIZE; + gs->ps.px = gs->ps.tx * TILE_SIZE; + gs->ps.py = gs->ps.ty * TILE_SIZE; // reset items - gs->ds.gun = 0; - gs->ds.jetpack = 0; - gs->ds.trophy = 0; - gs->ds.check_door = 0; + gs->ps.gun = 0; + gs->ps.jetpack = 0; + gs->ps.trophy = 0; + gs->ps.check_door = 0; } // poll input -void check_input() { +static void G_CheckInput() { SDL_Event ev; while ( SDL_PollEvent( &ev ) ) { @@ -80,7 +89,7 @@ void check_input() { // android back if ( key == SDLK_AC_BACK ) { gs->quit = 1; } // jump event - if ( key == SDLK_UP || key == SDLK_z ) { gs->ds.try_jump = 1; } + if ( key == SDLK_UP || key == SDLK_z ) { gs->ps.try_jump = 1; } } break; default: break; @@ -91,43 +100,47 @@ void check_input() { const uint8_t* keys = SDL_GetKeyboardState( NULL ); // attempt dave movement by setting try_ flags - if ( keys[SDL_SCANCODE_RIGHT] ) gs->ds.try_right = 1; - if ( keys[SDL_SCANCODE_LEFT] ) gs->ds.try_left = 1; - //if ( keys[SDL_SCANCODE_UP] ) gs->ds.try_jump = 1; + if ( keys[SDL_SCANCODE_RIGHT] ) gs->ps.try_right = 1; + if ( keys[SDL_SCANCODE_LEFT] ) gs->ps.try_left = 1; + //if ( keys[SDL_SCANCODE_UP] ) gs->ps.try_jump = 1; } // clear all try input flags at end of frame -void clear_input() { - gs->ds.try_left = 0; - gs->ds.try_right = 0; - gs->ds.try_jump = 0; - gs->ds.try_fire = 0; - gs->ds.try_jetpack = 0; - gs->ds.try_up = 0; - gs->ds.try_down = 0; +static void G_ClearInput() { + gs->ps.try_left = 0; + gs->ps.try_right = 0; + gs->ps.try_jump = 0; + gs->ps.try_fire = 0; + gs->ps.try_jetpack = 0; + gs->ps.try_up = 0; + gs->ps.try_down = 0; } -// remove item from world -void pickup_item( uint8_t tx, uint8_t ty ) { +// pickup functionality and remove from world +void P_PickupItem() { + uint8_t tx = gs->ps.check_pickup_x; + uint8_t ty = gs->ps.check_pickup_y; + if ( !tx || !ty ) return; uint8_t til = gs->levels[gs->current_level].tiles[ty * 100 + tx]; + // pickup functionality here - if ( til == 4 ) gs->ds.jetpack = 0xff; + if ( til == 4 ) gs->ps.jetpack = 0xff; if ( til == 10 ) { - gs->ds.score += 1000; - gs->ds.trophy = 1; + gs->ps.score += 1000; + gs->ps.trophy = 1; } - if ( til == 20 ) gs->ds.gun = 1; + if ( til == 20 ) gs->ps.gun = 1; // remove gs->levels[gs->current_level].tiles[ty * 100 + tx] = 0; - gs->ds.check_pickup_x = 0; - gs->ds.check_pickup_y = 0; + gs->ps.check_pickup_x = 0; + gs->ps.check_pickup_y = 0; } // returns 1 if passed pixel point is not within a solid tile -uint8_t is_clear( uint16_t px, uint16_t py ) { +uint8_t W_IsClear( uint16_t px, uint16_t py ) { uint8_t tx, ty; // tile pos uint8_t til; // tile index @@ -144,130 +157,131 @@ uint8_t is_clear( uint16_t px, uint16_t py ) { // pickups if ( til == 10 || til == 4 || til == 20 || (til >= 47 && til <= 52) ) { - gs->ds.check_pickup_x = tx; - gs->ds.check_pickup_y = ty; + gs->ps.check_pickup_x = tx; + gs->ps.check_pickup_y = ty; } // door if ( til == 2 ) { - gs->ds.check_door = 1; + gs->ps.check_door = 1; } return 1; } // update collision point clear flags -void check_collision() { +void P_UpdateCollision() { // 8 points of collision; relative to top left of tile 56 neutral frame (20x16) // 0, 1 = top left, top right - gs->ds.col_point[0] = is_clear( gs->ds.px + 4, gs->ds.py - 0 ); - gs->ds.col_point[1] = is_clear( gs->ds.px + 10, gs->ds.py - 0 ); + gs->ps.col_point[0] = W_IsClear( gs->ps.px + 4, gs->ps.py - 0 ); + gs->ps.col_point[1] = W_IsClear( gs->ps.px + 10, gs->ps.py - 0 ); // 2, 3 = right edge - gs->ds.col_point[2] = is_clear( gs->ds.px + 12, gs->ds.py + 2 ); - gs->ds.col_point[3] = is_clear( gs->ds.px + 12, gs->ds.py + 14 ); + gs->ps.col_point[2] = W_IsClear( gs->ps.px + 12, gs->ps.py + 2 ); + gs->ps.col_point[3] = W_IsClear( gs->ps.px + 12, gs->ps.py + 14 ); // 4, 5 = bottom edge - gs->ds.col_point[4] = is_clear( gs->ds.px + 10, gs->ds.py + 16 ); - gs->ds.col_point[5] = is_clear( gs->ds.px + 4, gs->ds.py + 16 ); + gs->ps.col_point[4] = W_IsClear( gs->ps.px + 10, gs->ps.py + 16 ); + gs->ps.col_point[5] = W_IsClear( gs->ps.px + 4, gs->ps.py + 16 ); // 6, 7 = left edge - gs->ds.col_point[6] = is_clear( gs->ds.px + 2, gs->ds.py + 14 ); - gs->ds.col_point[7] = is_clear( gs->ds.px + 2, gs->ds.py + 2 ); + gs->ps.col_point[6] = W_IsClear( gs->ps.px + 2, gs->ps.py + 14 ); + gs->ps.col_point[7] = W_IsClear( gs->ps.px + 2, gs->ps.py + 2 ); // update on_ground flag if a bottom point (4,5) is not clear - gs->ds.on_ground = (!gs->ds.col_point[4] || !gs->ds.col_point[5]); + gs->ps.on_ground = (!gs->ps.col_point[4] || !gs->ps.col_point[5]); } // validate input whose try flags were set -void verify_input() { +void P_VerifyInput() { // right; col points 2, 3 - if ( gs->ds.try_right && gs->ds.col_point[2] && gs->ds.col_point[3] ) { - gs->ds.do_right = 1; + if ( gs->ps.try_right && gs->ps.col_point[2] && gs->ps.col_point[3] ) { + gs->ps.do_right = 1; } // left; col points 6, 7 - if ( gs->ds.try_left && gs->ds.col_point[6] && gs->ds.col_point[7] ) { - gs->ds.do_left = 1; + if ( gs->ps.try_left && gs->ps.col_point[6] && gs->ps.col_point[7] ) { + gs->ps.do_left = 1; } // jump; on_ground and col points 0, 1 - if ( gs->ds.try_jump && gs->ds.on_ground && !gs->ds.do_jump - && (gs->ds.col_point[0] && gs->ds.col_point[1]) ) { - gs->ds.do_jump = 1; + if ( gs->ps.try_jump && gs->ps.on_ground && !gs->ps.do_jump + && (gs->ps.col_point[0] && gs->ps.col_point[1]) ) { + gs->ps.do_jump = 1; } // reset jump timer if contact a ground while still "jumping" - if ( gs->ds.try_jump && gs->ds.on_ground && gs->ds.jump_timer ) - gs->ds.jump_timer = 0; + if ( gs->ps.try_jump && gs->ps.on_ground && gs->ps.jump_timer ) + gs->ps.jump_timer = 0; } -// apply validated dave movement -void move_dave() { - // update dave's tile pos +// apply validated player movement +void P_Move() { + // update player's tile pos // sample x towards the center - gs->ds.tx = (gs->ds.px + TILE_SIZE / 2) / TILE_SIZE; - gs->ds.ty = gs->ds.py / TILE_SIZE; + gs->ps.tx = (gs->ps.px + TILE_SIZE / 2) / TILE_SIZE; + gs->ps.ty = gs->ps.py / TILE_SIZE; - if ( gs->ds.do_right ) { - gs->ds.px += 2; - gs->ds.do_right = 0; + if ( gs->ps.do_right ) { + gs->ps.px += 2; + gs->ps.do_right = 0; } - if ( gs->ds.do_left ) { - gs->ds.px -= 2; - gs->ds.do_left = 0; + if ( gs->ps.do_left ) { + gs->ps.px -= 2; + gs->ps.do_left = 0; } - if ( gs->ds.do_jump ) { - if ( !gs->ds.jump_timer ) - gs->ds.jump_timer = 25; + if ( gs->ps.do_jump ) { + if ( !gs->ps.jump_timer ) + gs->ps.jump_timer = 25; - if ( gs->ds.col_point[0] && gs->ds.col_point[1] ) { - if ( gs->ds.jump_timer > 12 ) - gs->ds.py -= 2; - if ( gs->ds.jump_timer >= 7 && gs->ds.jump_timer <= 12 ) - gs->ds.py -= 1; - gs->ds.jump_timer--; - } else gs->ds.jump_timer = 0; + if ( gs->ps.col_point[0] && gs->ps.col_point[1] ) { + if ( gs->ps.jump_timer > 12 ) + gs->ps.py -= 2; + if ( gs->ps.jump_timer >= 7 && gs->ps.jump_timer <= 12 ) + gs->ps.py -= 1; + gs->ps.jump_timer--; + } else gs->ps.jump_timer = 0; - //gs->ds.jump_timer--; + //gs->ps.jump_timer--; - if ( !gs->ds.jump_timer ) - gs->ds.do_jump = 0; + if ( !gs->ps.jump_timer ) + gs->ps.do_jump = 0; } } -// apply gravity to dave -void apply_gravity() { - if ( !gs->ds.do_jump && !gs->ds.on_ground ) { +// apply gravity to player +void P_ApplyGravity() { + if ( !gs->ps.do_jump && !gs->ps.on_ground ) { // check below sprite - if ( is_clear( gs->ds.px + 4, gs->ds.py + 17 ) && is_clear( gs->ds.px + 10, gs->ds.py + 17 ) ) - gs->ds.py += 2; + if ( W_IsClear( gs->ps.px + 4, gs->ps.py + 17 ) && W_IsClear( gs->ps.px + 10, gs->ps.py + 17 ) ) + gs->ps.py += 2; else { // align to tile - uint8_t not_align = gs->ds.py % TILE_SIZE; + uint8_t not_align = gs->ps.py % TILE_SIZE; if ( not_align ) { - gs->ds.py = not_align < (TILE_SIZE / 2) ? - gs->ds.py - not_align : gs->ds.py + TILE_SIZE - not_align; + gs->ps.py = not_align < (TILE_SIZE / 2) ? + gs->ps.py - not_align : gs->ps.py + TILE_SIZE - not_align; } } } } -void update_level() { +// level-wide state update +void W_Update() { // check if at door and has trophy - if ( gs->ds.check_door ) { - if ( gs->ds.trophy ) { + if ( gs->ps.check_door ) { + if ( gs->ps.trophy ) { if ( gs->current_level < 9 ) { gs->current_level++; - start_level(); + W_StartLevel(); } else { // finshed level 10 gs->quit = 1; } } else { // no trophy - gs->ds.check_door = 0; + gs->ps.check_door = 0; } } } // update game view based on set scroll values -void scroll_screen() { +void W_ScrollView() { // scroll view if dave is about to move off view - if ( gs->ds.tx - gs->view_x >= 18 ) + if ( gs->ps.tx - gs->view_x >= 18 ) gs->scroll_x = 15; - if ( gs->ds.tx - gs->view_x < 2 ) + if ( gs->ps.tx - gs->view_x < 2 ) gs->scroll_x = -15; // do the scroll @@ -281,28 +295,28 @@ void scroll_screen() { } } -// update game logic -void update_game() { +// main update routine +static void G_Update() { // update collision point flags - check_collision(); + P_UpdateCollision(); // pickups - pickup_item( gs->ds.check_pickup_x, gs->ds.check_pickup_y ); + P_PickupItem(); // verify input try flags - verify_input(); - // apply dave movement - move_dave(); + P_VerifyInput(); + // apply player movement + P_Move(); // game view scrolling - scroll_screen(); - // dave gravity - apply_gravity(); + W_ScrollView(); + // player gravity + P_ApplyGravity(); // update level-wide state - update_level(); + W_Update(); // reset input flags - clear_input(); + G_ClearInput(); } // draw level at current view -void draw_world( SDL_Renderer* r ) { +void Draw_World( SDL_Renderer* r ) { SDL_Rect dst; // draw level view 20x10 tiles at 16x16px for ( int j = 0; j < 10; ++j ) { @@ -316,33 +330,33 @@ void draw_world( SDL_Renderer* r ) { } } -// draw dave -void draw_dave( SDL_Renderer* r ) { +// draw player +void Draw_Player( SDL_Renderer* r ) { SDL_Rect dst; // relative to view - dst.x = gs->ds.px - gs->view_x * TILE_SIZE; - dst.y = gs->ds.py; + dst.x = gs->ps.px - gs->view_x * TILE_SIZE; + dst.y = gs->ps.py; // tile 56 neutral; 20x16px uint8_t til = 53; dst.w = 20; dst.h = 16; // render // grounded debug - if ( gs->ds.on_ground ) { + if ( gs->ps.on_ground ) { SDL_SetRenderDrawColor( r, 255, 0, 255, 255 ); SDL_RenderDrawRect( r, &dst ); } SDL_RenderCopy( r, g_assets->tile_tx[til], NULL, &dst ); } -// draw to renderer -void render( SDL_Renderer* r ) { +// main drawing routine +static void G_Draw( SDL_Renderer* r ) { // clear backbuffer SDL_SetRenderDrawColor( r, 0, 40, 80, 0xff ); SDL_RenderClear( r ); - draw_world( r ); - draw_dave( r ); + Draw_World( r ); + Draw_Player( r ); // flip buffers SDL_RenderPresent( r ); @@ -352,13 +366,7 @@ void render( SDL_Renderer* r ) { //const uint8_t R_SCALE = 3; int main( int argc, char** argv ) { - // load resources from DAVE.EXE - LoadTiles(); - LoadLevels(); - - gs = malloc( sizeof(game_state_t) ); - init_game(); - + // initialize SDL if ( SDL_Init( SDL_INIT_VIDEO ) ) SDL_Log( "SDL Init error: %s\n", SDL_GetError() ); @@ -384,26 +392,25 @@ int main( int argc, char** argv ) { // scaling hint //SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "linear" ); - g_assets = malloc( sizeof(game_assets_t) ); - init_assets( renderer ); - // tile surfaces should be converted as textures inside g_assets now - FreeTileSurfaces(); + // initialize game state and assets + G_Init(); + G_InitAssets( renderer ); // clear initial frame SDL_SetRenderDrawColor( renderer, 0, 40, 80, 0xff ); SDL_RenderClear( renderer ); // set state for first level - start_level(); + W_StartLevel(); // main loop while ( gs->quit == 0 ) { // fixed timestep uint32_t st = SDL_GetTicks(); - check_input(); - update_game(); - render( renderer ); + G_CheckInput(); + G_Update(); + G_Draw( renderer ); uint32_t delay = FRAME_DELAY - (SDL_GetTicks() - st); delay = delay > FRAME_DELAY ? 0 : delay; diff --git a/lmdave.h b/game.h similarity index 96% rename from lmdave.h rename to game.h index 2f59a6e..0c1234e 100644 --- a/lmdave.h +++ b/game.h @@ -41,7 +41,7 @@ typedef struct { // collision point clear flags; 1 = clear uint8_t col_point[8]; -} dave_state_t; +} player_state_t; // global game state typedef struct { @@ -51,8 +51,8 @@ typedef struct { uint8_t view_x, view_y; int8_t scroll_x; - // dave player state - dave_state_t ds; + // player state + player_state_t ps; level_t levels[NUM_EXE_LEVELS]; // copied from exe util's GetLevel } game_state_t; diff --git a/util/levels.c b/util/levels.c index e1ee7d3..7d1bf20 100644 --- a/util/levels.c +++ b/util/levels.c @@ -8,13 +8,13 @@ static level_t levels[NUM_EXE_LEVELS]; // copy a single level structure for external use -void GetLevel( unsigned n, level_t* lvl ) { +void Util_GetLevel( unsigned n, level_t* lvl ) { if ( n > NUM_EXE_LEVELS - 1 ) n = 0; memcpy( lvl, &levels[n], sizeof(level_t) ); } // export all levels to seperate .dat file -void SaveLevels() { +void Util_SaveLevels() { for ( int l = 0; l < NUM_EXE_LEVELS; ++l ) { char fname[1024]; snprintf( fname, 1024, "./levels/level%02u.dat", l ); @@ -38,7 +38,7 @@ void SaveLevels() { } // fill global level array with dat from exe -void LoadLevels() { +void Util_LoadLevels() { const uint32_t lvl_dat_addr = 0x26e0a; SDL_RWops* ddexe = SDL_RWFromFile( "res/DAVE.EXE", "rb" ); @@ -72,7 +72,7 @@ void LoadLevels() { } // create a large world map image with all levels -void CreateWorldMap() { +void Util_CreateWorldMap() { // create big empty surface for containing entire world map SDL_Surface* map = SDL_CreateRGBSurface( 0, 1600, 1600, 32, 0, 0, 0, 0 ); // level, row, column @@ -84,7 +84,7 @@ void CreateWorldMap() { dst.x = x * 16; dst.y = l * 160 + y * 16; dst.w = 16; dst.h = 16; - SDL_Surface** tile_sfc = GetTileSurfaces(); + SDL_Surface** tile_sfc = Util_GetTileSurfaces(); SDL_BlitSurface( tile_sfc[til], NULL, map, &dst ); // hardcoded player and monster starts diff --git a/util/tiles.c b/util/tiles.c index d52a479..5c3f7bc 100644 --- a/util/tiles.c +++ b/util/tiles.c @@ -9,7 +9,7 @@ static SDL_Surface* tile_sfc[NUM_EXE_TILES]; // export all tiles to bmp -void SaveTiles() { +void Util_SaveTiles() { // Save out the all tile surfaces for ( int curtil = 0; curtil < NUM_EXE_TILES; ++curtil ) { SDL_Surface* sfc = tile_sfc[curtil]; @@ -21,12 +21,12 @@ void SaveTiles() { } // return tile surface array for external use -SDL_Surface** GetTileSurfaces() { +SDL_Surface** Util_GetTileSurfaces() { return tile_sfc; } // fill global tile array with tiles from exe -void LoadTiles() { +void Util_LoadTiles() { const uint32_t vga_data_addr = 0x120f0; const uint32_t vga_pal_addr = 0x26b0a; // exe assumed uncompressed @@ -144,7 +144,7 @@ void LoadTiles() { } // free all loaded exe's tile surfaces -void FreeTileSurfaces() { +void Util_FreeTileSurfaces() { for ( int i = 0; i < NUM_EXE_TILES; ++i ) { SDL_FreeSurface( tile_sfc[i] ); } @@ -161,15 +161,15 @@ int main( int argc, char** argv ) { } SDL_RWclose( dscor );*/ - LoadTiles(); - SaveTiles(); + Util_LoadTiles(); + Util_SaveTiles(); // LEVELS - LoadLevels(); - SaveLevels(); - CreateWorldMap(); + Util_LoadLevels(); + Util_SaveLevels(); + Util_CreateWorldMap(); - FreeTileSurfaces(); + Util_FreeTileSurfaces(); return 0; } diff --git a/util/util.h b/util/util.h index dd60c73..f249834 100644 --- a/util/util.h +++ b/util/util.h @@ -9,10 +9,10 @@ #define NUM_EXE_LEVELS 10 // tiles -void LoadTiles(); -SDL_Surface** GetTileSurfaces(); -void SaveTiles(); -void FreeTileSurfaces(); +void Util_LoadTiles(); +SDL_Surface** Util_GetTileSurfaces(); +void Util_SaveTiles(); +void Util_FreeTileSurfaces(); // level structure // byte[256] path, two signed 8bit relative movement, 0xea 0xea for end @@ -26,9 +26,9 @@ typedef struct { } level_t; // levels -void LoadLevels(); -void GetLevel( unsigned n, level_t* lvl ); -void SaveLevels(); -void CreateWorldMap(); +void Util_LoadLevels(); +void Util_GetLevel( unsigned n, level_t* lvl ); +void Util_SaveLevels(); +void Util_CreateWorldMap(); #endif