void titleScreen() { removeTemporaryData(); freeGameResources(); initGame(); game.status = IN_TITLE; }
void tutorial() { removeTemporaryData(); freeGameResources(); initGame(); loadMap("tutorial", TRUE); cameraSnapToTargetEntity(); }
void startOnMap(char *mapName) { removeTemporaryData(); freeGameResources(); initGame(); loadMap(mapName, TRUE); cameraSnapToTargetEntity(); }
void newGame() { removeTemporaryData(); freeGameResources(); initGame(); stopMusic(); game.overrideMusic = TRUE; loadMap("map04", TRUE); runScript("intro_part1"); }
static void patchSaveGame(char *saveFile, double version) { char location[MAX_VALUE_LENGTH], *line, *savePtr, itemName[MAX_MESSAGE_LENGTH], *returnedName, mapName[MAX_VALUE_LENGTH]; unsigned char *buffer, *originalBuffer; int savedLocation = FALSE, saveMap; FILE *newSave; savePtr = NULL; freeGameResources(); newSave = fopen(tempFile, "wb"); buffer = decompressFile(saveFile); originalBuffer = malloc((strlen((char *)buffer) + 1) * sizeof(unsigned char)); if (originalBuffer == NULL) { showErrorAndExit("Failed to allocate %d bytes to patch save game", (int)((strlen((char *)buffer) + 1) * sizeof(unsigned char))); } strcpy((char *)originalBuffer, (char *)buffer); line = strtok_r((char *)buffer, "\n", &savePtr); returnedName = NULL; mapName[0] = '\0'; while (line != NULL) { if (line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } if (line[strlen(line) - 1] == '\r') { line[strlen(line) - 1] = '\0'; } sscanf(line, "%s", itemName); if (strcmpignorecase("PLAYER_LOCATION", itemName) == 0) { sscanf(line, "%*s %s\n", location); } else if (strcmpignorecase("MAP_NAME", itemName) == 0) { saveMap = TRUE; if (strlen(mapName) == 0 || strcmpignorecase(line, mapName) == 0) { sscanf(line, "%*s %s\n", itemName); returnedName = loadResources(savePtr); if (returnedName != NULL) { STRNCPY(mapName, returnedName, sizeof(mapName)); } /* Rewind to start */ free(buffer); buffer = malloc((strlen((char *)originalBuffer) + 1) * sizeof(unsigned char)); if (buffer == NULL) { showErrorAndExit("Failed to allocate %d bytes to patch save game", (int)((strlen((char *)originalBuffer) + 1) * sizeof(unsigned char))); } strcpy((char *)buffer, (char *)originalBuffer); line = strtok_r((char *)buffer, "\n", &savePtr); /* Load up the patch file */ saveMap = patchEntities(version, itemName); if (saveMap == FALSE) { snprintf(itemName, sizeof(itemName), "%ld_old", game.playTime * SDL_GetTicks()); } if (savedLocation == FALSE) { fprintf(newSave, "VERSION %0.2f\n", version); fprintf(newSave, "PLAY_TIME %ld\n", game.playTime); fprintf(newSave, "PLAYER_KILLS %d\n", game.kills); fprintf(newSave, "BATS_DROWNED %d\n", game.batsDrowned); fprintf(newSave, "TIMES_EATEN %d\n", game.timesEaten); fprintf(newSave, "DISTANCE_TRAVELLED %u\n", game.distanceTravelled); fprintf(newSave, "ATTACKS_BLOCKED %d\n", game.attacksBlocked); fprintf(newSave, "SLIME_TIME %d\n", game.timeSpentAsSlime); fprintf(newSave, "ARROWS_FIRED %d\n", game.arrowsFired); fprintf(newSave, "SECRETS_FOUND %d\n", game.secretsFound); fprintf(newSave, "CONTINUES %d\n", game.continues); fprintf(newSave, "CHEATING %d\n", game.cheating); fprintf(newSave, "PLAYER_LOCATION %s\n", location); savedLocation = TRUE; } fprintf(newSave, "MAP_NAME %s\n", itemName); if (strcmpignorecase(itemName, location) == 0) { fprintf(newSave, "PLAYER_DATA\n"); writePlayerToFile(newSave); fprintf(newSave, "PLAYER_INVENTORY\n"); writeInventoryToFile(newSave); } fprintf(newSave, "ENTITY_DATA\n"); /* Now write out all of the Entities */ writeEntitiesToFile(newSave); /* Now the targets */ writeTargetsToFile(newSave); /* And the triggers */ writeTriggersToFile(newSave); /* Add the global triggers */ writeGlobalTriggersToFile(newSave); /* Add the map triggers */ writeMapTriggersToFile(newSave); /* Add the objectives */ writeObjectivesToFile(newSave); freeLevelResources(); if (returnedName == NULL) { break; } } } line = strtok_r(NULL, "\n", &savePtr); } free(buffer); free(originalBuffer); fclose(newSave); #if DEV == 1 copyFile(tempFile, "tmpdata"); #endif copyFile(tempFile, saveFile); compressFile(saveFile); }
int loadGame(int slot) { char itemName[MAX_MESSAGE_LENGTH], mapName[MAX_MESSAGE_LENGTH], backup[MAX_PATH_LENGTH]; char saveFile[MAX_PATH_LENGTH], *line, *savePtr, completion[5]; double version = 0; float percentage, steps; unsigned char *buffer; int patchGame = FALSE, foundResources; FILE *fp; savePtr = NULL; snprintf(saveFile, sizeof(saveFile), "%ssave%d", gameSavePath, slot); fp = fopen(saveFile, "rb"); if (fp == NULL) { return FALSE; } fclose(fp); freeGameResources(); initGame(); buffer = decompressFile(saveFile); line = strtok_r((char *)buffer, "\n", &savePtr); foundResources = FALSE; while (line != NULL) { if (line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } if (line[strlen(line) - 1] == '\r') { line[strlen(line) - 1] = '\0'; } sscanf(line, "%s", itemName); if (strcmpignorecase("VERSION", itemName) == 0) { sscanf(line, "%*s %s\n", itemName); version = atof(itemName); if (version > VERSION) { printf("Save file version is newer than game version. This game might not work correctly.\n"); } } else if (strcmpignorecase("PLAY_TIME", itemName) == 0) { sscanf(line, "%*s %ld\n", &game.playTime); } else if (strcmpignorecase("PLAYER_KILLS", itemName) == 0) { sscanf(line, "%*s %d\n", &game.kills); } else if (strcmpignorecase("BATS_DROWNED", itemName) == 0) { sscanf(line, "%*s %d\n", &game.batsDrowned); } else if (strcmpignorecase("TIMES_EATEN", itemName) == 0) { sscanf(line, "%*s %d\n", &game.timesEaten); } else if (strcmpignorecase("DISTANCE_TRAVELLED", itemName) == 0) { sscanf(line, "%*s %u\n", &game.distanceTravelled); } else if (strcmpignorecase("ATTACKS_BLOCKED", itemName) == 0) { sscanf(line, "%*s %d\n", &game.attacksBlocked); } else if (strcmpignorecase("SLIME_TIME", itemName) == 0) { sscanf(line, "%*s %d\n", &game.timeSpentAsSlime); } else if (strcmpignorecase("ARROWS_FIRED", itemName) == 0) { sscanf(line, "%*s %d\n", &game.arrowsFired); } else if (strcmpignorecase("SECRETS_FOUND", itemName) == 0) { sscanf(line, "%*s %d\n", &game.secretsFound); } else if (strcmpignorecase("CONTINUES", itemName) == 0) { sscanf(line, "%*s %d\n", &game.continues); } else if (strcmpignorecase("CHEATING", itemName) == 0) { sscanf(line, "%*s %d\n", &game.cheating); } else if (strcmpignorecase("PLAYER_LOCATION", itemName) == 0) { if (version < VERSION) { patchGame = TRUE; break; } sscanf(line, "%*s %s\n", itemName); loadMap(itemName, FALSE); snprintf(mapName, sizeof(mapName), "MAP_NAME %s", itemName); } else if (strcmpignorecase(line, mapName) == 0) { foundResources = TRUE; loadResources(savePtr); } line = strtok_r(NULL, "\n", &savePtr); } if (patchGame == TRUE) { free(buffer); steps = (VERSION * 100) - (version * 100); steps = 100 / steps; percentage = 0; version += 0.01; /* Back up the original save file */ snprintf(backup, sizeof(backup), "%s.bak", saveFile); copyFile(saveFile, backup); showPatchMessage("0%"); while (TRUE) { getInput(IN_TITLE); patchSaveGame(saveFile, version); version += 0.01; percentage += steps; snprintf(completion, 5, "%d%%", (int)percentage); if ((int)(version * 100) > (int)(VERSION * 100)) { break; } showPatchMessage(completion); } return loadGame(slot); } /* Fudge to make a game saved in the new Village map still load OK */ if (foundResources == FALSE) { sscanf(mapName, "%*s %s\n", itemName); loadMap(itemName, TRUE); } free(buffer); copyFile(saveFile, tempFile); buffer = decompressFile(tempFile); free(buffer); cameraSnapToTargetEntity(); freeMessageQueue(); temporaryDataExists = TRUE; return TRUE; }
int loadContinueData() { char itemName[MAX_MESSAGE_LENGTH], mapName[MAX_MESSAGE_LENGTH]; char saveFile[MAX_PATH_LENGTH], *line, *savePtr; unsigned char *buffer; FILE *fp; savePtr = NULL; snprintf(saveFile, sizeof(saveFile), "%scontinuesave", gameSavePath); fp = fopen(saveFile, "rb"); if (fp == NULL) { return FALSE; } fclose(fp); freeGameResources(); initGame(); game.canContinue = TRUE; buffer = decompressFile(saveFile); if (strlen((char *)buffer) == 0) { showErrorAndExit("Something went wrong when decompressing the continue file"); } line = strtok_r((char *)buffer, "\n", &savePtr); while (line != NULL) { if (line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } if (line[strlen(line) - 1] == '\r') { line[strlen(line) - 1] = '\0'; } sscanf(line, "%s", itemName); if (strcmpignorecase("PLAY_TIME", itemName) == 0) { sscanf(line, "%*s %ld\n", &game.playTime); } else if (strcmpignorecase("PLAYER_KILLS", itemName) == 0) { sscanf(line, "%*s %d\n", &game.kills); } else if (strcmpignorecase("BATS_DROWNED", itemName) == 0) { sscanf(line, "%*s %d\n", &game.batsDrowned); } else if (strcmpignorecase("TIMES_EATEN", itemName) == 0) { sscanf(line, "%*s %d\n", &game.timesEaten); } else if (strcmpignorecase("DISTANCE_TRAVELLED", itemName) == 0) { sscanf(line, "%*s %u\n", &game.distanceTravelled); } else if (strcmpignorecase("ATTACKS_BLOCKED", itemName) == 0) { sscanf(line, "%*s %d\n", &game.attacksBlocked); } else if (strcmpignorecase("SLIME_TIME", itemName) == 0) { sscanf(line, "%*s %d\n", &game.timeSpentAsSlime); } else if (strcmpignorecase("ARROWS_FIRED", itemName) == 0) { sscanf(line, "%*s %d\n", &game.arrowsFired); } else if (strcmpignorecase("SECRETS_FOUND", itemName) == 0) { sscanf(line, "%*s %d\n", &game.secretsFound); } else if (strcmpignorecase("CONTINUES", itemName) == 0) { sscanf(line, "%*s %d\n", &game.continues); } else if (strcmpignorecase("CHEATING", itemName) == 0) { sscanf(line, "%*s %d\n", &game.cheating); } else if (strcmpignorecase("PLAYER_LOCATION", itemName) == 0) { sscanf(line, "%*s %s\n", itemName); loadMap(itemName, FALSE); snprintf(mapName, sizeof(mapName), "MAP_NAME %s", itemName); } else if (strcmpignorecase(line, mapName) == 0) { loadResources(savePtr); } line = strtok_r(NULL, "\n", &savePtr); } free(buffer); copyFile(saveFile, tempFile); buffer = decompressFile(tempFile); free(buffer); cameraSnapToTargetEntity(); freeMessageQueue(); return TRUE; }
int main(int argc, char *argv[]) { unsigned int frameLimit; int go, i, mapID, loadSlot, recordingID, replayingID; int joystick, showCredits, languageID; go = TRUE; loadSlot = -1; game.fps = 1000 / 60; languageID = mapID = recordingID = replayingID = -1; joystick = 0; showCredits = FALSE; /* Load the resources */ for (i=1;i<argc;i++) { if (strcmpignorecase("-record", argv[i]) == 0) { if (i + 1 >= argc) { printf("You must specify a file to record to\n"); printf("Type %s -h for help\n", argv[0]); exit(1); } if (recordingID == -1) { recordingID = i + 1; } i++; } else if (strcmpignorecase("-playback", argv[i]) == 0) { if (i + 1 >= argc) { printf("You must specify a file to playback from\n"); printf("Type %s -h for help\n", argv[0]); exit(1); } if (replayingID == -1) { replayingID = i + 1; } i++; } else if (strcmpignorecase("-load", argv[i]) == 0) { if (i + 1 >= argc) { printf("You must specify a slot to load from\n"); printf("Type %s -h for help\n", argv[0]); exit(1); } loadSlot = atoi(argv[i + 1]); i++; } else if (strcmpignorecase("-nojoystick", argv[i]) == 0) { game.disableJoystick = TRUE; } else if (strcmpignorecase("-joystick", argv[i]) == 0) { if (i + 1 >= argc) { printf("You must specify a joystick slot to use\n"); printf("Type %s -h for help\n", argv[0]); exit(1); } joystick = atoi(argv[i + 1]); i++; } else if (strcmpignorecase("-showcredits", argv[i]) == 0) { showCredits = TRUE; } else if (strstr(argv[i], "-lang") != NULL) { if (i + 1 >= argc) { printf("You must specify a language to use\n"); printf("Type %s -h for help\n", argv[0]); exit(1); } languageID = i + 1; i++; } else if (strstr(argv[i], "-h") != NULL || strstr(argv[i], "-help") != NULL) { printf("The Legend of Edgar options\n\n"); printf("\t-record <filename>: Captures keyboard input\n"); printf("\t-playback <filename>: Replays keyboard input\n"); printf("\t-load <save_slot>: Loads the game in slot <save_slot>. Slots start at 0\n"); printf("\t-nojoystick: Disables the joystick\n"); printf("\t-joystick <joystick_slot>: Use joystick <joystick_slot>. Slots start at 0\n"); printf("\t-showcredits: Shows the end credits\n"); printf("\t-language <language_code>: Use language <language_code>. e.g. en_US, es, pl\n\n"); exit(0); } #if DEV == 1 else if (strcmpignorecase("-saveonexit", argv[i]) == 0) { game.saveOnExit = TRUE; } else if (strcmpignorecase("-bmpwrite", argv[i]) == 0) { setScreenshotDir(argv[i + 1]); i++; } else { mapID = i; } #endif } setLanguage("edgar", languageID == -1 ? NULL : argv[languageID]); printf("Numeric is %s\n", setlocale(LC_NUMERIC, "C")); printf("atof(2.75) is %f\n", atof("2.75")); /* Call the cleanup function when the program exits */ atexit(cleanup); /* Start up SDL */ init(_("The Legend of Edgar"), joystick); loadRequiredResources(); if (replayingID != -1 && recordingID != -1) { showErrorAndExit("Cannot record and replay at the same time"); } #if DEV == 0 verifyVersion(); #endif /* Initialise the game variables */ freeGameResources(); initGame(); if (loadSlot == -1) { if (recordingID != -1) { setRecordData(argv[recordingID]); setMapFile(mapID == -1 ? "map01" : argv[mapID]); } else if (replayingID != -1) { setReplayData(argv[replayingID], TRUE); setMapFile(mapID == -1 ? "map01" : argv[mapID]); } if (mapID != -1) { startOnMap(argv[mapID]); } else if (game.firstRun == TRUE) { tutorial(); } else { game.status = IN_TITLE; } } else { if (recordingID != -1) { game.gameType = RECORDING; } else if (replayingID != -1) { game.gameType = REPLAYING; } if (loadGame(loadSlot) == FALSE) { showErrorAndExit("No saved game in slot %d", loadSlot); } if (recordingID != -1) { setRecordData(argv[recordingID]); setMapFile(getMapFilename()); } else if (replayingID != -1) { setReplayData(argv[replayingID], TRUE); } } /* Loop indefinitely for messages */ game.startTicks = SDL_GetTicks(); #if DEV == 1 printf("DEV Version\n"); #else printf("Production Version\n"); #endif frameLimit = SDL_GetTicks() + game.fps; if (showCredits == TRUE) { game.status = IN_CREDITS; } while (go == TRUE) { getInput(game.gameType); switch (game.status) { case IN_TITLE: doTitle(); break; case IN_GAME: freeCollisionGrid(); clearDrawLayers(); doGame(); doPlayer(); doInventory(); doMap(); doEntities(); doDecorations(); doCollisions(); doHud(); doDialogBox(); processMedals(); break; case IN_INVENTORY: doInventoryMenu(); break; case IN_MENU: doMenu(); break; case IN_CREDITS: freeCollisionGrid(); clearDrawLayers(); doGame(); doCredits(); doDecorations(); doCollisions(); break; default: doMenu(); break; } draw(); /* Sleep briefly to stop sucking up all the CPU time */ delay(frameLimit); frameLimit = SDL_GetTicks() + game.fps; game.frames++; } /* Exit the program */ exit(0); }