Ticket #8624: dialog_save_memory.patch
File dialog_save_memory.patch, 9.5 KB (added by , 15 years ago) |
---|
-
engines/scumm/input.cpp
410 410 // Fall back to default behavior 411 411 ScummEngine::processKeyboard(lastKeyHit); 412 412 413 // On Alt-F5 prepare savegame for the original save/load dialog. 414 if (lastKeyHit.keycode == Common::KEYCODE_F5 && lastKeyHit.flags == Common::KBD_ALT) { 415 prepareSavegame(); 416 } 417 413 418 if (VAR_KEYPRESS != 0xFF && _mouseAndKeyboardStat) { // Key Input 414 419 if (315 <= _mouseAndKeyboardStat && _mouseAndKeyboardStat <= 323) { 415 420 // Convert F-Keys for V1/V2 games (they start at 1) … … 424 429 // Fall back to default behavior 425 430 ScummEngine::processKeyboard(lastKeyHit); 426 431 427 // 'i' brings up an IQ dialog in Indy3 428 if (lastKeyHit.ascii == 'i' && _game.id == GID_INDY3) { 432 // On Alt-F5 prepare savegame for the original save/load dialog. 433 if (lastKeyHit.keycode == Common::KEYCODE_F5 && lastKeyHit.flags == Common::KBD_ALT) { 434 prepareSavegame(); 435 } 436 437 // 'i' brings up an IQ dialog in Indy3 (disabled in save/load dialog for input) 438 if (lastKeyHit.ascii == 'i' && _game.id == GID_INDY3 && _currentRoom != 14) { 429 439 // SCUMM var 244 is the episode score 430 440 // and var 245 is the series score 431 441 char text[50]; -
engines/scumm/saveload.cpp
28 28 #include "common/config-manager.h" 29 29 #include "common/savefile.h" 30 30 #include "common/system.h" 31 #include "common/zlib.h" 31 32 32 33 #include "scumm/actor.h" 33 34 #include "scumm/charset.h" … … 129 130 return true; 130 131 } 131 132 133 bool ScummEngine::saveState(Common::OutSaveFile *out, bool writeHeader) { 134 SaveGameHeader hdr; 135 136 if (writeHeader) { 137 memcpy(hdr.name, _saveLoadName, sizeof(hdr.name)); 138 saveSaveGameHeader(out, hdr); 139 } 140 #if !defined(__DS__) 141 Graphics::saveThumbnail(*out); 142 #endif 143 saveInfos(out); 144 145 Serializer ser(0, out, CURRENT_VER); 146 saveOrLoad(&ser); 147 return true; 148 } 149 132 150 bool ScummEngine::saveState(int slot, bool compat) { 151 bool saveFailed; 133 152 Common::String filename; 134 153 Common::OutSaveFile *out; 135 SaveGameHeader hdr;136 154 137 155 if (_saveLoadSlot == 255) { 138 156 // Allow custom filenames for save game system in HE Games … … 143 161 if (!(out = _saveFileMan->openForSaving(filename.c_str()))) 144 162 return false; 145 163 146 memcpy(hdr.name, _saveLoadName, sizeof(hdr.name)); 147 saveSaveGameHeader(out, hdr); 148 #if !defined(__DS__) 149 Graphics::saveThumbnail(*out); 150 #endif 151 saveInfos(out); 164 saveFailed = false; 165 if (!saveState(out)) 166 saveFailed = true; 152 167 153 Serializer ser(0, out, CURRENT_VER);154 saveOrLoad(&ser);155 168 out->finalize(); 156 if (out->err()) { 157 delete out; 169 if (out->err()) 170 saveFailed = true; 171 delete out; 172 173 if (saveFailed) { 158 174 debug(1, "State save as '%s' FAILED", filename.c_str()); 159 175 return false; 160 176 } 161 delete out;162 177 debug(1, "State saved as '%s'", filename.c_str()); 163 178 return true; 164 179 } 165 180 181 182 void ScummEngine::prepareSavegame() { 183 Common::MemoryWriteStreamDynamic *memStream; 184 Common::WriteStream *writeStream; 185 186 // free memory of the last prepared savegame 187 delete _savePreparedSavegame; 188 _savePreparedSavegame = NULL; 189 190 // store headerless savegame in a compressed memory stream 191 memStream = new Common::MemoryWriteStreamDynamic(); 192 writeStream = Common::wrapCompressedWriteStream(memStream); 193 if (saveState(writeStream, false)) { 194 // we have to finalize the compression-stream first, otherwise the internal 195 // memory-stream pointer will be zero (Important: flush() does not work here!). 196 writeStream->finalize(); 197 if (!writeStream->err()) { 198 // wrap uncompressing MemoryReadStream around the savegame data 199 _savePreparedSavegame = Common::wrapCompressedReadStream( 200 new Common::MemoryReadStream(memStream->getData(), memStream->size(), true)); 201 } 202 } 203 // free the CompressedWriteStream and MemoryWriteStreamDynamic 204 // but not the memory stream's internal buffer 205 delete writeStream; 206 } 207 208 bool ScummEngine::savePreparedSavegame(int slot, char *desc) { 209 bool success; 210 Common::String filename; 211 Common::OutSaveFile *out; 212 SaveGameHeader hdr; 213 uint32 nread, nwritten; 214 byte buffer[1024]; 215 216 out = 0; 217 success = true; 218 219 // check if savegame was successfully stored in memory 220 if (!_savePreparedSavegame) 221 success = false; 222 223 // open savegame file 224 if (success) { 225 filename = makeSavegameName(slot, false); 226 if (!(out = _saveFileMan->openForSaving(filename.c_str()))) { 227 success = false; 228 } 229 } 230 231 // write header to file 232 if (success) { 233 memset(hdr.name, 0, sizeof(hdr.name)); 234 strncpy(hdr.name, desc, sizeof(hdr.name)-1); 235 success = saveSaveGameHeader(out, hdr); 236 } 237 238 // copy savegame from memory-stream to file 239 if (success) { 240 _savePreparedSavegame->seek(0, SEEK_SET); 241 while (nread = _savePreparedSavegame->read(buffer, sizeof(buffer))) { 242 nwritten = out->write(buffer, nread); 243 if (nwritten < nread) { 244 success = false; 245 break; 246 } 247 } 248 } 249 250 if (out) { 251 out->finalize(); 252 if (out->err()) 253 success = false; 254 delete out; 255 } 256 257 if (!success) { 258 debug(1, "State save as '%s' FAILED", filename.c_str()); 259 return false; 260 } else { 261 debug(1, "State saved as '%s'", filename.c_str()); 262 return true; 263 } 264 } 265 166 266 static bool loadSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &hdr) { 167 267 hdr.type = in->readUint32BE(); 168 268 hdr.size = in->readUint32LE(); -
engines/scumm/script_v5.cpp
869 869 // which matches the original Indy3 save/load code. See also the notes 870 870 // on Feature Request #1666521. 871 871 STRINGID_IQ_EPISODE = 7, 872 STRINGID_IQ_SERIES = 9 872 STRINGID_IQ_SERIES = 9, 873 // The string IDs of the first savegame name, used as an offset to determine 874 // the IDs of all savenames. 875 // Loom is the only game whose savenames start with a different ID. 876 STRINGID_SAVENAME1 = 10, 877 STRINGID_SAVENAME1_LOOM = 9 873 878 }; 874 879 875 880 void ScummEngine_v5::o5_saveLoadVars() { … … 1235 1240 result = 100; 1236 1241 break; 1237 1242 case 0x20: // drive 1238 if (_game.id == GID_INDY3) { 1239 // 0 = hard drive 1240 // 1 = disk drive 1241 result = 0; 1243 if (_game.version <= 3) { 1244 // 0 = ??? 1245 // [1,2] = disk drive [A:,B:] 1246 // 3 = hard drive 1247 result = 3; 1242 1248 } else { 1243 1249 // set current drive 1244 1250 result = 1; 1245 1251 } 1246 1252 break; 1247 1253 case 0x40: // load 1248 if (loadState(slot, _saveTemporaryState))1254 if (loadState(slot, false)) 1249 1255 result = 3; // sucess 1250 1256 else 1251 1257 result = 5; // failed to load 1252 1258 break; 1253 1259 case 0x80: // save 1254 //if (saveState(slot, _saveTemporaryState)) 1255 // result = 0; // sucess 1256 //else 1260 if (_game.version <= 3) { 1261 char name[32]; 1262 if (_game.version <= 2) { 1263 // use generic name 1264 sprintf(name, "Game %c", 'A'+slot-1); 1265 } else { 1266 // use name entered by the user 1267 char* ptr; 1268 int firstSlot = (_game.id == GID_LOOM) ? STRINGID_SAVENAME1_LOOM : STRINGID_SAVENAME1; 1269 ptr = (char*)getStringAddress(slot + firstSlot - 1); 1270 strncpy(name, ptr, sizeof(name)); 1271 } 1272 1273 if(savePreparedSavegame(slot, name)) 1274 result = 0; 1275 else 1276 result = 2; 1277 } else { 1257 1278 result = 2; // failed to save 1279 } 1258 1280 break; 1259 1281 case 0xC0: // test if save exists 1260 1282 { -
engines/scumm/scumm.cpp
198 198 _saveLoadSlot = 0; 199 199 _lastSaveTime = 0; 200 200 _saveTemporaryState = false; 201 _savePreparedSavegame = NULL; 201 202 memset(_saveLoadFileName, 0, sizeof(_saveLoadFileName)); 202 203 memset(_saveLoadName, 0, sizeof(_saveLoadName)); 203 204 memset(_localScriptOffsets, 0, sizeof(_localScriptOffsets)); … … 569 570 delete _costumeLoader; 570 571 delete _costumeRenderer; 571 572 573 delete _savePreparedSavegame; 574 572 575 _textSurface.free(); 573 576 574 577 free(_shadowPalette); … … 1416 1419 _keyDownMap[i] = false; 1417 1420 1418 1421 _lastSaveTime = _system->getMillis(); 1422 1423 delete _savePreparedSavegame; 1424 _savePreparedSavegame = NULL; 1419 1425 } 1420 1426 1421 1427 void ScummEngine_v0::resetScumm() { -
engines/scumm/scumm.h
29 29 #include "engines/engine.h" 30 30 #include "common/endian.h" 31 31 #include "common/file.h" 32 #include "common/savefile.h" 32 33 #include "common/keyboard.h" 33 34 #include "common/rect.h" 34 35 #include "common/str.h" … … 626 627 char _saveLoadFileName[32]; 627 628 char _saveLoadName[32]; 628 629 630 // Prepared savegame used by the orginal save/load dialog. 631 // Must be valid as long as the savescreen is active. As we are not 632 // notified when the savescreen is closed, memory is only freed on a game 633 // reset, at the destruction of the engine or when the original save/load dialog 634 // is entered the next time. 635 Common::SeekableReadStream* _savePreparedSavegame; 636 637 bool saveState(Common::OutSaveFile *out, bool writeHeader = true); 629 638 bool saveState(int slot, bool compat); 630 639 bool loadState(int slot, bool compat); 631 640 virtual void saveOrLoad(Serializer *s); … … 633 642 void saveResource(Serializer *ser, int type, int index); 634 643 void loadResource(Serializer *ser, int type, int index); 635 644 645 void prepareSavegame(); 646 bool savePreparedSavegame(int slot, char *desc); 647 636 648 Common::String makeSavegameName(int slot, bool temporary) const { 637 649 return makeSavegameName(_targetName, slot, temporary); 638 650 }