Ticket #8615: agi-saveslots.diff
File agi-saveslots.diff, 10.1 KB (added by , 18 years ago) |
---|
-
engines/agi/agi.cpp
52 52 static uint32 g_tickTimer; 53 53 struct Mouse g_mouse; 54 54 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 60 55 void AgiEngine::processEvents() { 61 56 OSystem::Event event; 62 57 int key = 0; … … 82 77 g_mouse.x = event.mouse.x; 83 78 g_mouse.y = event.mouse.y; 84 79 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; 85 88 case OSystem::EVENT_MOUSEMOVE: 86 89 g_mouse.x = event.mouse.x; 87 90 g_mouse.y = event.mouse.y; … … 557 560 _oldMode = -1; 558 561 559 562 _searchTreeRoot = 0; 563 _firstSlot = 0; 560 564 } 561 565 562 566 void AgiEngine::initialize() { -
engines/agi/keyboard.h
29 29 30 30 namespace Agi { 31 31 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 32 37 /* QNX4 has a KEY_DOWN defined which we don't need to care about */ 33 38 #undef KEY_DOWN 34 39 … … 67 72 68 73 #define BUTTON_LEFT 0xF101 /* Left mouse button */ 69 74 #define BUTTON_RIGHT 0xF202 /* Right mouse button */ 75 #define WHEEL_UP 0xF203 /* Mouse wheel up */ 76 #define WHEEL_DOWN 0xF204 /* Mouse wheel down */ 70 77 71 78 #define KEY_SCAN(k) (k >> 8) 72 79 #define KEY_ASCII(k) (k & 0xff) -
engines/agi/savegame.cpp
451 451 return errOK; 452 452 } 453 453 454 #define NUM_SLOTS 12 454 #define NUM_SLOTS 100 455 #define NUM_VISIBLE_SLOTS 12 455 456 456 457 const char *AgiEngine::getSavegameFilename(int num) { 457 458 static char saveLoadSlot[12]; 458 sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), num );459 sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), num + _firstSlot); 459 460 return saveLoadSlot; 460 461 } 462 463 void 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 } 461 486 462 487 int AgiEngine::selectSlot() { 463 488 int i, key, active = 0; 464 489 int rc = -1; 465 int hm = 2, vm = 3; /* box margins */490 int hm = 1, vm = 3; /* box margins */ 466 491 int xmin, xmax, slotClicked; 467 char desc[NUM_ SLOTS][40];492 char desc[NUM_VISIBLE_SLOTS][40]; 468 493 int textCentre, buttonLength, buttonX[2], buttonY; 469 494 const char *buttonText[] = { " OK ", "Cancel", NULL }; 470 495 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]); 493 498 } 494 499 495 500 textCentre = GFX_WIDTH / CHAR_LINES / 2; … … 499 504 buttonY = (vm + 17) * CHAR_LINES; 500 505 501 506 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); 503 508 504 509 for (;;) { 505 510 char dstr[64]; 506 for (i = 0; i < NUM_ SLOTS; i++) {511 for (i = 0; i < NUM_VISIBLE_SLOTS; i++) { 507 512 sprintf(dstr, "[%-32.32s]", desc[i]); 508 513 printText(dstr, 0, hm + 1, vm + 4 + i, 509 514 (40 - 2 * hm) - 1, i == active ? MSG_BOX_COLOUR : MSG_BOX_TEXT, 510 515 i == active ? MSG_BOX_TEXT : MSG_BOX_COLOUR); 511 516 } 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); 512 532 513 533 _gfx->pollTimer(); /* msdos driver -> does nothing */ 514 534 key = doPollKeyboard(); … … 530 550 rc = -1; 531 551 goto getout; 532 552 } 553 slotClicked = ((int)g_mouse.y-1)/CHAR_COLS-(vm+4); 533 554 xmin = (hm + 1) * CHAR_COLS; 534 555 xmax = xmin + CHAR_COLS * 34; 535 556 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) 538 558 active = slotClicked; 539 559 } 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 } 540 574 break; 541 575 case KEY_DOWN: 542 576 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 } 544 586 break; 545 587 case KEY_UP: 546 588 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 } 549 598 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; 550 637 } 551 638 _gfx->doUpdate(); 552 639 } … … 568 655 int hm, vm, hp, vp; 569 656 int w; 570 657 571 hm = 2;658 hm = 1; 572 659 vm = 3; 573 660 hp = hm * CHAR_COLS; 574 661 vp = vm * CHAR_LINES; … … 577 664 sprintf(fileName, "%s", getSavegameFilename(slot)); 578 665 579 666 drawWindow(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); 580 printText("Select a slot in which you wish to 667 printText("Select a slot in which you wish to\nsave the game:", 581 668 0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); 582 669 583 670 slot = selectSlot(); … … 602 689 603 690 desc = _game.strings[MAX_STRINGS]; 604 691 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); 606 693 607 694 rc = selectionBox(dstr, buttons); 608 695 … … 636 723 int hm, vm, hp, vp; /* box margins */ 637 724 int w; 638 725 639 hm = 2;726 hm = 1; 640 727 vm = 3; 641 728 hp = hm * CHAR_COLS; 642 729 vp = vm * CHAR_LINES; -
engines/agi/agi.h
524 524 525 525 uint32 matchVersion(uint32 crc); 526 526 527 int _firstSlot; 528 527 529 public: 528 530 AgiGame _game; 529 531 AgiObject *_objects; /* objects in the game */ … … 535 537 Common::RandomSource *_rnd; 536 538 537 539 const char *getSavegameFilename(int num); 540 void getSavegameDescription(int num, char *buf); 538 541 int selectSlot(); 539 542 int saveGame(const char *fileName, const char *saveName); 540 543 int saveGameDialog();