/* ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, TravelState - map/travel loading state ```````````````````````````````` This state loaded when a new map is to be loaded. It loads in the given map file, loads up new Resources required (freeing those not required), and creates a LiveMap. Once complete, it pops off the stack and pushes GameState onto the stack. */ #include "globals.h" #include "State_Travel.h" #include "State_Menu.h" #include "State_Game.h" #include "state.h" #include "game_globals.h" #include "string.h" #include "LiveMap.h" #include "Map.h" #include "AnimData.h" #include "EntityData.h" #include "sprite.h" #include "Ui.h" char spins[5] = "/-\\|"; int openTravelState() { report(DEBUG, "TravelState", "opened, attempting to travel to %s", travel_map); spin = 0; //travel_text = newText(g_large_font, ""); //changeText(travel_text, "traveling to %s %c", travel_map, spins[spin]); travel_text = newTextt(&g_large_glyphs, ui_colors, ""); setTextt(travel_text, "traveling to %s %c", travel_map, spins[spin]); travel_text->box.x = g_v_width / 2 - travel_text->box.w/2; travel_text->box.y = g_v_height / 2 - travel_text->box.h/2; state_text = newTextt(&g_medium_glyphs, ui_colors, ""); setTextt(state_text, "opening..."); state_text->box.x = g_v_width/2 - state_text->box.w; state_text->box.y = travel_text->box.y + travel_text->box.h; map_data = newMapData(); // live_map is destroyed in closeGameState! travel_state = LOAD_MAP; return 0; } int handleTravelState() { return 0; } void processTravelState() { accumulator = g_tickrate; if (spin_time >= 100) { if(spin < 3) { spin++; } else { spin = 0; } spin_time = 0; } setTextt(travel_text, "traveling to %s %c", travel_map, spins[spin]); spin_time += g_tickrate.m; char *full_name; switch(travel_state) { case LOAD_MAP: // create full file name full_name = malloc(1); full_name = setStringF(full_name, "%s%s%s", MAP_DIR, travel_map, MAP_EXT); // attempt to load in map data //int ret = loadLiveMap(live_map, full_name); int ret = loadMapData(map_data, full_name); free(full_name); // were we successful? if (ret != 0) { travel_state = ERROR_LOAD; timer = 3000; } else { travel_state = LOAD_ENTITIES; timer = 5000; setTextt(state_text, "loading entities..."); x = y = 0; // initialize our animation resources :) live_animations = newResources(1, 128); // we addResource ourself, so it is not set here live_animations->loadResource_func = (void*)loadAnimData_res; live_animations->freeResource_func = (void*)freeAnimData; // initialize our sprite resources live_sprites = newResources(1, 256); live_sprites->loadResource_func = (void*)createSpriteFromFile; live_sprites->freeResource_func = (void*)freeSprite; // initialize our entity data resources live_entities = newResources(3, 32); live_entities->loadResource_func = (void*)loadEntityData_res; live_entities->freeResource_func = (void*)freeEntityData; } //fileToBuffer(file_buffer, travel_map); break; case LOAD_ENTITIES: {} struct EntityMapData *entity_mdata; while ((entity_mdata = iterObject(map_data->entities)) != NULL) { //printf("attempting to load %s\n", entity_mdata->name); loadResource(live_entities, entity_mdata->name); } setTextt(state_text, "loaded entities"); travel_state = LOAD_ENTITY_ANIM; x = y = 0; break; case LOAD_ENTITY_ANIM: if (x < live_entities->length) { if (live_entities->data[x] == NULL) { x++; break; } struct EntityData *entity_data = live_entities->data[x]; loadResource(live_animations, entity_data->anim); setTextt(state_text, "loaded animdata %s", entity_data->anim); x++; } else { setTextt(state_text, "loading animations..."); travel_state = LOAD_ANIMATIONS; } break; case LOAD_ANIMATIONS: // load player loadResource(live_animations, map_data->player_data.anim); // load player loadResource(live_animations, "cyb_metabit"); // x = y = 0; travel_state = LOAD_CELL_ANIM; break; case LOAD_CELL_ANIM: if (x < map_data->width) { for (y = 0; y < map_data->height; y++) { if (map_data->cells[x][y].decor_count > 0) { int d; for(d = 0; d < map_data->cells[x][y].decor_count; d++) { struct DecorMapData *decor_data = map_data->cells[x][y].decor[d]; int ret = loadResource(live_animations, decor_data->anim); // TODO: if we fail, should we bail? //printf("loaded %s as %d\n", decor_data->anim, ret); setTextt(state_text, "loaded %s", decor_data->anim); } } } x++; } else { x = 0; y = 0; setTextt(state_text, "loading sprites..."); travel_state = LOAD_SPRITES; } break; case LOAD_SPRITES: if (x < live_animations->length) { if (live_animations->data[x] == NULL) { x++; break; } struct AnimData *anim_data = live_animations->data[x]; struct SetData *set_data; struct FaceData *face_data; int s, f; for (s = 0; s < anim_data->count; s++) { set_data = anim_data->sets[s]; for (f = 0; f < set_data->count; f++) { face_data = set_data->faces[f]; // load in FrameSheet full_name = malloc(1); full_name = setStringF(full_name, "%s%s/%s/%s", ANIM_DIR, anim_data->name, set_data->name, face_data->name); face_data->sheet = loadFrameSheet(face_data->name, full_name); if (face_data->sheet == NULL) { report(ERROR, "beh", "error while loading framesheet"); // TODO: handle fail? } else { printf("loaded %d frames from %s into face %s\n", face_data->sheet->count, full_name, face_data->name); } free(full_name); } } setTextt(state_text, "loaded frames for \"%s\"", anim_data->name); x++; } else { travel_state = INIT_LIVE_MAP; setTextt(state_text, "initializing live map"); } break; case INIT_LIVE_MAP: if ((live_map = initLiveMap(map_data)) == NULL) { report(ERROR, "beh", "error while loading live map"); travel_state = ERROR_LOAD; } else { setTextt(state_text, "starting game"); travel_state = START_GAME; timer = 2048; } freeMapData(map_data); break; case START_GAME: timer -= g_tickrate.m; setTextt(state_text, "starting game in %d", timer); if (timer <= 0) { popState(g_state_manager); } break; case ERROR_LOAD: timer -= g_tickrate.m; setTextt(state_text, "error while loading, returning to menu in %d", timer); if (timer <= 0) { popState(g_state_manager); } break; } // Show a progress bar, once per item // 1. Attempt to load "maps/"+travel_map+".map" // 2. Once loaded into a MapData struct (with EntityData, WallData, TileData), we collect Data types (perhaps pre-defined in .map?) // 3. From the Data types arrays/list, we loadResource each one until complete (updating the text to show current resource) // 4. Once all resources are loaded, we modify live_map to match the MapData, including Floors, Walls, and similar. // 5. popState and push GameState! } void renderTravelState() { //renderText(travel_text, g_v_width/2, g_v_height/2); renderTextt(travel_text); renderTextt(state_text); } void closeTravelState() { report(DEBUG, "TravelState", "closed"); switch(travel_state) { case ERROR_LOAD: case LOAD_ANIMATIONS: pushState(g_state_manager, newState(STATE_DEFAULT, openMenuState, closeMenuState, handleMenuState, processMenuState, renderMenuState)); break; case START_GAME: pushState(g_state_manager, newState(STATE_DEFAULT, openGameState, closeGameState, handleGameState, processGameState, renderGameState)); break; } freeTextt(travel_text); freeTextt(state_text); // }