diff options
author | Matthew Hoops | 2011-12-12 15:25:28 -0500 |
---|---|---|
committer | Matthew Hoops | 2011-12-12 15:25:28 -0500 |
commit | 00279659b22cbd5db739d5351e83a9fc2a2ae408 (patch) | |
tree | 497f06f46820043cbdf1725652b8f0073223e24a /engines/dreamweb/saveload.cpp | |
parent | d932df79bed5aac97e17c0920a5e75cb5ce733ee (diff) | |
parent | d1628feb761acc9f4607f64de3eb620fea53bcc9 (diff) | |
download | scummvm-rg350-00279659b22cbd5db739d5351e83a9fc2a2ae408.tar.gz scummvm-rg350-00279659b22cbd5db739d5351e83a9fc2a2ae408.tar.bz2 scummvm-rg350-00279659b22cbd5db739d5351e83a9fc2a2ae408.zip |
Merge remote branch 'upstream/master' into pegasus
Conflicts:
video/qt_decoder.cpp
Diffstat (limited to 'engines/dreamweb/saveload.cpp')
-rw-r--r-- | engines/dreamweb/saveload.cpp | 589 |
1 files changed, 386 insertions, 203 deletions
diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp index 636182dc83..f0fd477ec1 100644 --- a/engines/dreamweb/saveload.cpp +++ b/engines/dreamweb/saveload.cpp @@ -28,54 +28,53 @@ namespace DreamGen { -void DreamGenContext::loadgame() { - STACK_CHECK; +// Temporary storage for loading the room from a savegame +Room g_madeUpRoomDat; + +void DreamGenContext::loadGame() { if (data.byte(kCommandtype) != 246) { data.byte(kCommandtype) = 246; - al = 41; - commandonly(); + commandOnly(41); } if (data.word(kMousebutton) == data.word(kOldbutton)) return; // "noload" - if (data.word(kMousebutton) == 1) { - ax = 0xFFFF; - doload(); - } + if (data.word(kMousebutton) == 1) + doLoad(-1); } -// input: ax = savegameId // if -1, open menu to ask for slot to load // if >= 0, directly load from that slot -void DreamGenContext::doload() { - STACK_CHECK; - int savegameId = (int16)ax; - +void DreamGenContext::doLoad(int savegameId) { data.byte(kLoadingorsave) = 1; if (ConfMan.getBool("dreamweb_originalsaveload") && savegameId == -1) { - showopbox(); - showloadops(); + showOpBox(); + showLoadOps(); data.byte(kCurrentslot) = 0; - showslots(); - shownames(); + showSlots(); + showNames(); data.byte(kPointerframe) = 0; - worktoscreenm(); - namestoold(); + workToScreenM(); + namesToOld(); data.byte(kGetback) = 0; - while (true) { - if (data.byte(kQuitrequested)) - return; // "quitloaded" - delpointer(); - readmouse(); - showpointer(); - vsync(); - dumppointer(); - dumptextline(); - bx = offset_loadlist; - checkcoords(); - if (data.byte(kGetback) == 1) - break; + while (data.byte(kGetback) == 0) { + if (quitRequested()) + return; + delPointer(); + readMouse(); + showPointer(); + vSync(); + dumpPointer(); + dumpTextLine(); + RectWithCallback loadlist[] = { + { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getBackToOps }, + { kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamGenContext::actualLoad }, + { kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamGenContext::selectSlot }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkCoords(loadlist); if (data.byte(kGetback) == 2) return; // "quitloaded" } @@ -98,83 +97,35 @@ void DreamGenContext::doload() { return; } + loadPosition(savegameId); - // TODO: proper scheme for filename, in a separate function - //Common::String filename = ConfMan.getActiveDomainName() + Common::String::format(".d%02d", savegameId); - Common::String filename = Common::String::format("DREAMWEB.D%02d", savegameId); - debug(1, "Loading from filename: %s", filename.c_str()); - engine->openSaveFileForReading(filename); - - // TODO: The below is duplicated from Loadposition - data.word(kTimecount) = 0; - clearchanges(); - - ds = cs; - dx = kFileheader; - cx = kHeaderlen; - savefileread(); - es = cs; - di = kFiledata; - ax = savegameId; - if (savegameId < 7) { - cx = 17; - _mul(cx); - ds = data; - dx = kSavenames; - _add(dx, ax); - loadseg(); - } else { - // For potential support of more than 7 savegame slots, - // loading into the savenames buffer isn't always possible - // Emulate a loadseg call: - uint8 namebuf[17]; - engine->readFromFile(namebuf, 17); - _add(di, 2); - } - ds = data; - dx = kStartvars; - loadseg(); - ds = data.word(kExtras); - dx = kExframedata; - loadseg(); - ds = data.word(kBuffers); - dx = kListofchanges; - loadseg(); - ds = data; - dx = kMadeuproomdat; - loadseg(); - ds = cs; - dx = kReelroutines; - loadseg(); - closefile(); data.byte(kGetback) = 1; } + // If we reach this point, loadPosition() has just been called. + // Among other things, it will have filled g_MadeUpRoomDat. + // kTempgraphics might not have been allocated if we bypassed all menus if (data.word(kTempgraphics) != 0xFFFF) - getridoftemp(); + getRidOfTemp(); - dx = data; - es = dx; - bx = kMadeuproomdat; - startloading(); - loadroomssample(); + startLoading(g_madeUpRoomDat); + loadRoomsSample(); data.byte(kRoomloaded) = 1; data.byte(kNewlocation) = 255; - clearsprites(); - initman(); - initrain(); + clearSprites(); + initMan(); + initRain(); data.word(kTextaddressx) = 13; data.word(kTextaddressy) = 182; data.byte(kTextlen) = 240; startup(); - worktoscreen(); + workToScreenCPP(); data.byte(kGetback) = 4; } -void DreamGenContext::savegame() { - STACK_CHECK; +void DreamGenContext::saveGame() { if (data.byte(kMandead) == 2) { blank(); return; @@ -182,8 +133,7 @@ void DreamGenContext::savegame() { if (data.byte(kCommandtype) != 247) { data.byte(kCommandtype) = 247; - al = 44; - commandonly(); + commandOnly(44); } if (data.word(kMousebutton) != 1) return; @@ -191,34 +141,36 @@ void DreamGenContext::savegame() { data.byte(kLoadingorsave) = 2; if (ConfMan.getBool("dreamweb_originalsaveload")) { - showopbox(); - showsaveops(); + showOpBox(); + showSaveOps(); data.byte(kCurrentslot) = 0; - showslots(); - shownames(); - worktoscreenm(); - namestoold(); + showSlots(); + showNames(); + workToScreenM(); + namesToOld(); data.word(kBufferin) = 0; data.word(kBufferout) = 0; data.byte(kGetback) = 0; - while (true) { - _cmp(data.byte(kQuitrequested), 0); - if (!flags.z()) - return /* (quitsavegame) */; - delpointer(); - checkinput(); - readmouse(); - showpointer(); - vsync(); - dumppointer(); - dumptextline(); - bx = offset_savelist; - checkcoords(); - _cmp(data.byte(kGetback), 0); - if (flags.z()) - continue; - break; + while (data.byte(kGetback) == 0) { + if (quitRequested()) + return; + delPointer(); + checkInput(); + readMouse(); + showPointer(); + vSync(); + dumpPointer(); + dumpTextLine(); + + RectWithCallback savelist[] = { + { kOpsx+176,kOpsx+192,kOpsy+60,kOpsy+76,&DreamGenContext::getBackToOps }, + { kOpsx+128,kOpsx+190,kOpsy+12,kOpsy+100,&DreamGenContext::actualSave }, + { kOpsx+2,kOpsx+92,kOpsy+4,kOpsy+81,&DreamGenContext::selectSlot }, + { 0,320,0,200,&DreamGenContext::blank }, + { 0xFFFF,0,0,0,0 } + }; + checkCoords(savelist); } return; } else { @@ -238,54 +190,7 @@ void DreamGenContext::savegame() { return; } - // TODO: The below is copied from actualsave - al = data.byte(kLocation); - ah = 0; - cx = 32; - _mul(cx); - ds = cs; - si = kRoomdata; - _add(si, ax); - di = kMadeuproomdat; - bx = di; - es = cs; - cx = 16; - _movsw(cx, true); - al = data.byte(kRoomssample); - es.byte(bx+13) = al; - al = data.byte(kMapx); - es.byte(bx+15) = al; - al = data.byte(kMapy); - es.byte(bx+16) = al; - al = data.byte(kLiftflag); - es.byte(bx+20) = al; - al = data.byte(kManspath); - es.byte(bx+21) = al; - al = data.byte(kFacing); - es.byte(bx+22) = al; - al = 255; - es.byte(bx+27) = al; - - // TODO: The below is copied from saveposition - makeheader(); - - //Common::String filename = ConfMan.getActiveDomainName() + Common::String::format(".d%02d", savegameId); - Common::String filename = Common::String::format("DREAMWEB.D%02d", savegameId); - debug(1, "Saving to filename: %s (%s)", filename.c_str(), game_description.c_str()); - - engine->openSaveFileForWriting(filename.c_str()); - - dx = data; - ds = dx; - dx = kFileheader; - cx = kHeaderlen; - savefilewrite(); - dx = data; - es = dx; - di = kFiledata; - - // TODO: Check if this 2 is a constant - uint8 descbuf[17] = { 2, 0 }; + char descbuf[17] = { 2, 0 }; strncpy((char*)descbuf+1, game_description.c_str(), 16); unsigned int desclen = game_description.size(); if (desclen > 15) @@ -294,50 +199,328 @@ void DreamGenContext::savegame() { descbuf[++desclen] = 0; while (desclen < 17) descbuf[++desclen] = 1; - if (savegameId < 7) { - ax = savegameId; - cx = 17; - _mul(cx); - ds = data; - dx = kSavenames; - _add(dx, ax); - memcpy(data.ptr(dx,17), descbuf, 17); - saveseg(); - } else { - // savenames only has room for descriptions for 7 slots - uint16 len = es.word(di); - _add(di, 2); - assert(len == 17); - engine->writeToSaveFile(descbuf, len); - } + if (savegameId < 7) + memcpy(&_saveNames[17*savegameId], descbuf, 17); - ds = data; - dx = kStartvars; - saveseg(); - ds = data.word(kExtras); - dx = kExframedata; - saveseg(); - ds = data.word(kBuffers); - dx = kListofchanges; - saveseg(); - ds = data; - dx = kMadeuproomdat; - saveseg(); - ds = data; - dx = kReelroutines; - saveseg(); - closefile(); - - getridoftemp(); - restoreall(); + savePosition(savegameId, descbuf); + + // TODO: The below is copied from actualsave + getRidOfTemp(); + restoreAll(); // reels data.word(kTextaddressx) = 13; data.word(kTextaddressy) = 182; data.byte(kTextlen) = 240; - redrawmainscrn(); - worktoscreenm(); + redrawMainScrn(); + workToScreenM(); data.byte(kGetback) = 4; } } +void DreamGenContext::namesToOld() { + memcpy(_saveNamesOld, _saveNames, 17*7); +} + +void DreamGenContext::oldToNames() { + memcpy(_saveNames, _saveNamesOld, 17*7); +} + +void DreamGenContext::saveLoad() { + if (data.word(kWatchingtime) || (data.byte(kPointermode) == 2)) { + blank(); + return; + } + if (data.byte(kCommandtype) != 253) { + data.byte(kCommandtype) = 253; + commandOnly(43); + } + if ((data.word(kMousebutton) != data.word(kOldbutton)) && (data.word(kMousebutton) & 1)) + doSaveLoad(); +} + +void DreamGenContext::showMainOps() { + showFrame(tempGraphics(), kOpsx+10, kOpsy+10, 8, 0); + showFrame(tempGraphics(), kOpsx+59, kOpsy+30, 7, 0); + showFrame(tempGraphics(), kOpsx+128+4, kOpsy+12, 1, 0); +} + +void DreamGenContext::showDiscOps() { + showFrame(tempGraphics(), kOpsx+128+4, kOpsy+12, 1, 0); + showFrame(tempGraphics(), kOpsx+10, kOpsy+10, 9, 0); + showFrame(tempGraphics(), kOpsx+59, kOpsy+30, 10, 0); + showFrame(tempGraphics(), kOpsx+176+2, kOpsy+60-4, 5, 0); +} + +void DreamGenContext::actualSave() { + if (data.byte(kCommandtype) != 222) { + data.byte(kCommandtype) = 222; + commandOnly(44); + } + + if (!(data.word(kMousebutton) & 1)) + return; + + unsigned int slot = data.byte(kCurrentslot); + + const char *desc = &_saveNames[17*slot]; + if (desc[1] == 0) // The actual description string starts at desc[1] + return; + + savePosition(slot, desc); + + getRidOfTemp(); + restoreAll(); // reels + data.word(kTextaddressx) = 13; + data.word(kTextaddressy) = 182; + data.byte(kTextlen) = 240; + redrawMainScrn(); + workToScreenM(); + data.byte(kGetback) = 4; +} + +void DreamGenContext::actualLoad() { + if (data.byte(kCommandtype) != 221) { + data.byte(kCommandtype) = 221; + commandOnly(41); + } + + if (data.word(kMousebutton) == data.word(kOldbutton) || data.word(kMousebutton) != 1) + return; + + unsigned int slot = data.byte(kCurrentslot); + + const char *desc = &_saveNames[17*slot]; + if (desc[1] == 0) // The actual description string starts at desc[1] + return; + + loadPosition(data.byte(kCurrentslot)); + data.byte(kGetback) = 1; +} + +void DreamGenContext::savePosition(unsigned int slot, const char *descbuf) { + + const Room ¤tRoom = g_roomData[data.byte(kLocation)]; + + Room madeUpRoom = currentRoom; + madeUpRoom.roomsSample = data.byte(kRoomssample); + madeUpRoom.mapX = data.byte(kMapx); + madeUpRoom.mapY = data.byte(kMapy); + madeUpRoom.liftFlag = data.byte(kLiftflag); + madeUpRoom.b21 = data.byte(kManspath); + madeUpRoom.facing = data.byte(kFacing); + madeUpRoom.b27 = 255; + + + engine->processEvents(); // TODO: Is this necessary? + + Common::String filename = engine->getSavegameFilename(slot); + debug(1, "savePosition: slot %d filename %s", slot, filename.c_str()); + Common::OutSaveFile *outSaveFile = engine->getSaveFileManager()->openForSaving(filename); + if (!outSaveFile) // TODO: Do proper error handling! + error("save could not be opened for writing"); + + // Initialize new header + FileHeader header; + + // Note: _desc is not zero-terminated + const char *desc = "DREAMWEB DATA FILE COPYRIGHT 1992 CREATIVE REALITY"; + assert(strlen(desc) == sizeof(header._desc)); + memcpy(header._desc, desc, sizeof(header._desc)); + memset(&header._len[0], 0, sizeof(header._len)); + memset(&header._padding[0], 0, sizeof(header._padding)); + + // fill length fields in savegame file header + uint16 len[6] = { 17, kLengthofvars, kLengthofextra, + 4*kNumchanges, 48, kLenofreelrouts }; + for (int i = 0; i < 6; ++i) + header.setLen(i, len[i]); + + outSaveFile->write((const uint8 *)&header, sizeof(FileHeader)); + outSaveFile->write(descbuf, len[0]); + outSaveFile->write(data.ptr(kStartvars, len[1]), len[1]); + outSaveFile->write(getSegment(data.word(kExtras)).ptr(kExframedata, len[2]), len[2]); + outSaveFile->write(getSegment(data.word(kBuffers)).ptr(kListofchanges, len[3]), len[3]); + + // len[4] == 48, which is sizeof(Room) plus 16 for 'Roomscango' + outSaveFile->write((const uint8 *)&madeUpRoom, sizeof(Room)); + outSaveFile->write(data.ptr(kRoomscango, 16), 16); + + outSaveFile->write(data.ptr(kReelroutines, len[5]), len[5]); + + outSaveFile->finalize(); + if (outSaveFile->err()) { + // TODO: Do proper error handling + warning("an error occurred while writing the savegame"); + } + + delete outSaveFile; +} + +void DreamGenContext::loadPosition(unsigned int slot) { + data.word(kTimecount) = 0; + clearChanges(); + + Common::String filename = engine->getSavegameFilename(slot); + debug(1, "loadPosition: slot %d filename %s", slot, filename.c_str()); + Common::InSaveFile *inSaveFile = engine->getSaveFileManager()->openForLoading(filename); + if (!inSaveFile) // TODO: Do proper error handling! + error("save could not be opened for reading"); + + FileHeader header; + + inSaveFile->read((uint8 *)&header, sizeof(FileHeader)); + + // read segment lengths from savegame file header + int len[6]; + for (int i = 0; i < 6; ++i) + len[i] = header.len(i); + if (len[0] != 17) + ::error("Error loading save: description buffer isn't 17 bytes"); + + if (slot < 7) { + inSaveFile->read(&_saveNames[17*slot], len[0]); + } else { + // The savenames buffer only has room for 7 descriptions + uint8 namebuf[17]; + inSaveFile->read(namebuf, 17); + } + inSaveFile->read(data.ptr(kStartvars, len[1]), len[1]); + inSaveFile->read(getSegment(data.word(kExtras)).ptr(kExframedata, len[2]), len[2]); + inSaveFile->read(getSegment(data.word(kBuffers)).ptr(kListofchanges, len[3]), len[3]); + + // len[4] == 48, which is sizeof(Room) plus 16 for 'Roomscango' + // Note: the values read into g_madeUpRoomDat are only used in actualLoad, + // which is (almost) immediately called after this function + inSaveFile->read((uint8 *)&g_madeUpRoomDat, sizeof(Room)); + inSaveFile->read(data.ptr(kRoomscango, 16), 16); + + inSaveFile->read(data.ptr(kReelroutines, len[5]), len[5]); + + delete inSaveFile; +} + +// Count number of save files, and load their descriptions into _saveNames +unsigned int DreamGenContext::scanForNames() { + unsigned int count = 0; + + FileHeader header; + + // TODO: Change this to use SaveFileManager::listSavefiles() + for (unsigned int slot = 0; slot < 7; ++slot) { + _saveNames[17*slot+0] = 2; + _saveNames[17*slot+1] = 0; + for (int i = 2; i < 17; ++i) + _saveNames[17*slot+i] = 1; + + // Try opening savegame with the given slot id + Common::String filename = engine->getSavegameFilename(slot); + Common::InSaveFile *inSaveFile = engine->getSaveFileManager()->openForLoading(filename); + if (!inSaveFile) + continue; + + ++count; + + inSaveFile->read((uint8 *)&header, sizeof(FileHeader)); + + if (header.len(0) != 17) { + ::warning("Error loading save: description buffer isn't 17 bytes"); + delete inSaveFile; + continue; + } + + // NB: Only possible if slot < 7 + inSaveFile->read(&_saveNames[17*slot], 17); + + delete inSaveFile; + } + + al = (uint8)count; + + return count; +} + +void DreamGenContext::loadOld() { + if (data.byte(kCommandtype) != 252) { + data.byte(kCommandtype) = 252; + commandOnly(48); + } + + if (!(data.word(kMousebutton) & 1)) + return; + + doLoad(-1); + + if (data.byte(kGetback) == 4 || quitRequested()) + return; + + showDecisions(); + workToScreenM(); + data.byte(kGetback) = 0; +} + +void DreamGenContext::loadSaveBox() { + loadIntoTemp("DREAMWEB.G08"); +} + +// show savegame names (original interface), and set kCursorpos +void DreamBase::showNames() { + for (int slot = 0; slot < 7; ++slot) { + // The first character of the savegame name is unused + Common::String name(&_saveNames[17*slot + 1]); + + if (slot != data.byte(kCurrentslot)) { + printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false); + continue; + } + if (data.byte(kLoadingorsave) != 2) { + data.word(kCharshift) = 91; + printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false); + data.word(kCharshift) = 0; + continue; + } + + int pos = name.size(); + data.byte(kCursorpos) = pos; + name += '/'; // cursor character + printDirect((const uint8 *)name.c_str(), kOpsx + 21, kOpsy + 10*slot + 10, 200, false); + } +} + +void DreamGenContext::checkInput() { + if (data.byte(kLoadingorsave) == 3) + return; + + readKey(); + + // The first character of the savegame name is unused + char *name = &_saveNames[17*data.byte(kCurrentslot) + 1]; + + if (data.byte(kCurrentkey) == 0) { + return; + } else if (data.byte(kCurrentkey) == 13) { + data.byte(kLoadingorsave) = 3; + } else if (data.byte(kCurrentkey) == 8) { + if (data.byte(kCursorpos) == 0) + return; + + --data.byte(kCursorpos); + name[data.byte(kCursorpos)] = 0; + name[data.byte(kCursorpos)+1] = 1; + } else { + if (data.byte(kCursorpos) == 14) + return; + + name[data.byte(kCursorpos)] = data.byte(kCurrentkey); + name[data.byte(kCursorpos)+1] = 0; + name[data.byte(kCursorpos)+2] = 1; + ++data.byte(kCursorpos); + } + + showOpBox(); + showNames(); + showSlots(); + showSaveOps(); + workToScreenM(); +} + -} /*namespace dreamgen */ +} // End of namespace DreamGen |