Ticket #8596: AgiSaveGame-09jan2007.patch

File AgiSaveGame-09jan2007.patch, 31.8 KB (added by spookypeanut, 17 years ago)

Patch against revision 25058

  • engines/agi/agi.cpp

     
    531531        Common::addSpecialDebugLevel(kDebugLevelScripts, "Scripts", "Scripts debugging");
    532532        Common::addSpecialDebugLevel(kDebugLevelSound, "Sound", "Sound debugging");
    533533        Common::addSpecialDebugLevel(kDebugLevelText, "Text", "Text output debugging");
     534        Common::addSpecialDebugLevel(kDebugLevelSavegame, "Savegame", "Saving & restoring game debugging");
    534535
    535536
    536537        memset(&game, 0, sizeof(struct agi_game));
     
    587588        _sound = new SoundMgr(this, _mixer);
    588589        _picture = new PictureMgr(this, _gfx);
    589590        _sprites = new SpritesMgr(this, _gfx);
    590         _saveGameMgr = new SaveGameMgr(this, _sprites, _gfx, _sound, _picture);
    591591
    592592        _gfx->initMachine();
    593593
  • engines/agi/op_cmd.cpp

     
    448448}
    449449
    450450cmd(save_game) {
    451         game.simple_save ? g_agi->_saveGameMgr->savegame_simple() : g_agi->_saveGameMgr->savegame_dialog();
     451        game.simple_save ? g_agi->saveGameSimple() : g_agi->saveGameDialog();
    452452}
    453453
    454454cmd(load_game) {
    455455        assert(1);
    456         game.simple_save ? g_agi->_saveGameMgr->loadgame_simple() : g_agi->_saveGameMgr->loadgame_dialog();
     456        game.simple_save ? g_agi->loadGameSimple() : g_agi->loadGameDialog();
    457457}
    458458
    459459cmd(init_disk) {                                /* do nothing */
  • engines/agi/savegame.cpp

     
    3838#include "agi/keyboard.h"
    3939#include "agi/menu.h"
    4040
    41 namespace Agi {
     41#define SAVEGAME_VERSION 2
    4242
    43 static const char *strSig = "AGI:";
    44 
    45 void SaveGameMgr::write_string(Common::File *f, const char *s) {
    46         f->writeSint16BE((int16)strlen(s));
    47         f->write(s, strlen(s));
    48 }
    49 
    50 void SaveGameMgr::read_string(Common::File *f, char *s) {
    51         int16 size = f->readSint16BE();
    52         f->read(s, size);
    53         s[size] = (char)0;
    54 }
    55 
    56 void SaveGameMgr::write_bytes(Common::File *f, const char *s, int16 size) {
    57         f->write(s, size);
    58 }
    59 
    60 void SaveGameMgr::read_bytes(Common::File *f, char *s, int16 size) {
    61         f->read(s, size);
    62 }
    63 
    6443/*
    65  * Version 0: view table has 64 entries
    66  * Version 1: view table has 256 entries (needed in KQ3)
     44 * Version 0 (Sarien): view table has 64 entries
     45 * Version 1 (Sarien): view table has 256 entries (needed in KQ3)
     46 * Version 2 (ScummVM): first ScummVM version
    6747 */
    68 #define SAVEGAME_VERSION 1
    6948
    70 int SaveGameMgr::save_game(char *s, const char *d) {
    71         int16 i;
    72         struct image_stack_element *ptr = _vm->image_stack;
    73         Common::File f;
     49namespace Agi {
    7450
    75         // FIXME: Do *not* use Common::File to access savegames, it is not portable!
    76         f.open(s, Common::File::kFileWriteMode);
     51static const uint32 AGIflag=MKID_BE('AGI:');
    7752
    78         if (!f.isOpen())
     53int AgiEngine::saveGame(const char *fileName, const char *description) {
     54        char gameIDstring[8]="gameIDX";
     55        int i;
     56        struct image_stack_element *ptr = image_stack;
     57        Common::OutSaveFile *out;
     58
     59        debugC(3, kDebugLevelMain | kDebugLevelSavegame, "AgiEngine::saveGame(%s, %s)", fileName, description);
     60        if (!(out = _saveFileMan->openForSaving(fileName))) {
     61                warning("Can't create file '%s', game not saved", fileName);
    7962                return err_BadFileOpen;
     63        } else {
     64                debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for writing", fileName);
     65        }
    8066
    81         write_bytes(&f, strSig, 8);
    82         write_string(&f, d);
     67        out->writeUint32BE(AGIflag);
     68        out->write(description, 31);
    8369
    84         f.writeByte((uint8)SAVEGAME_VERSION);
    85         f.writeByte((uint8)_vm->game.state);
    86         /* game.name */
    87         write_string(&f, _vm->game.id);
    88         /* game.crc */
     70        out->writeByte(SAVEGAME_VERSION);
     71        debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing save game version (%d)", SAVEGAME_VERSION);
    8972
     73        out->writeByte(game.state);
     74        debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing game state (%d)", game.state);
     75       
     76        strcpy(gameIDstring, game.id);
     77        out->write(gameIDstring, 8);
     78        debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing game id (%s, %s)", gameIDstring, game.id);
     79
    9080        for (i = 0; i < MAX_FLAGS; i++)
    91                 f.writeByte(_vm->game.flags[i]);
     81                out->writeByte(game.flags[i]);
    9282        for (i = 0; i < MAX_VARS; i++)
    93                 f.writeByte(_vm->game.vars[i]);
     83                out->writeByte(game.vars[i]);
    9484
    95         f.writeSint16BE((int8)_vm->game.horizon);
    96         f.writeSint16BE((int16)_vm->game.line_status);
    97         f.writeSint16BE((int16)_vm->game.line_user_input);
    98         f.writeSint16BE((int16)_vm->game.line_min_print);
    99         /* game.cursor_pos */
    100         /* game.input_buffer */
    101         /* game.echo_buffer */
    102         /* game.keypress */
    103         f.writeSint16BE((int16)_vm->game.input_mode);
    104         f.writeSint16BE((int16)_vm->game.lognum);
     85        out->writeSint16BE((int8)game.horizon);
     86        out->writeSint16BE((int16)game.line_status);
     87        out->writeSint16BE((int16)game.line_user_input);
     88        out->writeSint16BE((int16)game.line_min_print);
    10589
    106         f.writeSint16BE((int16)_vm->game.player_control);
    107         f.writeSint16BE((int16)_vm->game.quit_prog_now);
    108         f.writeSint16BE((int16)_vm->game.status_line);
    109         f.writeSint16BE((int16)_vm->game.clock_enabled);
    110         f.writeSint16BE((int16)_vm->game.exit_all_logics);
    111         f.writeSint16BE((int16)_vm->game.picture_shown);
    112         f.writeSint16BE((int16)_vm->game.has_prompt);
    113         f.writeSint16BE((int16)_vm->game.game_flags);
     90        out->writeSint16BE((int16)game.input_mode);
     91        out->writeSint16BE((int16)game.lognum);
    11492
    115         /* Reversed to keep compatibility with old savegames */
    116         f.writeSint16BE((int16)!_vm->game.input_enabled);
     93        out->writeSint16BE((int16)game.player_control);
     94        out->writeSint16BE((int16)game.quit_prog_now);
     95        out->writeSint16BE((int16)game.status_line);
     96        out->writeSint16BE((int16)game.clock_enabled);
     97        out->writeSint16BE((int16)game.exit_all_logics);
     98        out->writeSint16BE((int16)game.picture_shown);
     99        out->writeSint16BE((int16)game.has_prompt);
     100        out->writeSint16BE((int16)game.game_flags);
    117101
     102        out->writeSint16BE((int16)game.input_enabled);
     103
    118104        for (i = 0; i < _HEIGHT; i++)
    119                 f.writeByte(_vm->game.pri_table[i]);
     105                out->writeByte(game.pri_table[i]);
     106       
     107        out->writeSint16BE((int16)game.gfx_mode);
     108        out->writeByte(game.cursor_char);
     109        out->writeSint16BE((int16)game.color_fg);
     110        out->writeSint16BE((int16)game.color_bg);
    120111
    121         /* game.msg_box_ticks */
    122         /* game.block */
    123         /* game.window */
    124         /* game.has_window */
    125 
    126         f.writeSint16BE((int16)_vm->game.gfx_mode);
    127         f.writeByte(_vm->game.cursor_char);
    128         f.writeSint16BE((int16)_vm->game.color_fg);
    129         f.writeSint16BE((int16)_vm->game.color_bg);
    130 
    131112        /* game.hires */
    132113        /* game.sbuf */
    133114        /* game.ego_words */
    134115        /* game.num_ego_words */
    135116
    136         f.writeSint16BE((int16)_vm->game.num_objects);
    137         for (i = 0; i < (int16)_vm->game.num_objects; i++)
    138                 f.writeSint16BE((int16)_vm->object_get_location(i));
     117        out->writeSint16BE((int16)game.num_objects);
     118        for (i = 0; i < (int16)game.num_objects; i++)
     119                out->writeSint16BE((int16)object_get_location(i));
    139120
    140121        /* game.ev_keyp */
    141122        for (i = 0; i < MAX_STRINGS; i++)
    142                 write_string(&f, _vm->game.strings[i]);
     123                out->write(game.strings[i], MAX_STRINGLEN);
    143124
    144125        /* record info about loaded resources */
    145126        for (i = 0; i < MAX_DIRS; i++) {
    146                 f.writeByte(_vm->game.dir_logic[i].flags);
    147                 f.writeSint16BE((int16)_vm->game.logics[i].sIP);
    148                 f.writeSint16BE((int16)_vm->game.logics[i].cIP);
     127                out->writeByte(game.dir_logic[i].flags);
     128                out->writeSint16BE((int16)game.logics[i].sIP);
     129                out->writeSint16BE((int16)game.logics[i].cIP);
    149130        }
    150131        for (i = 0; i < MAX_DIRS; i++)
    151                 f.writeByte(_vm->game.dir_pic[i].flags);
     132                out->writeByte(game.dir_pic[i].flags);
    152133        for (i = 0; i < MAX_DIRS; i++)
    153                 f.writeByte(_vm->game.dir_view[i].flags);
     134                out->writeByte(game.dir_view[i].flags);
    154135        for (i = 0; i < MAX_DIRS; i++)
    155                 f.writeByte(_vm->game.dir_sound[i].flags);
     136                out->writeByte(game.dir_sound[i].flags);
    156137
    157138        /* game.pictures */
    158139        /* game.logics */
     
    160141        /* game.sounds */
    161142
    162143        for (i = 0; i < MAX_VIEWTABLE; i++) {
    163                 struct vt_entry *v = &_vm->game.view_table[i];
     144                struct vt_entry *v = &game.view_table[i];
    164145
    165                 f.writeByte(v->step_time);
    166                 f.writeByte(v->step_time_count);
    167                 f.writeByte(v->entry);
    168                 f.writeSint16BE(v->x_pos);
    169                 f.writeSint16BE(v->y_pos);
    170                 f.writeByte(v->current_view);
     146                out->writeByte(v->step_time);
     147                out->writeByte(v->step_time_count);
     148                out->writeByte(v->entry);
     149                out->writeSint16BE(v->x_pos);
     150                out->writeSint16BE(v->y_pos);
     151                out->writeByte(v->current_view);
    171152
    172153                /* v->view_data */
    173154
    174                 f.writeByte(v->current_loop);
    175                 f.writeByte(v->num_loops);
     155                out->writeByte(v->current_loop);
     156                out->writeByte(v->num_loops);
    176157
    177158                /* v->loop_data */
    178159
    179                 f.writeByte(v->current_cel);
    180                 f.writeByte(v->num_cels);
     160                out->writeByte(v->current_cel);
     161                out->writeByte(v->num_cels);
    181162
    182163                /* v->cel_data */
    183164                /* v->cel_data_2 */
    184165
    185                 f.writeSint16BE(v->x_pos2);
    186                 f.writeSint16BE(v->y_pos2);
     166                out->writeSint16BE(v->x_pos2);
     167                out->writeSint16BE(v->y_pos2);
    187168
    188169                /* v->s */
    189170
    190                 f.writeSint16BE(v->x_size);
    191                 f.writeSint16BE(v->y_size);
    192                 f.writeByte(v->step_size);
    193                 f.writeByte(v->cycle_time);
    194                 f.writeByte(v->cycle_time_count);
    195                 f.writeByte(v->direction);
     171                out->writeSint16BE(v->x_size);
     172                out->writeSint16BE(v->y_size);
     173                out->writeByte(v->step_size);
     174                out->writeByte(v->cycle_time);
     175                out->writeByte(v->cycle_time_count);
     176                out->writeByte(v->direction);
    196177
    197                 f.writeByte(v->motion);
    198                 f.writeByte(v->cycle);
    199                 f.writeByte(v->priority);
     178                out->writeByte(v->motion);
     179                out->writeByte(v->cycle);
     180                out->writeByte(v->priority);
    200181
    201                 f.writeUint16BE(v->flags);
     182                out->writeUint16BE(v->flags);
    202183
    203                 f.writeByte(v->parm1);
    204                 f.writeByte(v->parm2);
    205                 f.writeByte(v->parm3);
    206                 f.writeByte(v->parm4);
     184                out->writeByte(v->parm1);
     185                out->writeByte(v->parm2);
     186                out->writeByte(v->parm3);
     187                out->writeByte(v->parm4);
    207188        }
    208189
    209190        /* Save image stack */
    210191
    211         for (i = 0; i < _vm->image_stack_pointer; i++) {
    212                 ptr = &_vm->image_stack[i];
    213                 f.writeByte(ptr->type);
    214                 f.writeSint16BE(ptr->parm1);
    215                 f.writeSint16BE(ptr->parm2);
    216                 f.writeSint16BE(ptr->parm3);
    217                 f.writeSint16BE(ptr->parm4);
    218                 f.writeSint16BE(ptr->parm5);
    219                 f.writeSint16BE(ptr->parm6);
    220                 f.writeSint16BE(ptr->parm7);
     192        for (i = 0; i < image_stack_pointer; i++) {
     193                ptr = &image_stack[i];
     194                out->writeByte(ptr->type);
     195                out->writeSint16BE(ptr->parm1);
     196                out->writeSint16BE(ptr->parm2);
     197                out->writeSint16BE(ptr->parm3);
     198                out->writeSint16BE(ptr->parm4);
     199                out->writeSint16BE(ptr->parm5);
     200                out->writeSint16BE(ptr->parm6);
     201                out->writeSint16BE(ptr->parm7);
    221202        }
    222         f.writeByte(0);
     203        out->writeByte(0);
    223204
    224         f.close();
    225 
     205        out->flush();
     206        if (out->ioFailed())
     207                warning("Can't write file '%s'. (Disk full?)", fileName);
     208        else
     209                debugC(1, kDebugLevelMain | kDebugLevelSavegame, "Saved game %s in file %s", description, fileName);
     210       
     211        delete out;
     212        debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Closed %s", fileName);
    226213        return err_OK;
    227214}
    228215
    229 int SaveGameMgr::load_game(char *s) {
    230         int i, ver, vt_entries = MAX_VIEWTABLE;
     216int AgiEngine::loadGame(const char *fileName) {
     217        char description[31], saveVersion, loadId[8];
     218        int i, vt_entries = MAX_VIEWTABLE;
    231219        uint8 t;
    232220        int16 parm[7];
    233         char sig[8];
    234         char id[8];
    235         char description[256];
    236         Common::File f;
     221        Common::InSaveFile *in;
    237222
    238         // FIXME: Do *not* use Common::File to access savegames, it is not portable!
    239         f.open(s);
     223        debugC(3, kDebugLevelMain | kDebugLevelSavegame, "AgiEngine::loadGame(%s)", fileName);
    240224
    241         if (!f.isOpen())
     225        if (!(in = _saveFileMan->openForLoading(fileName))) {
     226                warning("Can't open file '%s', game not loaded", fileName);
    242227                return err_BadFileOpen;
    243 
    244         read_bytes(&f, sig, 8);
    245         if (strncmp(sig, strSig, 8)) {
    246                 f.close();
    247                 return err_BadFileOpen;
     228        } else {
     229                debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for reading", fileName);
    248230        }
    249231
    250         read_string(&f, description);
     232        uint32 typea = in->readUint32BE();
     233        if (typea == AGIflag) {
     234                debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Has AGI flag, good start");
     235        } else {
     236                warning("This doesn't appear to be an AGI savegame, game not restored");
     237                delete in;     
     238                return err_OK;
     239        }
    251240
    252         ver = f.readByte();
    253         if (ver == 0)
    254                 vt_entries = 64;
    255         _vm->game.state = f.readByte();
    256         /* game.name - not saved */
    257         read_string(&f, id);
    258         if (strcmp(id, _vm->game.id)) {
    259                 f.close();
     241        in->read(description, 31);
     242       
     243        debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Description is: %s", description);
     244       
     245        saveVersion = in->readByte();
     246        if (saveVersion != SAVEGAME_VERSION)
     247                warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, SAVEGAME_VERSION);
     248
     249        game.state = in->readByte();
     250       
     251        in->read(loadId, 8);
     252        if (strcmp(loadId, game.id)) {
     253                delete in;     
     254                warning("This save seems to be from a different AGI game (save from %s, running %s), not loaded", loadId, game.id);
    260255                return err_BadFileOpen;
    261256        }
    262         /* game.crc - not saved */
    263257
    264258        for (i = 0; i < MAX_FLAGS; i++)
    265                 _vm->game.flags[i] = f.readByte();
     259                game.flags[i] = in->readByte();
    266260        for (i = 0; i < MAX_VARS; i++)
    267                 _vm->game.vars[i] = f.readByte();
     261                game.vars[i] = in->readByte();
    268262
    269         _vm->game.horizon = f.readSint16BE();
    270         _vm->game.line_status = f.readSint16BE();
    271         _vm->game.line_user_input = f.readSint16BE();
    272         _vm->game.line_min_print = f.readSint16BE();
    273 
     263        game.horizon = in->readSint16BE();
     264        game.line_status = in->readSint16BE();
     265        game.line_user_input = in->readSint16BE();
     266        game.line_min_print = in->readSint16BE();
     267       
    274268        /* These are never saved */
    275         _vm->game.cursor_pos = 0;
    276         _vm->game.input_buffer[0] = 0;
    277         _vm->game.echo_buffer[0] = 0;
    278         _vm->game.keypress = 0;
     269        game.cursor_pos = 0;
     270        game.input_buffer[0] = 0;
     271        game.echo_buffer[0] = 0;
     272        game.keypress = 0;
    279273
    280         _vm->game.input_mode = f.readSint16BE();
    281         _vm->game.lognum = f.readSint16BE();
     274        game.input_mode = in->readSint16BE();
     275        game.lognum = in->readSint16BE();
    282276
    283         _vm->game.player_control = f.readSint16BE();
    284         _vm->game.quit_prog_now = f.readSint16BE();
    285         _vm->game.status_line = f.readSint16BE();
    286         _vm->game.clock_enabled = f.readSint16BE();
    287         _vm->game.exit_all_logics = f.readSint16BE();
    288         _vm->game.picture_shown = f.readSint16BE();
    289         _vm->game.has_prompt = f.readSint16BE();
    290         _vm->game.game_flags = f.readSint16BE();
    291         _vm->game.input_enabled = !f.readSint16BE();
     277        game.player_control = in->readSint16BE();
     278        game.quit_prog_now = in->readSint16BE();
     279        game.status_line = in->readSint16BE();
     280        game.clock_enabled = in->readSint16BE();
     281        game.exit_all_logics = in->readSint16BE();
     282        game.picture_shown = in->readSint16BE();
     283        game.has_prompt = in->readSint16BE();
     284        game.game_flags = in->readSint16BE();
     285        game.input_enabled = in->readSint16BE();
    292286
    293287        for (i = 0; i < _HEIGHT; i++)
    294                 _vm->game.pri_table[i] = f.readByte();
     288                game.pri_table[i] = in->readByte();
    295289
    296         if (_vm->game.has_window)
    297                 _vm->close_window();
     290        if (game.has_window)
     291                close_window();
    298292
    299         _vm->game.msg_box_ticks = 0;
    300         _vm->game.block.active = false;
     293        game.msg_box_ticks = 0;
     294        game.block.active = false;
    301295        /* game.window - fixed by close_window() */
    302296        /* game.has_window - fixed by close_window() */
    303297
    304         _vm->game.gfx_mode = f.readSint16BE();
    305         _vm->game.cursor_char = f.readByte();
    306         _vm->game.color_fg = f.readSint16BE();
    307         _vm->game.color_bg = f.readSint16BE();
     298        game.gfx_mode = in->readSint16BE();
     299        game.cursor_char = in->readByte();
     300        game.color_fg = in->readSint16BE();
     301        game.color_bg = in->readSint16BE();
    308302
    309303        /* game.hires - rebuilt from image stack */
    310304        /* game.sbuf - rebuilt from image stack */
     
    312306        /* game.ego_words - fixed by clean_input */
    313307        /* game.num_ego_words - fixed by clean_input */
    314308
    315         _vm->game.num_objects = f.readSint16BE();
    316         for (i = 0; i < (int16)_vm->game.num_objects; i++)
    317                 _vm->object_set_location(i, f.readSint16BE());
     309        game.num_objects = in->readSint16BE();
     310        for (i = 0; i < (int16)game.num_objects; i++)
     311                object_set_location(i, in->readSint16BE());
    318312
    319313        /* Those are not serialized */
    320314        for (i = 0; i < MAX_DIRS; i++) {
    321                 _vm->game.ev_keyp[i].occured = false;
     315                game.ev_keyp[i].occured = false;
    322316        }
    323317
    324318        for (i = 0; i < MAX_STRINGS; i++)
    325                 read_string(&f, _vm->game.strings[i]);
     319                in->read(game.strings[i], MAX_STRINGLEN);
    326320
    327321        for (i = 0; i < MAX_DIRS; i++) {
    328                 if (f.readByte() & RES_LOADED)
    329                         _vm->agiLoadResource(rLOGIC, i);
     322                if (in->readByte() & RES_LOADED)
     323                        agiLoadResource(rLOGIC, i);
    330324                else
    331                         _vm->agiUnloadResource(rLOGIC, i);
    332                 _vm->game.logics[i].sIP = f.readSint16BE();
    333                 _vm->game.logics[i].cIP = f.readSint16BE();
     325                        agiUnloadResource(rLOGIC, i);
     326                game.logics[i].sIP = in->readSint16BE();
     327                game.logics[i].cIP = in->readSint16BE();
    334328        }
    335329
    336330        for (i = 0; i < MAX_DIRS; i++) {
    337                 if (f.readByte() & RES_LOADED)
    338                         _vm->agiLoadResource(rPICTURE, i);
     331                if (in->readByte() & RES_LOADED)
     332                        agiLoadResource(rPICTURE, i);
    339333                else
    340                         _vm->agiUnloadResource(rPICTURE, i);
     334                        agiUnloadResource(rPICTURE, i);
    341335        }
    342336
    343337        for (i = 0; i < MAX_DIRS; i++) {
    344                 if (f.readByte() & RES_LOADED)
    345                         _vm->agiLoadResource(rVIEW, i);
     338                if (in->readByte() & RES_LOADED)
     339                        agiLoadResource(rVIEW, i);
    346340                else
    347                         _vm->agiUnloadResource(rVIEW, i);
     341                        agiUnloadResource(rVIEW, i);
    348342        }
    349343
    350344        for (i = 0; i < MAX_DIRS; i++) {
    351                 if (f.readByte() & RES_LOADED)
    352                         _vm->agiLoadResource(rSOUND, i);
     345                if (in->readByte() & RES_LOADED)
     346                        agiLoadResource(rSOUND, i);
    353347                else
    354                         _vm->agiUnloadResource(rSOUND, i);
     348                        agiUnloadResource(rSOUND, i);
    355349        }
    356350
    357351        /* game.pictures - loaded above */
     
    360354        /* game.sounds - loaded above */
    361355
    362356        for (i = 0; i < vt_entries; i++) {
    363                 struct vt_entry *v = &_vm->game.view_table[i];
     357                struct vt_entry *v = &game.view_table[i];
    364358
    365                 v->step_time = f.readByte();
    366                 v->step_time_count = f.readByte();
    367                 v->entry = f.readByte();
    368                 v->x_pos = f.readSint16BE();
    369                 v->y_pos = f.readSint16BE();
    370                 v->current_view = f.readByte();
     359                v->step_time = in->readByte();
     360                v->step_time_count = in->readByte();
     361                v->entry = in->readByte();
     362                v->x_pos = in->readSint16BE();
     363                v->y_pos = in->readSint16BE();
     364                v->current_view = in->readByte();
    371365
    372366                /* v->view_data - fixed below  */
    373367
    374                 v->current_loop = f.readByte();
    375                 v->num_loops = f.readByte();
     368                v->current_loop = in->readByte();
     369                v->num_loops = in->readByte();
    376370
    377371                /* v->loop_data - fixed below  */
    378372
    379                 v->current_cel = f.readByte();
    380                 v->num_cels = f.readByte();
     373                v->current_cel = in->readByte();
     374                v->num_cels = in->readByte();
    381375
    382376                /* v->cel_data - fixed below  */
    383377                /* v->cel_data_2 - fixed below  */
    384378
    385                 v->x_pos2 = f.readSint16BE();
    386                 v->y_pos2 = f.readSint16BE();
     379                v->x_pos2 = in->readSint16BE();
     380                v->y_pos2 = in->readSint16BE();
    387381
    388382                /* v->s - fixed below */
    389383
    390                 v->x_size = f.readSint16BE();
    391                 v->y_size = f.readSint16BE();
    392                 v->step_size = f.readByte();
    393                 v->cycle_time = f.readByte();
    394                 v->cycle_time_count = f.readByte();
    395                 v->direction = f.readByte();
     384                v->x_size = in->readSint16BE();
     385                v->y_size = in->readSint16BE();
     386                v->step_size = in->readByte();
     387                v->cycle_time = in->readByte();
     388                v->cycle_time_count = in->readByte();
     389                v->direction = in->readByte();
    396390
    397                 v->motion = f.readByte();
    398                 v->cycle = f.readByte();
    399                 v->priority = f.readByte();
     391                v->motion = in->readByte();
     392                v->cycle = in->readByte();
     393                v->priority = in->readByte();
    400394
    401                 v->flags = f.readUint16BE();
     395                v->flags = in->readUint16BE();
    402396
    403                 v->parm1 = f.readByte();
    404                 v->parm2 = f.readByte();
    405                 v->parm3 = f.readByte();
    406                 v->parm4 = f.readByte();
     397                v->parm1 = in->readByte();
     398                v->parm2 = in->readByte();
     399                v->parm3 = in->readByte();
     400                v->parm4 = in->readByte();
    407401        }
    408402        for (i = vt_entries; i < MAX_VIEWTABLE; i++) {
    409                 memset(&_vm->game.view_table[i], 0, sizeof(struct vt_entry));
     403                memset(&game.view_table[i], 0, sizeof(struct vt_entry));
    410404        }
    411405
    412406        /* Fix some pointers in viewtable */
    413407
    414408        for (i = 0; i < MAX_VIEWTABLE; i++) {
    415                 struct vt_entry *v = &_vm->game.view_table[i];
     409                struct vt_entry *v = &game.view_table[i];
    416410
    417                 if (_vm->game.dir_view[v->current_view].offset == _EMPTY)
     411                if (game.dir_view[v->current_view].offset == _EMPTY)
    418412                        continue;
    419413
    420                 if (!(_vm->game.dir_view[v->current_view].flags & RES_LOADED))
    421                         _vm->agiLoadResource(rVIEW, v->current_view);
     414                if (!(game.dir_view[v->current_view].flags & RES_LOADED))
     415                        agiLoadResource(rVIEW, v->current_view);
    422416
    423                 _vm->set_view(v, v->current_view);      /* Fix v->view_data */
    424                 _vm->set_loop(v, v->current_loop);      /* Fix v->loop_data */
    425                 _vm->set_cel(v, v->current_cel);        /* Fix v->cel_data */
     417                set_view(v, v->current_view);   /* Fix v->view_data */
     418                set_loop(v, v->current_loop);   /* Fix v->loop_data */
     419                set_cel(v, v->current_cel);     /* Fix v->cel_data */
    426420                v->cel_data_2 = v->cel_data;
    427421                v->s = NULL;    /* not sure if it is used... */
    428422        }
     
    431425
    432426        /* Clear input line */
    433427        _gfx->clearScreen(0);
    434         _vm->write_status();
     428        write_status();
    435429
    436430        /* Recreate background from saved image stack */
    437         _vm->clear_image_stack();
    438         while ((t = f.readByte()) != 0) {
     431        clear_image_stack();
     432        while ((t = in->readByte()) != 0) {
    439433                for (i = 0; i < 7; i++)
    440                         parm[i] = f.readSint16BE();
    441                 _vm->replay_image_stack_call(t, parm[0], parm[1], parm[2],
     434                        parm[i] = in->readSint16BE();
     435                replay_image_stack_call(t, parm[0], parm[1], parm[2],
    442436                                parm[3], parm[4], parm[5], parm[6]);
    443437        }
    444438
    445         f.close();
     439        delete in;     
     440        debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Closed %s", fileName);
    446441
    447         _vm->setflag(F_restore_just_ran, true);
     442        setflag(F_restore_just_ran, true);
    448443
    449         _vm->game.has_prompt = 0;       /* force input line repaint if necessary */
    450         _vm->clean_input();
     444        game.has_prompt = 0;    /* force input line repaint if necessary */
     445        clean_input();
    451446
    452447        _sprites->erase_both();
    453448        _sprites->blit_both();
     
    460455
    461456#define NUM_SLOTS 12
    462457
    463 int SaveGameMgr::select_slot() {
     458const char *AgiEngine::getSavegameFilename(int num) {
     459        static char saveLoadSlot[12];
     460        sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), num);
     461        return saveLoadSlot;
     462}
     463
     464int AgiEngine::selectSlot() {
    464465        int i, key, active = 0;
    465466        int rc = -1;
    466467        int hm = 2, vm = 3;     /* box margins */
    467468        char desc[NUM_SLOTS][40];
    468469
    469470        for (i = 0; i < NUM_SLOTS; i++) {
    470                 char name[MAX_PATH];
    471                 Common::File f;
    472                 char sig[8];
    473                 // FIXME: Do *not* use Common::File to access savegames, it is not portable!
    474                 sprintf(name, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, i);
    475                 f.open(name);
    476                 if (!f.isOpen()) {
     471                char fileName[MAX_PATH];
     472                Common::InSaveFile *in;
     473               
     474                debugC(4, kDebugLevelMain | kDebugLevelSavegame, "Game id seems to be %s", _targetName.c_str());
     475                sprintf(fileName, "%s", getSavegameFilename(i));
     476                if (!(in = _saveFileMan->openForLoading(fileName))) {
     477                        debugC(4, kDebugLevelMain | kDebugLevelSavegame, "File %s does not exist", fileName);
    477478                        strcpy(desc[i], "          (empty slot)");
    478479                } else {
    479                         read_bytes(&f, sig, 8);
    480                         if (strncmp(sig, strSig, 8)) {
     480                        debugC(4, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for reading", fileName);
     481                        uint32 type = in->readUint32BE();
     482                        if (type == AGIflag) {
     483                                debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Has AGI flag, good start");
     484                                in->read(desc[i], 31);
     485                        } else {
     486                                warning("This doesn't appear to be an AGI savegame");
    481487                                strcpy(desc[i], "(corrupt file)");
    482                         } else {
    483                                 read_string(&f, desc[i]);
    484                         }
    485                         f.close();
     488                        }
     489
     490                        delete in;
    486491                }
    487492        }
    488493
     
    490495                char dstr[64];
    491496                for (i = 0; i < NUM_SLOTS; i++) {
    492497                        sprintf(dstr, "[%-32.32s]", desc[i]);
    493                         _vm->print_text(dstr, 0, hm + 1, vm + 4 + i,
     498                        print_text(dstr, 0, hm + 1, vm + 4 + i,
    494499                                        (40 - 2 * hm) - 1, i == active ? MSG_BOX_COLOUR : MSG_BOX_TEXT,
    495500                                        i == active ? MSG_BOX_TEXT : MSG_BOX_COLOUR);
    496501
    497502                }
    498503
    499504                _gfx->pollTimer();      /* msdos driver -> does nothing */
    500                 key = _vm->do_poll_keyboard();
     505                key = do_poll_keyboard();
    501506                switch (key) {
    502507                case KEY_ENTER:
    503508                        rc = active;
    504                         strncpy(_vm->game.strings[MAX_STRINGS], desc[i], MAX_STRINGLEN);
     509                        strncpy(game.strings[MAX_STRINGS], desc[i], MAX_STRINGLEN);
    505510                        goto press;
    506511                case KEY_ESCAPE:
    507512                        rc = -1;
     
    525530        debugC(8, kDebugLevelMain | kDebugLevelInput, "Button pressed: %d", rc);
    526531
    527532getout:
    528         _vm->close_window();
     533        close_window();
    529534        return rc;
    530535}
    531536
    532 int SaveGameMgr::savegame_simple() {
    533         char path[MAX_PATH];
    534 
    535         sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, 0);
    536         save_game(path, "Default savegame");
    537 
    538         return err_OK;
    539 }
    540 
    541 int SaveGameMgr::savegame_dialog() {
    542         char path[MAX_PATH];
     537int AgiEngine::saveGameDialog() {
     538        char fileName[MAX_PATH];
    543539        char *desc;
    544540        const char *buttons[] = { "Do as I say!", "I regret", NULL };
    545541        char dstr[200];
    546542        int rc, slot = 0;
    547         int hm, vm, hp, vp;     /* box margins */
     543        int hm, vm, hp, vp;     
    548544        int w;
    549545
    550546        hm = 2;
     
    553549        vp = vm * CHAR_LINES;
    554550        w = (40 - 2 * hm) - 1;
    555551
    556         sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, slot);
     552        sprintf(fileName, "%s", getSavegameFilename(slot));
    557553
    558         _vm->draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp);
    559         _vm->print_text("Select a slot in which you wish to save the game:",
     554        draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp);
     555        print_text("Select a slot in which you wish to save the game:",
    560556                        0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR);
    561         _vm->print_text("Press ENTER to select, ESC cancels",
     557        print_text("Press ENTER to select, ESC cancels",
    562558                        0, hm + 1, vm + 17, w, MSG_BOX_TEXT, MSG_BOX_COLOUR);
    563559
    564         slot = select_slot();
    565         if (slot < 0)           /* ESC pressed */
     560        slot = selectSlot();
     561        if (slot < 0)   
    566562                return err_OK;
    567563
    568         /* Get savegame description */
    569         _vm->draw_window(hp, vp + 5 * CHAR_LINES, GFX_WIDTH - hp,
     564        draw_window(hp, vp + 5 * CHAR_LINES, GFX_WIDTH - hp,
    570565                        GFX_HEIGHT - vp - 9 * CHAR_LINES);
    571         _vm->print_text("Enter a description for this game:",
     566        print_text("Enter a description for this game:",
    572567                        0, hm + 1, vm + 6, w, MSG_BOX_TEXT, MSG_BOX_COLOUR);
    573568        _gfx->drawRectangle(3 * CHAR_COLS, 11 * CHAR_LINES - 1,
    574569                        37 * CHAR_COLS, 12 * CHAR_LINES, MSG_BOX_TEXT);
    575570        _gfx->flushBlock(3 * CHAR_COLS, 11 * CHAR_LINES - 1,
    576571                        37 * CHAR_COLS, 12 * CHAR_LINES);
    577572
    578         _vm->get_string(2, 11, 33, MAX_STRINGS);
    579         _gfx->printCharacter(3, 11, _vm->game.cursor_char, MSG_BOX_COLOUR, MSG_BOX_TEXT);
     573        get_string(2, 11, 33, MAX_STRINGS);
     574        _gfx->printCharacter(3, 11, game.cursor_char, MSG_BOX_COLOUR, MSG_BOX_TEXT);
    580575        do {
    581                 _vm->main_cycle();
    582         } while (_vm->game.input_mode == INPUT_GETSTRING);
    583         _vm->close_window();
     576                main_cycle();
     577        } while (game.input_mode == INPUT_GETSTRING);
     578        close_window();
    584579
    585         desc = _vm->game.strings[MAX_STRINGS];
     580        desc = game.strings[MAX_STRINGS];
    586581        sprintf(dstr, "Are you sure you want to save the game "
    587582                        "described as:\n\n%s\n\nin slot %d?\n\n\n", desc, slot);
    588583
    589         rc = _vm->selection_box(dstr, buttons);
     584        rc = selection_box(dstr, buttons);
    590585
    591586        if (rc != 0) {
    592                 _vm->message_box("Game NOT saved.");
     587                message_box("Game NOT saved.");
    593588                return err_OK;
    594589        }
    595590
    596         sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, slot);
    597         debugC(8, kDebugLevelMain | kDebugLevelResources, "file is [%s]", path);
     591        sprintf(fileName, "%s", getSavegameFilename(slot));
     592        debugC(8, kDebugLevelMain | kDebugLevelResources, "file is [%s]", fileName);
    598593
    599         save_game(path, desc);
     594        saveGame(fileName, desc);
    600595
    601         _vm->message_box("Game saved.");
     596        message_box("Game saved.");
    602597
    603598        return err_OK;
    604599}
    605600
    606 int SaveGameMgr::loadgame_simple() {
    607         char path[MAX_PATH];
    608         int rc = 0;
     601int AgiEngine::saveGameSimple() {
     602        char fileName[MAX_PATH];
    609603
    610         sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, 0);
     604        sprintf(fileName, "%s", getSavegameFilename(0));
     605        saveGame(fileName, "Default savegame");
    611606
    612         _sprites->erase_both();
    613         _sound->stop_sound();
    614         _vm->close_window();
    615 
    616         if ((rc = load_game(path)) == err_OK) {
    617                 _vm->message_box("Game restored.");
    618                 _vm->game.exit_all_logics = 1;
    619                 _vm->menu->enable_all();
    620         } else {
    621                 _vm->message_box("Error restoring game.");
    622         }
    623 
    624         return rc;
     607        return err_OK;
    625608}
    626609
    627 int SaveGameMgr::loadgame_dialog() {
    628         char path[MAX_PATH];
     610int AgiEngine::loadGameDialog() {
     611        char fileName[MAX_PATH];
    629612        int rc, slot = 0;
    630613        int hm, vm, hp, vp;     /* box margins */
    631614        int w;
     
    636619        vp = vm * CHAR_LINES;
    637620        w = (40 - 2 * hm) - 1;
    638621
    639         sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, slot);
     622        sprintf(fileName, "%s", getSavegameFilename(slot));
    640623
    641624        _sprites->erase_both();
    642625        _sound->stop_sound();
    643626
    644         _vm->draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp);
    645         _vm->print_text("Select a game which you wish to\nrestore:",
     627        draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp);
     628        print_text("Select a game which you wish to\nrestore:",
    646629                        0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR);
    647         _vm->print_text("Press ENTER to select, ESC cancels",
     630        print_text("Press ENTER to select, ESC cancels",
    648631                        0, hm + 1, vm + 17, w, MSG_BOX_TEXT, MSG_BOX_COLOUR);
    649632
    650         slot = select_slot();
     633        slot = selectSlot();
    651634
    652635        if (slot < 0) {
    653                 _vm->message_box("Game NOT restored.");
     636                message_box("Game NOT restored.");
    654637                return err_OK;
    655638        }
    656639
    657         sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, slot);
     640        sprintf(fileName, "%s", getSavegameFilename(slot));
    658641
    659         if ((rc = load_game(path)) == err_OK) {
    660                 _vm->message_box("Game restored.");
    661                 _vm->game.exit_all_logics = 1;
    662                 _vm->menu->enable_all();
     642        if ((rc = loadGame(fileName)) == err_OK) {
     643                message_box("Game restored.");
     644                game.exit_all_logics = 1;
     645                menu->enable_all();
    663646        } else {
    664                 _vm->message_box("Error restoring game.");
     647                message_box("Error restoring game.");
    665648        }
    666649
    667650        return rc;
    668651}
    669652
     653int AgiEngine::loadGameSimple() {
     654        char fileName[MAX_PATH];
     655        int rc = 0;
     656
     657        sprintf(fileName, "%s", getSavegameFilename(0));
     658
     659        _sprites->erase_both();
     660        _sound->stop_sound();
     661        close_window();
     662
     663        if ((rc = loadGame(fileName)) == err_OK) {
     664                message_box("Game restored.");
     665                game.exit_all_logics = 1;
     666                menu->enable_all();
     667        } else {
     668                message_box("Error restoring game.");
     669        }
     670
     671        return rc;
     672}
     673
    670674}                             // End of namespace Agi
  • engines/agi/agi.h

     
    152152        kDebugLevelMenu =      1 << 5,
    153153        kDebugLevelScripts =   1 << 6,
    154154        kDebugLevelSound =     1 << 7,
    155         kDebugLevelText =      1 << 8
     155        kDebugLevelText =      1 << 8,
     156        kDebugLevelSavegame =  1 << 9
    156157};
    157158
    158159/**
     
    486487class GfxMgr;
    487488class SpritesMgr;
    488489class Menu;
    489 class SaveGameMgr;
    490490
    491491extern struct Mouse g_mouse;
    492492
     
    557557        Common::RandomSource *_rnd;
    558558        const char *_savePath;
    559559
     560        const char *getSavegameFilename(int num);
     561        int selectSlot();
     562        int saveGame(const char *fileName, const char *saveName);
     563        int saveGameDialog();
     564        int saveGameSimple();
     565        int loadGame(const char *fileName);
     566        int loadGameDialog();
     567        int loadGameSimple();
     568
    560569        volatile uint32 clock_count;
    561570
    562571        uint8 *intobj;
     
    569578        GfxMgr *_gfx;
    570579        SoundMgr *_sound;
    571580        PictureMgr *_picture;
    572         SaveGameMgr *_saveGameMgr;
    573581
    574582        #define INITIAL_IMAGE_STACK_SIZE 32
    575583
  • engines/agi/savegame.h

     
    2727
    2828#include "agi/agi.h"
    2929
    30 class Common::File;
     30//class Common::File;
    3131
    3232namespace Agi {
    3333
     
    4040class SoundMgr;
    4141class PictureMgr;
    4242
    43 class SaveGameMgr {
    44 private:
    45 
    46         AgiEngine *_vm;
    47         SpritesMgr *_sprites;
    48         GfxMgr *_gfx;
    49         SoundMgr *_sound;
    50         PictureMgr *_picture;
    51 
    52         void write_string(Common::File *f, const char *s);
    53         void read_string(Common::File *f, char *s);
    54         void write_bytes(Common::File *f, const char *s, int16 size);
    55         void read_bytes(Common::File *f, char *s, int16 size);
    56         int save_game(char *s, const char *d);
    57         int load_game(char *s);
    58         int select_slot();
    59 
    60 public:
    61         SaveGameMgr(AgiEngine *agi, SpritesMgr *sprites,
    62                                 GfxMgr *gfx,
    63                                 SoundMgr *sound, PictureMgr *picture) {
    64                 _vm = agi;
    65                 _sprites = sprites;
    66                 _gfx = gfx;
    67                 _sound = sound;
    68                 _picture = picture;
    69         }
    70 
    71         int savegame_dialog();
    72         int loadgame_dialog();
    73         int savegame_simple();
    74         int loadgame_simple();
    75 };
    76 
    7743}                             // End of namespace Agi
    7844
    7945#endif                          /* AGI_SAVEGAME_H */