English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. General (https://eab.abime.net/forumdisplay.php?f=37)
-   -   How do Game Saves work? (https://eab.abime.net/showthread.php?t=70859)

diablothe2nd 21 September 2013 14:24

How do Game Saves work?
 
my question is not specific to blitz basic but any more direct help with this in terms of Blitz would be a great help.

for things like floppy based games like monkey island etc that require a blank formatted disk to save on, how would this work?

does the game need to call a routine or something to be able to access the disk/hd? does the system need to pause or is there such a thing as disk access on the fly?

and how would said save be written, i guess you'd have tags like level number, lives, collectibles, and some for of quest tracker. they are usually bundled into an obscure filetype, and i guess some are obfuscated to prevent cheating?

Codetapper 21 September 2013 14:35

I don't know much about Blitz but in general, you switch the operating system back on, write the file to disk, and wait 2 seconds so the disk won't end up corrupt, then return to the game.

As for the save game, it depends on the game but what you said is pretty close. Some games you'd get away with very simple save states like you said, but if you need to restore the exact state you'd have to save every object and it's data at that point in time.

NovaCoder 21 September 2013 14:48

Wolfenstein 3D just dumps all the objects to disk as binary in a single file, then reading it back is just the opposite.

This kind of thing:

Code:

int SaveTheGame(char *fn, char *tag, int x, int y)
{
        int fd;
        int i;
        objtype *ob, nullobj;
        long checksum;


        fd = OpenWrite(fn);

        if (fd == -1) {
                Message(STR_NOSPACE1"\n"
                        STR_NOSPACE2);

                IN_ClearKeysDown();
                IN_Ack();

                return -1;
        }

        // write savegame header
        WriteBytes(fd, (byte *)GAMEHDR, 8);
        WriteBytes(fd, (byte *)SAVTYPE, 4);
        WriteInt32(fd, 0xFFFFFFFF); // write version
        WriteBytes(fd, (byte *)GAMETYPE, 4);
        WriteInt32(fd, time(NULL));
        WriteInt32(fd, 0x00000000);
        WriteInt32(fd, 0x00000000);
        WriteBytes(fd, (byte *)tag, 32); // write savegame name

        checksum = 0;

        DiskFlopAnim(x,y);

        //WriteBytes(fd, (byte *)&gamestate, sizeof(gamestate));
    WriteInt32(fd, gamestate.difficulty);
    WriteInt32(fd, gamestate.mapon);
    WriteInt32(fd, gamestate.oldscore);
    WriteInt32(fd, gamestate.score);
    WriteInt32(fd, gamestate.nextextra);
    WriteInt32(fd, gamestate.lives);
    WriteInt32(fd, gamestate.health);
    WriteInt32(fd, gamestate.ammo);
    WriteInt32(fd, gamestate.keys);
    WriteInt32(fd, gamestate.bestweapon);
    WriteInt32(fd, gamestate.weapon);
    WriteInt32(fd, gamestate.chosenweapon);
    WriteInt32(fd, gamestate.faceframe);
    WriteInt32(fd, gamestate.attackframe);
    WriteInt32(fd, gamestate.attackcount);
    WriteInt32(fd, gamestate.weaponframe);
    WriteInt32(fd, gamestate.episode);
    WriteInt32(fd, gamestate.secretcount);
    WriteInt32(fd, gamestate.treasurecount);
    WriteInt32(fd, gamestate.killcount);
    WriteInt32(fd, gamestate.secrettotal);
    WriteInt32(fd, gamestate.treasuretotal);
    WriteInt32(fd, gamestate.killtotal);
    WriteInt32(fd, gamestate.TimeCount);
    WriteInt32(fd, gamestate.killx);
    WriteInt32(fd, gamestate.killy);
    WriteInt8(fd, gamestate.victoryflag);
        checksum = DoChecksum((byte*)&gamestate, sizeof(gamestate), checksum);

        DiskFlopAnim(x,y);

#ifdef SPEAR
        for (i = 0; i < 20; i++)
#else
        for (i = 0; i < 8; i++)
#endif
        {
                //WriteBytes(fd, (byte *)&LevelRatios[i], sizeof(LRstruct));
        WriteInt32(fd, LevelRatios[i].kill);
        WriteInt32(fd, LevelRatios[i].secret);
        WriteInt32(fd, LevelRatios[i].treasure);
        WriteInt32(fd, LevelRatios[i].time);
        checksum = DoChecksum((byte*)&LevelRatios[i], sizeof(LRstruct), checksum);
        }


Code:

int LoadTheGame(char *fn, int x, int y)
{
        int fd;
        int i;
        long checksum, oldchecksum;
        objtype nullobj;

        fd = OpenRead(fn);
        if (fd == -1)
                goto openfail;

        ReadSeek(fd, 64, SEEK_SET);

        checksum = 0;

        DiskFlopAnim(x,y);


        //ReadBytes(fd, (byte *)&gamestate, sizeof(gamestate));
        gamestate.difficulty        = ReadInt32(fd);
        gamestate.mapon                = ReadInt32(fd);
        gamestate.oldscore        = ReadInt32(fd);
        gamestate.score                = ReadInt32(fd);
        gamestate.nextextra        = ReadInt32(fd);
        gamestate.lives                = ReadInt32(fd);
        gamestate.health        = ReadInt32(fd);
        gamestate.ammo                = ReadInt32(fd);
        gamestate.keys                = ReadInt32(fd);
        gamestate.bestweapon        = ReadInt32(fd);
        gamestate.weapon        = ReadInt32(fd);
        gamestate.chosenweapon        = ReadInt32(fd);
        gamestate.faceframe        = ReadInt32(fd);
        gamestate.attackframe        = ReadInt32(fd);
        gamestate.attackcount        = ReadInt32(fd);
        gamestate.weaponframe        = ReadInt32(fd);
        gamestate.episode        = ReadInt32(fd);
        gamestate.secretcount        = ReadInt32(fd);
        gamestate.treasurecount        = ReadInt32(fd);
        gamestate.killcount        = ReadInt32(fd);
        gamestate.secrettotal        = ReadInt32(fd);
        gamestate.treasuretotal = ReadInt32(fd);
        gamestate.killtotal        = ReadInt32(fd);
        gamestate.TimeCount        = ReadInt32(fd);
        gamestate.killx                = ReadInt32(fd);
        gamestate.killy                = ReadInt32(fd);
        gamestate.victoryflag        = ReadInt8(fd);
    checksum = DoChecksum((byte*)&gamestate,sizeof(gamestate),checksum);

        DiskFlopAnim(x,y);

#ifdef SPEAR
        for (i = 0; i < 20; i++)
#else
        for (i = 0; i < 8; i++)
#endif
        {
                //ReadBytes(fd, (byte *)&LevelRatios[i], sizeof(LRstruct));
                LevelRatios[i].kill        = ReadInt32(fd);
                LevelRatios[i].secret        = ReadInt32(fd);
                LevelRatios[i].treasure        = ReadInt32(fd);
                LevelRatios[i].time        = ReadInt32(fd);
        checksum = DoChecksum((byte*)&LevelRatios[i], sizeof(LRstruct), checksum);
        }


diablothe2nd 21 September 2013 14:55

nice one, cheers novacoder :great


All times are GMT +2. The time now is 03:58.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.05524 seconds with 11 queries