VOGONS

Common searches


Save States - Proof of concept

Topic actions

Reply 80 of 227, by jal

User metadata
Rank Oldbie
Rank
Oldbie
Manwe wrote:

Thanks for your answer, JAL, but I already read the thread

Not well enough, e.g. on page 3 there's mentioning of saving to disk, to which I replied:

jal wrote:

As I understand it, ZenJu is perfectly capable of writing the states to disk, but since he does not save the entire state of DOSBox (especially hardware, whose state is usually rather static while a game is running, but definitely not while, say, another game is), saving to disk would not allow restoring the game again (at least not without first starting the game again).

That should've answered your question, right?

JAL

Reply 81 of 227, by ykhwong

User metadata
Rank Oldbie
Rank
Oldbie

This can save state to disk, specifically to directory /save/1 to 10. It simply works only in current DOSBox instance though. Still experimental.

In save_state.cpp

#include <fstream>

void SaveState::save(size_t slot) { //throw (Error)
if (slot >= SLOT_COUNT) return;

try {
for (CompEntry::iterator i = components.begin(); i != components.end(); ++i) {
std::ostringstream ss;
i->second.comp.getBytes(ss);
i->second.rawBytes[slot].set(ss.str());
char temp[20] = "./save/";
int realslot = slot+1;
char realslot_str[20];
itoa(realslot,realslot_str,10);
strcat(temp,realslot_str);
strcat(temp,"/");
strcat(temp,i->first.c_str());
std::ofstream outfile (temp, std::ofstream::binary);
outfile << ss.str();
//compress all other saved states except position "slot"
const std::vector<RawBytes>& rb = i->second.rawBytes;
std::for_each(rb.begin(), rb.begin() + slot, std::mem_fun_ref(&RawBytes::compress));
std::for_each(rb.begin() + slot + 1, rb.end(), std::mem_fun_ref(&RawBytes::compress));
outfile.close();
}
}
catch (const std::bad_alloc&)
{
throw Error("Save failed! Out of Memory!");
}
}


void SaveState::load(size_t slot) const { //throw (Error)
// if (isEmpty(slot)) return;
for (CompEntry::const_iterator i = components.begin(); i != components.end(); ++i) {
std::filebuf * fb;
std::ifstream ss;
std::ifstream check_file;
fb = ss.rdbuf();
char temp[20] = "./save/";
int realslot = slot+1;
char realslot_str[20];
itoa(realslot,realslot_str,10);
strcat(temp,realslot_str);
strcat(temp,"/");
strcat(temp,i->first.c_str());

check_file.open(temp, std::ifstream::in);
check_file.close();
if(check_file.fail()) throw Error("No saved file for this slot. Aborted.");

fb->open(temp,std::ios::in | std::ios::binary);
i->second.comp.setBytes(ss);
if (fb->in_avail() != 0 || ss.eof()) { //basic consistency check
throw Error("Save state corrupted! Program in inconsistent state!") + " - " + i->first;
}
//compress all other saved states except position "slot"
const std::vector<RawBytes>& rb = i->second.rawBytes;
std::for_each(rb.begin(), rb.begin() + slot, std::mem_fun_ref(&RawBytes::compress));
Show last 4 lines
        std::for_each(rb.begin() + slot + 1, rb.end(), std::mem_fun_ref(&RawBytes::compress));
fb->close();
}
}

Reply 83 of 227, by ykhwong

User metadata
Rank Oldbie
Rank
Oldbie
Neville wrote:

Interesting... are you adding this patch to your unofficial version of DOSBox?

Yes, you can find save directory in my current release.

Several files are genereated in the location and their names explain what they mean. I can make it a single saved file by flushing buffer when saving but loading states procedure will become more complex.

Reply 84 of 227, by Xelasarg

User metadata
Rank Member
Rank
Member

Nice one, ykhwong!

This works surprisingly well. Maybe it'll never be stable enough to be integrated into an official release, but it's a fine addition to your experimental builds.

"What's a paladin?!"

Reply 85 of 227, by ykhwong

User metadata
Rank Oldbie
Rank
Oldbie

Tiny updates for saving to disk. All credits go to ZenJu.
- States can be saved to or loaded from disk.
- Added a verification code to check if states are properly saved to disk.
- Creates a save directory if it does not exist.
- Saves a name of program running in DOSBox.
- Does not save CPU paging part and does not register POD of memory function as they disturb loading states in another instance.

Saved state files are reusable even after DOSBox exits.

Special key review:
Left ALT + F5 -> Save state / Left ALT + F9 -> Load state
Left Alt + F6 -> Previous slot / Left ALT + F7 -> Next slot

Attachments

  • Filename
    savestates_disk.diff
    File size
    49.89 KiB
    Downloads
    439 downloads
    File license
    Fair use/fair dealing exception

Reply 86 of 227, by Bisqwit

User metadata
Rank Newbie
Rank
Newbie

For reference, here is a link to the savestate patch that I created a few years back. Savestates and movie support (patch included)

My savestates could be saved on the disk, and loaded from there, even across dosbox close & open, and it had movie recording support, but movies tended to desync if loaded in a computer with different speed specifications.
It addressed the re-entrancy problem by disabling save&load function while re-entrant (during DOS input wait INT 21h for example), and it addressed the file I/O consistency by implementing an emulation layer over the I/O which virtualizes the whole I/O layer, preserving a delta over the state where files where when dosbox was started (no actual files are thus modified). I don't remember how I solved the dilemma with callback function pointers.

Just providing it here to allow possibly some insight that might help develop this currently studied candidate further.

x6425081281317.png

Reply 87 of 227, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

At around that time i committed several changes to avoid machine recursions, but the
main ones remain (paging and shells, the latter being the more relevant since it can block
saving and loading completely).

There are some bits and pieces that i wasn't too happy about back then, like having some
layers over existing code rather than some more integrated solution, but that may or may
not be relevant.

Reply 89 of 227, by ripa

User metadata
Rank Oldbie
Rank
Oldbie

Do you have SDL_net.dll in the same directory as dosbox.exe? It should work just fine if you install regular dosbox, then put the new exe into the directory. You can rename the exe so you can have vanilla dosbox and save-state dosbox installed in the same directory.

Reply 91 of 227, by jez

User metadata
Rank Member
Rank
Member

Any updates on whether something like this might make it into the main build anytime soon? There are some games with dodgy save/load mechanisms that can cause corruption; a solid DOSBox save state mechanism would be awesome as a save/load replacement for these games (yeah yeah, the quality of some DOS programmers' code sucked...)

== Jez ==

Reply 92 of 227, by Geektastic

User metadata
Rank Newbie
Rank
Newbie

ask wd. Really though, no probably not anytime soon. ZenJu was only here for about a month, and his last post was almost two years ago. He may have gotten dismayed that wd didn't want save states in the mainline code (at that time). Kind of like Bisqwit's position, in that he was quite motivated to code this at one time, but that post above was his last post here, too. Still, ZenJu's implementation is certainly usable for most games and goes beyond a "proof of concept"! If you require save-to-disk saved states, wkhwong patched the code for this, linked above. So I guess I should ask: What software did you try that didn't work with beta9? If you haven't tried, please do. Do not assume because it's "old" it doesn't work anymore - it does.

Reply 93 of 227, by tikalat

User metadata
Rank Member
Rank
Member

Thank you for the experimental save states code.

I think they are really practical for me (even if a temporary solution at this stage).

I'm (very slowly) going through some of the ykhwong save state version. To make it a little more useful for what I play.

This one adds palette states. Example is (sometimes) loading up states from the Gobliiins series (random incorrect colors).

Patch seems to fix this up atm.

ykhwong svn-daum 2012-02-20


gui/render.cpp

(add to end of file)
#include "../save_state.h"

//save state support
namespace
{
class SerializeRender : public SerializeGlobalPOD
{
public:
SerializeRender() : SerializeGlobalPOD("Render")
{
registerPOD(render.pal);
}
} dummy;
}

Attachments

  • Filename
    gui_render_palette_savestate.diff
    File size
    307 Bytes
    Downloads
    192 downloads
    File comment
    ykhwong svn-daum (2012-02-20)
    File license
    Fair use/fair dealing exception

Reply 94 of 227, by tikalat

User metadata
Rank Member
Rank
Member

Another small improvement. This time for mouse cursor.

Sometimes Lemmings 2 can act goofy with the mouse, allowing restricted cursor movement on loadstate.

This will resize the 'mouse window' on savestate.

ykhwong svn-daum 2012-02-20

(ints/mouse.cpp)

(add to end of file)
#include "../save_state.h"


//save state support
namespace
{
class SerializeMouse : public SerializeGlobalPOD
{
public:
SerializeMouse() : SerializeGlobalPOD("Mouse")
{
registerPOD(mouse.min_x);
registerPOD(mouse.min_y);
registerPOD(mouse.max_x);
registerPOD(mouse.max_y);
registerPOD(mouse.clipx);
registerPOD(mouse.clipy);
}
} dummy;
}

Attachments

  • Filename
    ints_mouse_savestate.diff
    File size
    487 Bytes
    Downloads
    198 downloads
    File comment
    ykhwong svn-daum 2012-02-20
    File license
    Fair use/fair dealing exception

Reply 96 of 227, by Dominus

User metadata
Rank DOSBox Moderator
Rank
DOSBox Moderator

Isn't tikalat giving enough examples?;)

Windows 3.1x guide for DOSBox
60 seconds guide to DOSBox
DOSBox SVN snapshot for macOS (10.4-11.x ppc/intel 32/64bit) notarized for gatekeeper

Reply 97 of 227, by Jorpho

User metadata
Rank l33t++
Rank
l33t++

Tikalat is giving examples of games that have problems with the DOSBox savestate code. I understood Jez as referring to games whose own internal code has problems loading and saving games using their own mechanisms.

Reply 98 of 227, by Dominus

User metadata
Rank DOSBox Moderator
Rank
DOSBox Moderator

Sorry, you are right 😉
I can't name any now but I know I wished for a savestate feature in a couple of games.
But I can't think of one where the savegames were prone to corruption.

Windows 3.1x guide for DOSBox
60 seconds guide to DOSBox
DOSBox SVN snapshot for macOS (10.4-11.x ppc/intel 32/64bit) notarized for gatekeeper