void saveGame(int slot) { char itemName[MAX_MESSAGE_LENGTH], *line, *savePtr; char saveFile[MAX_PATH_LENGTH]; char *mapName = getMapFilename(); char tempSaveFile[MAX_PATH_LENGTH]; int i; unsigned char *buffer; int skipping = FALSE; FILE *read; FILE *write; savePtr = NULL; if (slot == -1) { for (i=1001;;i++) { snprintf(saveFile, sizeof(saveFile), "%ssave%d", gameSavePath, i); read = fopen(saveFile, "rb"); if (read == NULL) { break; } else { fclose(read); } } } else { /* Backup older save */ snprintf(saveFile, sizeof(saveFile), "%ssave%d", gameSavePath, slot); snprintf(tempSaveFile, sizeof(tempSaveFile), "%stempsave%d", gameSavePath, slot); } write = fopen(tempSaveFile, "wb"); fprintf(write, "VERSION %0.2f\n", VERSION); fprintf(write, "PLAY_TIME %ld\n", game.playTime); fprintf(write, "PLAYER_KILLS %d\n", game.kills); fprintf(write, "BATS_DROWNED %d\n", game.batsDrowned); fprintf(write, "TIMES_EATEN %d\n", game.timesEaten); fprintf(write, "DISTANCE_TRAVELLED %u\n", game.distanceTravelled); fprintf(write, "ATTACKS_BLOCKED %d\n", game.attacksBlocked); fprintf(write, "SLIME_TIME %d\n", game.timeSpentAsSlime); fprintf(write, "ARROWS_FIRED %d\n", game.arrowsFired); fprintf(write, "SECRETS_FOUND %d\n", game.secretsFound); fprintf(write, "CONTINUES %d\n", game.continues); fprintf(write, "CHEATING %d\n", game.cheating); fprintf(write, "PLAYER_LOCATION %s\n", mapName); read = fopen(tempFile, "rb"); if (read == NULL) { if (temporaryDataExists == TRUE) { showErrorAndExit("SAVE GAME: Could not find persistance file: %s", strerror(errno)); } } else { fclose(read); buffer = decompressFile(tempFile); 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'; } if (skipping == FALSE) { sscanf(line, "%s", itemName); if (strcmpignorecase("PLAYER_DATA", itemName) == 0 || strcmpignorecase("PLAYER_INVENTORY", itemName) == 0 || strcmpignorecase("PLAYER_LOCATION", itemName) == 0 || strcmpignorecase("VERSION", itemName) == 0) { skipping = TRUE; } else if (strcmpignorecase("MAP_NAME", itemName) == 0) { sscanf(line, "%*s %s\n", itemName); if (strcmpignorecase(itemName, mapName) == 0) { skipping = TRUE; } else { fprintf(write, "%s\n", line); } } else { fprintf(write, "%s\n", line); } } else { sscanf(line, "%s", itemName); if (strcmpignorecase("MAP_NAME", itemName) == 0) { sscanf(line, "%*s %s\n", itemName); if (strcmpignorecase(itemName, mapName) != 0) { skipping = FALSE; fprintf(write, "%s\n", line); } } } line = strtok_r(NULL, "\n", &savePtr); } free(buffer); } /* Save the player's position */ fprintf(write, "MAP_NAME %s\n", mapName); fprintf(write, "PLAYER_DATA\n"); writePlayerToFile(write); fprintf(write, "INVENTORY_INDEX %d\n", getInventoryIndex()); fprintf(write, "PLAYER_INVENTORY\n"); writeInventoryToFile(write); fprintf(write, "ENTITY_DATA\n"); /* Now write out all of the Entities */ writeEntitiesToFile(write); /* Now the targets */ writeTargetsToFile(write); /* And the triggers */ writeTriggersToFile(write); /* Add the global triggers */ writeGlobalTriggersToFile(write); /* Add the map triggers */ writeMapTriggersToFile(write); /* Add the objectives */ writeObjectivesToFile(write); /* Save the player data */ fclose(write); #if DEV == 1 copyFile(tempSaveFile, "savedata"); #endif compressFile(tempSaveFile); copyFile(tempSaveFile, saveFile); remove(tempSaveFile); updateSaveFileIndex(slot); }
void saveTemporaryData() { char *line, itemName[MAX_MESSAGE_LENGTH], *savePtr; char swapFile[MAX_PATH_LENGTH]; char *mapName = getMapFilename(); unsigned char *buffer; int skipping = FALSE; FILE *read; FILE *write; savePtr = NULL; snprintf(swapFile, sizeof(swapFile), "%sswap", gameSavePath); read = fopen(tempFile, "rb"); write = fopen(swapFile, "wb"); if (read == NULL) { if (temporaryDataExists == TRUE) { showErrorAndExit("SAVE TEMP DATA: Could not find persistance file: %s", strerror(errno)); } } else { fclose(read); buffer = decompressFile(tempFile); if (strlen((char *)buffer) == 0) { showErrorAndExit("Something went wrong when decompressing the persistance 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'; } if (skipping == FALSE) { sscanf(line, "%s", itemName); if (strcmpignorecase("PLAYER_DATA", line) == 0 || strcmpignorecase("PLAYER_INVENTORY", line) == 0 || strcmpignorecase("GLOBAL_TRIGGER", line) == 0 || strcmpignorecase("OBJECTIVE", line) == 0 || strcmpignorecase("PLAYER_LOCATION", line) == 0 || strcmpignorecase("MAP_TRIGGER", line) == 0) { skipping = TRUE; } else if (strcmpignorecase("MAP_NAME", itemName) == 0) { sscanf(line, "%*s %s\n", itemName); if (strcmpignorecase(itemName, mapName) == 0) { skipping = TRUE; } else { fprintf(write, "%s\n", line); } } else { fprintf(write, "%s\n", line); } } else { sscanf(line, "%s", itemName); if (strcmpignorecase("MAP_NAME", itemName) == 0) { sscanf(line, "%*s %s\n", itemName); if (strcmpignorecase(itemName, mapName) != 0) { skipping = FALSE; fprintf(write, "%s\n", line); } } } line = strtok_r(NULL, "\n", &savePtr); } free(buffer); if (remove(tempFile) != 0) { showErrorAndExit("Could not remove temporary file"); } } fprintf(write, "MAP_NAME %s\n", mapName); fprintf(write, "ENTITY_DATA\n"); /* Now write out all of the Entities */ writeEntitiesToFile(write); /* Now the targets */ writeTargetsToFile(write); /* And the triggers */ writeTriggersToFile(write); fclose(write); if (rename(swapFile, tempFile) != 0) { showErrorAndExit("Could not rename temporary file"); } #if DEV == 1 copyFile(tempFile, "tmpdata"); #endif compressFile(tempFile); temporaryDataExists = 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); }