Ticket #8615: agi-saveslots.diff

File agi-saveslots.diff, 10.1 KB (added by eriktorbjorn, 16 years ago)

Patch against current SVN

  • engines/agi/agi.cpp

     
    5252static uint32 g_tickTimer;
    5353struct Mouse g_mouse;
    5454
    55 #define keyEnqueue(k) do { _keyQueue[_keyQueueEnd++] = (k); \
    56         _keyQueueEnd %= KEY_QUEUE_SIZE; } while (0)
    57 #define keyDequeue(k) do { (k) = _keyQueue[_keyQueueStart++]; \
    58         _keyQueueStart %= KEY_QUEUE_SIZE; } while (0)
    59 
    6055void AgiEngine::processEvents() {
    6156        OSystem::Event event;
    6257        int key = 0;
     
    8277                        g_mouse.x = event.mouse.x;
    8378                        g_mouse.y = event.mouse.y;
    8479                        break;
     80                case OSystem::EVENT_WHEELUP:
     81                        key = WHEEL_UP;
     82                        keyEnqueue(key);
     83                        break;
     84                case OSystem::EVENT_WHEELDOWN:
     85                        key = WHEEL_DOWN;
     86                        keyEnqueue(key);
     87                        break;
    8588                case OSystem::EVENT_MOUSEMOVE:
    8689                        g_mouse.x = event.mouse.x;
    8790                        g_mouse.y = event.mouse.y;
     
    557560        _oldMode = -1;
    558561       
    559562        _searchTreeRoot = 0;
     563        _firstSlot = 0;
    560564}
    561565
    562566void AgiEngine::initialize() {
  • engines/agi/keyboard.h

     
    2929
    3030namespace Agi {
    3131
     32#define keyEnqueue(k) do { _keyQueue[_keyQueueEnd++] = (k); \
     33        _keyQueueEnd %= KEY_QUEUE_SIZE; } while (0)
     34#define keyDequeue(k) do { (k) = _keyQueue[_keyQueueStart++]; \
     35        _keyQueueStart %= KEY_QUEUE_SIZE; } while (0)
     36
    3237/* QNX4 has a KEY_DOWN defined which we don't need to care about */
    3338#undef KEY_DOWN
    3439
     
    6772
    6873#define BUTTON_LEFT     0xF101  /* Left mouse button */
    6974#define BUTTON_RIGHT    0xF202  /* Right mouse button */
     75#define WHEEL_UP        0xF203  /* Mouse wheel up */
     76#define WHEEL_DOWN      0xF204  /* Mouse wheel down */
    7077
    7178#define KEY_SCAN(k)     (k >> 8)
    7279#define KEY_ASCII(k)    (k & 0xff)
  • engines/agi/savegame.cpp

     
    451451        return errOK;
    452452}
    453453
    454 #define NUM_SLOTS 12
     454#define NUM_SLOTS 100
     455#define NUM_VISIBLE_SLOTS 12
    455456
    456457const char *AgiEngine::getSavegameFilename(int num) {
    457458        static char saveLoadSlot[12];
    458         sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), num);
     459        sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), num + _firstSlot);
    459460        return saveLoadSlot;
    460461}
     462
     463void AgiEngine::getSavegameDescription(int num, char *buf) {
     464        char fileName[MAX_PATH];
     465        Common::InSaveFile *in;
     466               
     467        debugC(4, kDebugLevelMain | kDebugLevelSavegame, "Current game id is %s", _targetName.c_str());
     468        sprintf(fileName, "%s", getSavegameFilename(num));
     469        if (!(in = _saveFileMan->openForLoading(fileName))) {
     470                debugC(4, kDebugLevelMain | kDebugLevelSavegame, "File %s does not exist", fileName);
     471                strcpy(buf, "          (empty slot)");
     472        } else {
     473                debugC(4, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for reading", fileName);
     474                uint32 type = in->readUint32BE();
     475                if (type == AGIflag) {
     476                        debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Has AGI flag, good start");
     477                        in->read(buf, 31);
     478                } else {
     479                        warning("This doesn't appear to be an AGI savegame");
     480                        strcpy(buf, "(corrupt file)");
     481                }
     482
     483                delete in;
     484        }
     485}
    461486       
    462487int AgiEngine::selectSlot() {
    463488        int i, key, active = 0;
    464489        int rc = -1;
    465         int hm = 2, vm = 3;     /* box margins */
     490        int hm = 1, vm = 3;     /* box margins */
    466491        int xmin, xmax, slotClicked;
    467         char desc[NUM_SLOTS][40];
     492        char desc[NUM_VISIBLE_SLOTS][40];
    468493        int textCentre, buttonLength, buttonX[2], buttonY;
    469494        const char *buttonText[] = { "  OK  ", "Cancel", NULL };
    470495
    471         for (i = 0; i < NUM_SLOTS; i++) {
    472                 char fileName[MAX_PATH];
    473                 Common::InSaveFile *in;
    474                
    475                 debugC(4, kDebugLevelMain | kDebugLevelSavegame, "Current game id is %s", _targetName.c_str());
    476                 sprintf(fileName, "%s", getSavegameFilename(i));
    477                 if (!(in = _saveFileMan->openForLoading(fileName))) {
    478                         debugC(4, kDebugLevelMain | kDebugLevelSavegame, "File %s does not exist", fileName);
    479                         strcpy(desc[i], "          (empty slot)");
    480                 } else {
    481                         debugC(4, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for reading", fileName);
    482                         uint32 type = in->readUint32BE();
    483                         if (type == AGIflag) {
    484                                 debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Has AGI flag, good start");
    485                                 in->read(desc[i], 31);
    486                         } else {
    487                                 warning("This doesn't appear to be an AGI savegame");
    488                                 strcpy(desc[i], "(corrupt file)");
    489                         }
    490 
    491                         delete in;
    492                 }
     496        for (i = 0; i < NUM_VISIBLE_SLOTS; i++) {
     497                getSavegameDescription(i, desc[i]);
    493498        }
    494499
    495500        textCentre = GFX_WIDTH / CHAR_LINES / 2;
     
    499504        buttonY = (vm + 17) * CHAR_LINES;
    500505       
    501506        for (i = 0; i < 2; i++)
    502         _gfx->drawButton(buttonX[i], buttonY, buttonText[i], 0, 0, MSG_BOX_TEXT, MSG_BOX_COLOUR);
     507                _gfx->drawButton(buttonX[i], buttonY, buttonText[i], 0, 0, MSG_BOX_TEXT, MSG_BOX_COLOUR);
    503508
    504509        for (;;) {
    505510                char dstr[64];
    506                 for (i = 0; i < NUM_SLOTS; i++) {
     511                for (i = 0; i < NUM_VISIBLE_SLOTS; i++) {
    507512                        sprintf(dstr, "[%-32.32s]", desc[i]);
    508513                        printText(dstr, 0, hm + 1, vm + 4 + i,
    509514                                        (40 - 2 * hm) - 1, i == active ? MSG_BOX_COLOUR : MSG_BOX_TEXT,
    510515                                        i == active ? MSG_BOX_TEXT : MSG_BOX_COLOUR);
    511516                }
     517
     518                char upArrow[] = "^";
     519                char downArrow[] = "v";
     520                char scrollBar[] = " ";
     521
     522                int sbPos = 1 + (_firstSlot * (NUM_VISIBLE_SLOTS - 2)) / (NUM_SLOTS - NUM_VISIBLE_SLOTS);
     523                if (sbPos > NUM_VISIBLE_SLOTS - 2)
     524                        sbPos = NUM_VISIBLE_SLOTS - 2;
     525
     526                for (i = 1; i < NUM_VISIBLE_SLOTS - 1; i++)
     527                        printText(scrollBar, 35, hm + 1, vm + 4 + i, 1, MSG_BOX_COLOUR, 7, true);
     528
     529                printText(upArrow, 35, hm + 1, vm + 4, 1, 8, 7);
     530                printText(downArrow, 35, hm + 1, vm + 4 + NUM_VISIBLE_SLOTS - 1, 1, 8, 7);
     531                printText(scrollBar, 35, hm + 1, vm + 4 + sbPos, 1, MSG_BOX_COLOUR, MSG_BOX_TEXT);
    512532               
    513533                _gfx->pollTimer();      /* msdos driver -> does nothing */
    514534                key = doPollKeyboard();
     
    530550                                rc = -1;
    531551                                goto getout;
    532552                        }
     553                        slotClicked = ((int)g_mouse.y-1)/CHAR_COLS-(vm+4);
    533554                        xmin = (hm + 1) * CHAR_COLS;
    534555                        xmax = xmin + CHAR_COLS * 34;
    535556                        if ((int)g_mouse.x >= xmin && (int)g_mouse.x <= xmax) {
    536                                 slotClicked = ((int)g_mouse.y-1)/CHAR_COLS-(vm+4);
    537                                 if (slotClicked >= 0 && slotClicked < NUM_SLOTS)
     557                                if (slotClicked >= 0 && slotClicked < NUM_VISIBLE_SLOTS)
    538558                                        active = slotClicked;
    539559                        }
     560                        xmin = (hm + 36) * CHAR_COLS;
     561                        xmax = xmin + CHAR_COLS;
     562                        if ((int)g_mouse.x >= xmin && (int)g_mouse.x <= xmax) {
     563                                if (slotClicked >= 0 && slotClicked < NUM_VISIBLE_SLOTS) {
     564                                        if (slotClicked == 0)
     565                                                keyEnqueue(KEY_UP);
     566                                        else if (slotClicked == NUM_VISIBLE_SLOTS - 1)
     567                                                keyEnqueue(KEY_DOWN);
     568                                        else if (slotClicked < sbPos)
     569                                                keyEnqueue(KEY_UP_RIGHT);
     570                                        else if (slotClicked > sbPos)
     571                                                keyEnqueue(KEY_DOWN_RIGHT);
     572                                }
     573                        }
    540574                        break;
    541575                case KEY_DOWN:
    542576                        active++;
    543                         active %= NUM_SLOTS;
     577                        if (active >= NUM_VISIBLE_SLOTS) {
     578                                if (_firstSlot + NUM_VISIBLE_SLOTS < NUM_SLOTS) {
     579                                        _firstSlot++;
     580                                        for (i = 1; i < NUM_VISIBLE_SLOTS; i++)
     581                                                memcpy(desc[i - 1], desc[i], sizeof(desc[0]));
     582                                        getSavegameDescription(NUM_VISIBLE_SLOTS - 1, desc[NUM_VISIBLE_SLOTS - 1]);
     583                                }
     584                                active = NUM_VISIBLE_SLOTS - 1;
     585                        }
    544586                        break;
    545587                case KEY_UP:
    546588                        active--;
    547                         if (active < 0)
    548                                 active = NUM_SLOTS - 1;
     589                        if (active < 0) {
     590                                active = 0;
     591                                if (_firstSlot > 0) {
     592                                        _firstSlot--;
     593                                        for (i = NUM_VISIBLE_SLOTS - 1; i > 0; i--)
     594                                                memcpy(desc[i], desc[i - 1], sizeof(desc[0]));
     595                                        getSavegameDescription(0, desc[0]);
     596                                }
     597                        }
    549598                        break;
     599                       
     600                // Page Up/Down and mouse wheel scrolling all leave 'active'
     601                // unchanged so that a visible slot will remain selected.
     602
     603                case WHEEL_DOWN:
     604                        if (_firstSlot < NUM_SLOTS - NUM_VISIBLE_SLOTS) {
     605                                _firstSlot++;
     606                                for (i = 1; i < NUM_VISIBLE_SLOTS; i++)
     607                                        memcpy(desc[i - 1], desc[i], sizeof(desc[0]));
     608                                getSavegameDescription(NUM_VISIBLE_SLOTS - 1, desc[NUM_VISIBLE_SLOTS - 1]);
     609                        }
     610                        break;
     611                case WHEEL_UP:
     612                        if (_firstSlot > 0) {
     613                                _firstSlot--;
     614                                for (i = NUM_VISIBLE_SLOTS - 1; i > 0; i--)
     615                                        memcpy(desc[i], desc[i - 1], sizeof(desc[0]));
     616                                getSavegameDescription(0, desc[0]);
     617                        }
     618                        break;
     619                case KEY_DOWN_RIGHT:
     620                        // This is probably triggered by Page Down.
     621                        _firstSlot += NUM_VISIBLE_SLOTS;
     622                        if (_firstSlot > NUM_SLOTS - NUM_VISIBLE_SLOTS) {
     623                                _firstSlot = NUM_SLOTS - NUM_VISIBLE_SLOTS;
     624                        }
     625                        for (i = 0; i < NUM_VISIBLE_SLOTS; i++)
     626                                getSavegameDescription(i, desc[i]);
     627                        break;
     628                case KEY_UP_RIGHT:
     629                        // This is probably triggered by Page Up.
     630                        _firstSlot -= NUM_VISIBLE_SLOTS;
     631                        if (_firstSlot < 0) {
     632                                _firstSlot = 0;
     633                        }
     634                        for (i = 0; i < NUM_VISIBLE_SLOTS; i++)
     635                                getSavegameDescription(i, desc[i]);
     636                        break;
    550637                }
    551638                _gfx->doUpdate();
    552639        }
     
    568655        int hm, vm, hp, vp;     
    569656        int w;
    570657
    571         hm = 2;
     658        hm = 1;
    572659        vm = 3;
    573660        hp = hm * CHAR_COLS;
    574661        vp = vm * CHAR_LINES;
     
    577664        sprintf(fileName, "%s", getSavegameFilename(slot));
    578665
    579666        drawWindow(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp);
    580         printText("Select a slot in which you wish to save the game:",
     667        printText("Select a slot in which you wish to\nsave the game:",
    581668                        0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR);
    582669
    583670        slot = selectSlot();
     
    602689
    603690        desc = _game.strings[MAX_STRINGS];
    604691        sprintf(dstr, "Are you sure you want to save the game "
    605                         "described as:\n\n%s\n\nin slot %d?\n\n\n", desc, slot);
     692                        "described as:\n\n%s\n\nin slot %d?\n\n\n", desc, slot + _firstSlot);
    606693
    607694        rc = selectionBox(dstr, buttons);
    608695
     
    636723        int hm, vm, hp, vp;     /* box margins */
    637724        int w;
    638725
    639         hm = 2;
     726        hm = 1;
    640727        vm = 3;
    641728        hp = hm * CHAR_COLS;
    642729        vp = vm * CHAR_LINES;
  • engines/agi/agi.h

     
    524524
    525525        uint32 matchVersion(uint32 crc);
    526526
     527        int _firstSlot;
     528
    527529public:
    528530        AgiGame _game;
    529531        AgiObject *_objects;    /* objects in the game */
     
    535537        Common::RandomSource *_rnd;
    536538
    537539        const char *getSavegameFilename(int num);
     540        void getSavegameDescription(int num, char *buf);
    538541        int selectSlot();
    539542        int saveGame(const char *fileName, const char *saveName);
    540543        int saveGameDialog();