/* Copyright (C) 2006 Parallel Realities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "save.h" void showSaveGameProgess(char *progress, bool autoSaving) { graphics->setMode(MODE_2D); if (!autoSaving) { graphics->drawRect(0, (graphics->screen->h / 2) - 10, graphics->screen->w, 34, GLColor::black, false); graphics->drawRect(0, (graphics->screen->h / 2) - 10, graphics->screen->w, 1, GLColor::white, false); graphics->drawRect(0, (graphics->screen->h / 2) + 24, graphics->screen->w, 1, GLColor::white, false); graphics->drawString(graphics->screenMidX, graphics->screenMidY, TXT_CENTERED, GLColor::white, true, "%s", progress); graphics->delay(1, false); } else { graphics->showLoadingProgress("Saving Game State..."); } } void removeSaveFromList(int slotId) { String saveSaveName; saveSaveName.setText("%s/"SAVE_FORMAT, engine->userHomeDirectory.getText(), slotId); debug(("removeSaveFromList() - Removing save game '%s'\n", saveSaveName.getText())); remove(saveSaveName.getText()); saveSaveName.setText(""SAVE_FORMAT, slotId); engine->saveSlot[slotId].inUse = false; engine->saveSlot[slotId].description = "Empty"; engine->saveSaveGameHeaders(); } void createSaveHeader(int slotId) { debug(("createSaveHeader - %d\n", slotId)); char timeBuffer[40]; char dateBuffer[40]; time_t ltime; time(<ime); tm *today = localtime(<ime); strftime(timeBuffer, 40, "%H:%M %Z", today); strftime(dateBuffer, 40, "%d/%m/%Y", today); engine->saveSlot[slotId].inUse = true; engine->saveSlot[slotId].time = timeBuffer; engine->saveSlot[slotId].date = dateBuffer; engine->saveSlot[slotId].mapName = game->mission.getText(); engine->saveSlot[slotId].description = mission->missionName.getText(); engine->saveSaveGameHeaders(); } void compressSaveGameData(char *inputFilename) { uLongf cSize = 0; uLongf fSize = 0; Bytef *buffer; Bytef *output; FILE *infile = fopen(inputFilename, "rb"); fseek(infile, SEEK_SET, SEEK_END); long size = ftell(infile); fclose(infile); size = (uLongf)(size * 1.1); buffer = new Bytef[size]; output = new Bytef[size]; gzFile fp = gzopen(inputFilename, "rb"); fSize = gzread(fp, buffer, size); gzclose(fp); cSize = (uLongf)((fSize * 1.01) + 12); compress2(output, &cSize, buffer, fSize, 9); String outputFilename; outputFilename.setText("%s/"SAVE_FORMAT, engine->userHomeDirectory.getText(), game->saveSlot); debug(("Attempting to compress save game %s to %s\n", inputFilename, outputFilename.getText())); FILE *outfile = fopen(outputFilename.getText(), "wb"); fwrite(output, 1, cSize, outfile); fwrite(&cSize, 1, sizeof(uLongf), outfile); fwrite(&fSize, 1, sizeof(uLongf), outfile); fclose(outfile); #if !DEV remove(inputFilename); #endif debug(("Compressed save from %d to %d\n", (int)fSize, (int)cSize)); delete buffer; delete output; } void saveGameData(bool autoSaving) { if ((game->saveSlot == -1) && (autoSaving)) { return; } engine->startDebugTimer("saveGameData()"); createSaveHeader(game->saveSlot); String filename; filename.setText("%s/blobWarsSaveTempFile", engine->userHomeDirectory.getText()); debug(("Attempting to save game to %s\n", filename.getText())); FILE *fp = fopen(filename.getText(), "wb"); if (!fp) { graphics->showErrorAndExit("Couldn't save game"); } showSaveGameProgess("Saving Game - Please Wait...", autoSaving); if (!game->changingLevel) { graphics->delay(500, false); } showSaveGameProgess("Saving Game - Please Wait... 10%%", autoSaving); fprintf(fp, "// ############### Custom Item Data ############\n\n"); entityManager->saveCustomItems(fp); fprintf(fp, "// ############### Game Data ############\n\n"); game->save(fp); showSaveGameProgess("Saving Game - Please Wait... 25%%", autoSaving); fprintf(fp, "// ############### Mission Data ############\n\n"); mission->save(fp); showSaveGameProgess("Saving Game - Please Wait... 50%%", autoSaving); fprintf(fp, "// ############### All Entity Data ############\n\n"); entityManager->save(fp); showSaveGameProgess("Saving Game - Please Wait... 75%%", autoSaving); fprintf(fp, "// ############### Particle Data ############\n\n"); particleManager->save(fp); showSaveGameProgess("Saving Game - Please Wait... 85%%", autoSaving); fprintf(fp, "@END@\n"); fclose(fp); showSaveGameProgess("Saving Game - Please Wait... 95%%", autoSaving); compressSaveGameData(filename.getText()); debug(("Successfully saved game to %s (slot %d)\n", filename.getText(), game->saveSlot)); showSaveGameProgess("Saving Game - Done", autoSaving); engine->endDebugTimer("saveGameData()"); if (!game->changingLevel) { graphics->delay(500, false); } } void saveRestartData() { if (game->saveSlot == -1) { return; } String filename; filename.setText("%s/"SAVE_FORMAT, engine->userHomeDirectory.getText(), game->saveSlot); engine->loadData(filename.getText()); filename.setText("%s/"SAVE_FORMAT"-restart", engine->userHomeDirectory.getText(), game->saveSlot); FILE *fp = fopen(filename.getText(), "wb"); if (fp == NULL) { printf("WARNING: Couldn't create restart file '%s'\n", filename.getText()); return; } fwrite(engine->dataBuffer, 1, engine->lastReadDataSize, fp); fclose(fp); } bool saveGame() { int saveSlot = doLoadSaveGameDialog("Save"); // don't bother! They pressed cancel! if (saveSlot == -1) { return false; } game->saveSlot = saveSlot; uiManager->onlyShowGroup("@none@"); saveGameData(false); engine->resetTimeDifference(); return true; }