From 305ab6847a6c3467ab02ea3f0798e300d82c89ed Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 2 Jul 2012 04:18:12 +0200 Subject: GOB: Reorganize and clean up PreGob / Once Upon A Time --- engines/gob/pregob/onceupon/abracadabra.cpp | 28 +-- engines/gob/pregob/onceupon/abracadabra.h | 6 +- engines/gob/pregob/onceupon/babayaga.cpp | 28 +-- engines/gob/pregob/onceupon/babayaga.h | 6 +- engines/gob/pregob/onceupon/onceupon.cpp | 355 ++++++++++++++++------------ engines/gob/pregob/onceupon/onceupon.h | 221 +++++++++++------ engines/gob/pregob/pregob.h | 50 +++- 7 files changed, 424 insertions(+), 270 deletions(-) (limited to 'engines') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 5a5e407774..2e4b5f21e7 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -80,7 +80,6 @@ const char *Abracadabra::kAnimalNames[] = { Abracadabra::Abracadabra(GobEngine *vm) : OnceUpon(vm) { - setAnimalsButton(&kAnimalsButtons); } Abracadabra::~Abracadabra() { @@ -99,28 +98,13 @@ void Abracadabra::run() { if (_vm->shouldQuit()) return; - mainLoop(); - - if (!_vm->shouldQuit()) - showByeBye(); -} + // Handle the start menu + doStartMenu(&kAnimalsButtons, ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); + if (_vm->shouldQuit()) + return; -void Abracadabra::mainLoop() { - clearScreen(); - - MenuType mainMenu = kMenuTypeMainStart; - - while (!_vm->shouldQuit()) { - MenuAction action = doMenu(mainMenu); - if (action == kMenuActionPlay) - warning("Abracadabra::mainLoop(): TODO: Play"); - else if (action == kMenuActionRestart) - warning("Abracadabra::mainLoop(): TODO: Restart"); - else if (action == kMenuActionAnimals) - doAnimalNames(ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); - else if (action == kMenuActionQuit) - break; - } + // Play the actual game + playGame(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/abracadabra.h b/engines/gob/pregob/onceupon/abracadabra.h index 5f3a1ba634..f2075fc750 100644 --- a/engines/gob/pregob/onceupon/abracadabra.h +++ b/engines/gob/pregob/onceupon/abracadabra.h @@ -37,13 +37,13 @@ public: void run(); private: + /** Definition of the menu button that leads to the animal names screen. */ static const MenuButton kAnimalsButtons; + /** Definition of the buttons that make up the animals in the animal names screen. */ static const MenuButton kAnimalButtons[]; + /** File prefixes for the name of each animal. */ static const char *kAnimalNames[]; - - - void mainLoop(); }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 9475ac4b05..6f27f469e3 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -80,7 +80,6 @@ const char *BabaYaga::kAnimalNames[] = { BabaYaga::BabaYaga(GobEngine *vm) : OnceUpon(vm) { - setAnimalsButton(&kAnimalsButtons); } BabaYaga::~BabaYaga() { @@ -99,28 +98,13 @@ void BabaYaga::run() { if (_vm->shouldQuit()) return; - mainLoop(); - - if (!_vm->shouldQuit()) - showByeBye(); -} + // Handle the start menu + doStartMenu(&kAnimalsButtons, ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); + if (_vm->shouldQuit()) + return; -void BabaYaga::mainLoop() { - clearScreen(); - - MenuType mainMenu = kMenuTypeMainStart; - - while (!_vm->shouldQuit()) { - MenuAction action = doMenu(mainMenu); - if (action == kMenuActionPlay) - warning("BabaYaga::mainLoop(): TODO: Play"); - else if (action == kMenuActionRestart) - warning("BabaYaga::mainLoop(): TODO: Restart"); - else if (action == kMenuActionAnimals) - doAnimalNames(ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); - else if (action == kMenuActionQuit) - break; - } + // Play the actual game + playGame(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.h b/engines/gob/pregob/onceupon/babayaga.h index de42f8e8fe..181b6f4d54 100644 --- a/engines/gob/pregob/onceupon/babayaga.h +++ b/engines/gob/pregob/onceupon/babayaga.h @@ -37,13 +37,13 @@ public: void run(); private: + /** Definition of the menu button that leads to the animal names screen. */ static const MenuButton kAnimalsButtons; + /** Definition of the buttons that make up the animals in the animal names screen. */ static const MenuButton kAnimalButtons[]; + /** File prefixes for the name of each animal. */ static const char *kAnimalNames[]; - - - void mainLoop(); }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 6b90e9ba00..785d78b769 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -132,8 +132,17 @@ const char *OnceUpon::kSound[kSoundMAX] = { }; -OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _jeudak(0), _lettre(0), _plettre(0), _glettre(0), - _openedArchives(false), _animalsButton(0) { +OnceUpon::ScreenBackup::ScreenBackup() : palette(-1), changedCursor(false), cursorVisible(false) { + screen = new Surface(320, 200, 1); +} + +OnceUpon::ScreenBackup::~ScreenBackup() { + delete screen; +} + + +OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _openedArchives(false), + _jeudak(0), _lettre(0), _plettre(0), _glettre(0) { } @@ -144,6 +153,8 @@ OnceUpon::~OnceUpon() { void OnceUpon::init() { deinit(); + // Open data files + bool hasSTK1 = _vm->_dataIO->openArchive("stk1.stk", true); bool hasSTK2 = _vm->_dataIO->openArchive("stk2.stk", true); bool hasSTK3 = _vm->_dataIO->openArchive("stk3.stk", true); @@ -153,6 +164,8 @@ void OnceUpon::init() { _openedArchives = true; + // Open fonts + _jeudak = _vm->_draw->loadFont("jeudak.let"); _lettre = _vm->_draw->loadFont("lettre.let"); _plettre = _vm->_draw->loadFont("plettre.let"); @@ -162,6 +175,8 @@ void OnceUpon::init() { error("OnceUpon::OnceUpon(): Failed to fonts (%d, %d, %d, %d)", _jeudak != 0, _lettre != 0, _plettre != 0, _glettre != 0); + // Verify the language + if (_vm->_global->_language == kLanguageAmerican) _vm->_global->_language = kLanguageBritish; @@ -171,17 +186,25 @@ void OnceUpon::init() { "please contact the ScummVM team with details about this version.\n" "Thanks", _vm->getLangDesc(_vm->_global->_language)); - loadSounds(kSound, kSoundMAX); + // Load all our sounds and init the screen + loadSounds(kSound, kSoundMAX); initScreen(); + // We start with an invalid palette + _palette = -1; + + // We start with no selected difficulty and at section 0 _difficulty = kDifficultyMAX; _section = 0; } void OnceUpon::deinit() { + // Free sounds freeSounds(); + // Free fonts + delete _jeudak; delete _lettre; delete _plettre; @@ -192,6 +215,8 @@ void OnceUpon::deinit() { _plettre = 0; _glettre = 0; + // Close archives + if (_openedArchives) { _vm->_dataIO->closeArchive(true); _vm->_dataIO->closeArchive(true); @@ -201,29 +226,115 @@ void OnceUpon::deinit() { _openedArchives = false; } -void OnceUpon::setAnimalsButton(const MenuButton *animalsButton) { - _animalsButton = animalsButton; -} - -void OnceUpon::setCopyProtectionPalette() { - setPalette(kCopyProtectionPalette, kPaletteSize); -} - void OnceUpon::setGamePalette(uint palette) { if (palette >= kPaletteCount) return; + _palette = palette; + setPalette(kGamePalettes[palette], kPaletteSize); } void OnceUpon::setGameCursor() { Surface cursor(320, 16, 1); + // Set the default game cursor _vm->_video->drawPackedSprite("icon.cmp", cursor); - setCursor(cursor, 105, 0, 120, 15, 0, 0); } +void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const { + ani.setAnimation(state); + ani.setMode(once ? ANIObject::kModeOnce : ANIObject::kModeContinuous); + ani.setPause(pause); + ani.setVisible(true); + ani.setPosition(); +} + +void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y) const { + + // A special way of drawing something: + // Draw every other line "downwards", wait a bit after each line + // Then, draw the remaining lines "upwards" and again wait a bit after each line. + + if (_vm->shouldQuit()) + return; + + const int16 width = right - left + 1; + const int16 height = bottom - top + 1; + + if ((width <= 0) || (height <= 0)) + return; + + // Draw the even lines downwards + for (int16 i = 0; i < height; i += 2) { + if (_vm->shouldQuit()) + return; + + _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); + _vm->_draw->blitInvalidated(); + + _vm->_util->longDelay(1); + } + + // Draw the odd lines upwards + for (int16 i = (height & 1) ? height : (height - 1); i >= 0; i -= 2) { + if (_vm->shouldQuit()) + return; + + _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); + _vm->_draw->blitInvalidated(); + + _vm->_util->longDelay(1); + } +} + +void OnceUpon::backupScreen(ScreenBackup &backup, bool setDefaultCursor) { + // Backup the screen and palette + backup.screen->blit(*_vm->_draw->_backSurface); + backup.palette = _palette; + + // Backup the cursor + + backup.cursorVisible = isCursorVisible(); + + backup.changedCursor = false; + if (setDefaultCursor) { + backup.changedCursor = true; + + addCursor(); + setGameCursor(); + } +} + +void OnceUpon::restoreScreen(ScreenBackup &backup) { + if (_vm->shouldQuit()) + return; + + // Restore the screen + _vm->_draw->_backSurface->blit(*backup.screen); + _vm->_draw->forceBlit(); + + // Restore the palette + if (backup.palette >= 0) + setGamePalette(backup.palette); + + // Restore the cursor + + if (!backup.cursorVisible) + hideCursor(); + + if (backup.changedCursor) + removeCursor(); + + backup.changedCursor = false; +} + void OnceUpon::fixTXTStrings(TXTFile &txt) const { TXTFile::LineArray &lines = txt.getLines(); for (uint i = 0; i < lines.size(); i++) @@ -251,18 +362,22 @@ enum CopyProtectionState { bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]) { fadeOut(); - setCopyProtectionPalette(); + setPalette(kCopyProtectionPalette, kPaletteSize); + // Load the copy protection sprites Surface sprites[2] = {Surface(320, 200, 1), Surface(320, 200, 1)}; _vm->_video->drawPackedSprite("grille1.cmp", sprites[0]); _vm->_video->drawPackedSprite("grille2.cmp", sprites[1]); + // Load the clown animation ANIFile ani (_vm, "grille.ani", 320); ANIObject clown(ani); + // Set the copy protection cursor setCursor(sprites[1], 5, 110, 20, 134, 3, 0); + // We start with 2 tries left, not having a correct answer and the copy protection not set up yet CopyProtectionState state = kCPStateSetup; uint8 triesLeft = 2; @@ -423,31 +538,6 @@ void OnceUpon::cpWrong() { clearScreen(); } -void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const { - ani.setAnimation(state); - ani.setMode(once ? ANIObject::kModeOnce : ANIObject::kModeContinuous); - ani.setPause(pause); - ani.setVisible(true); - ani.setPosition(); -} - -void OnceUpon::showWait(uint palette) { - // Show the loading floppy - - fadeOut(); - clearScreen(); - setGamePalette(palette); - - Surface wait(320, 43, 1); - - _vm->_video->drawPackedSprite("wait.cmp", wait); - _vm->_draw->_backSurface->blit(wait, 0, 0, 72, 33, 122, 84); - - _vm->_draw->forceBlit(); - - fadeIn(); -} - void OnceUpon::showIntro() { // Show all intro parts @@ -475,6 +565,23 @@ void OnceUpon::showIntro() { showWait(17); } +void OnceUpon::showWait(uint palette) { + // Show the loading floppy + + fadeOut(); + clearScreen(); + setGamePalette(palette); + + Surface wait(320, 43, 1); + + _vm->_video->drawPackedSprite("wait.cmp", wait); + _vm->_draw->_backSurface->blit(wait, 0, 0, 72, 33, 122, 84); + + _vm->_draw->forceBlit(); + + fadeIn(); +} + void OnceUpon::showQuote() { // Show the quote about fairytales @@ -534,6 +641,8 @@ void OnceUpon::showTitle() { } void OnceUpon::playTitleMusic() { + // Look at what platform this is and play the appropriate music type + if (_vm->getPlatform() == Common::kPlatformPC) playTitleMusicDOS(); else if (_vm->getPlatform() == Common::kPlatformAmiga) @@ -571,6 +680,8 @@ void OnceUpon::playTitleMusicAtariST() { } void OnceUpon::stopTitleMusic() { + // Just stop everything + _vm->_sound->adlibSetRepeating(0); _vm->_sound->blasterRepeatComposition(0); @@ -625,55 +736,29 @@ void OnceUpon::showByeBye() { fadeOut(); } -OnceUpon::MenuAction OnceUpon::doMenu(MenuType type) { - bool cursorVisible = isCursorVisible(); - - // Set the cursor - addCursor(); - setGameCursor(); - - // Backup the screen - Surface screenBackup(320, 200, 1); - screenBackup.blit(*_vm->_draw->_backSurface); - - // Handle the specific menu - MenuAction action; - if (type == kMenuTypeMainStart) - action = doMenuMainStart(); - else if (type == kMenuTypeMainIngame) - action = doMenuMainIngame(); - else if (type == kMenuTypeIngame) - action = doMenuIngame(); - else - error("OnceUpon::doMenu(): No such menu %d", type); - - if (_vm->shouldQuit()) - return action; - - // The ingame menu cleans itself up in a special way - if (type == kMenuTypeIngame) - clearMenuIngame(screenBackup); - - // The main menus fade out - if ((type == kMenuTypeMainStart) || (type == kMenuTypeMainIngame)) - fadeOut(); - - // Restore the screen - _vm->_draw->_backSurface->blit(screenBackup); - _vm->_draw->forceBlit(); +void OnceUpon::doStartMenu(const MenuButton *animalsButton, uint animalCount, + const MenuButton *animalButtons, const char * const *animalNames) { + clearScreen(); - // Restore the cursor - if (!cursorVisible) - hideCursor(); - removeCursor(); + // Wait until we clicked on of the difficulty buttons and are ready to start playing + while (!_vm->shouldQuit()) { + MenuAction action = handleStartMenu(animalsButton); + if (action == kMenuActionPlay) + break; - return action; + // If we pressed the "listen to animal names" button, handle that screen + if (action == kMenuActionAnimals) + handleAnimalNames(animalCount, animalButtons, animalNames); + } } -OnceUpon::MenuAction OnceUpon::doMenuMainStart() { +OnceUpon::MenuAction OnceUpon::handleStartMenu(const MenuButton *animalsButton) { + ScreenBackup screenBackup; + backupScreen(screenBackup, true); + fadeOut(); setGamePalette(17); - drawMenuMainStart(); + drawStartMenu(animalsButton); showCursor(); fadeIn(); @@ -702,22 +787,28 @@ OnceUpon::MenuAction OnceUpon::doMenuMainStart() { _difficulty = (Difficulty)diff; action = kMenuActionPlay; - drawMenuMainStart(); + drawStartMenu(animalsButton); _vm->_util->longDelay(1000); } - if (_animalsButton && (checkButton(_animalsButton, 1, mouseX, mouseY) != -1)) + if (animalsButton && (checkButton(animalsButton, 1, mouseX, mouseY) != -1)) action = kMenuActionAnimals; } + fadeOut(); + restoreScreen(screenBackup); + return action; } -OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { +OnceUpon::MenuAction OnceUpon::handleMainMenu() { + ScreenBackup screenBackup; + backupScreen(screenBackup, true); + fadeOut(); setGamePalette(17); - drawMenuMainIngame(); + drawMainMenu(); showCursor(); fadeIn(); @@ -745,7 +836,7 @@ OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { if ((diff >= 0) && (diff != (int)_difficulty)) { _difficulty = (Difficulty)diff; - drawMenuMainIngame(); + drawMainMenu(); } // If we clicked on a section button, restart the game from this section @@ -757,11 +848,17 @@ OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { } + fadeOut(); + restoreScreen(screenBackup); + return action; } -OnceUpon::MenuAction OnceUpon::doMenuIngame() { - drawMenuIngame(); +OnceUpon::MenuAction OnceUpon::handleIngameMenu() { + ScreenBackup screenBackup; + backupScreen(screenBackup, true); + + drawIngameMenu(); showCursor(); MenuAction action = kMenuActionNone; @@ -791,20 +888,23 @@ OnceUpon::MenuAction OnceUpon::doMenuIngame() { } + clearIngameMenu(*screenBackup.screen); + restoreScreen(screenBackup); + return action; } -void OnceUpon::drawMenuMainStart() { +void OnceUpon::drawStartMenu(const MenuButton *animalsButton) { // Draw the background _vm->_video->drawPackedSprite("menu2.cmp", *_vm->_draw->_backSurface); // Draw the "Listen to animal names" button - if (_animalsButton) { + if (animalsButton) { Surface elements(320, 38, 1); _vm->_video->drawPackedSprite("elemenu.cmp", elements); - _vm->_draw->_backSurface->fillRect(_animalsButton->left , _animalsButton->top, - _animalsButton->right, _animalsButton->bottom, 0); - drawButton(*_vm->_draw->_backSurface, elements, *_animalsButton); + _vm->_draw->_backSurface->fillRect(animalsButton->left , animalsButton->top, + animalsButton->right, animalsButton->bottom, 0); + drawButton(*_vm->_draw->_backSurface, elements, *animalsButton); } // Highlight the current difficulty @@ -813,7 +913,7 @@ void OnceUpon::drawMenuMainStart() { _vm->_draw->forceBlit(); } -void OnceUpon::drawMenuMainIngame() { +void OnceUpon::drawMainMenu() { // Draw the background _vm->_video->drawPackedSprite("menu.cmp", *_vm->_draw->_backSurface); @@ -837,11 +937,11 @@ void OnceUpon::drawMenuMainIngame() { _vm->_draw->forceBlit(); } -void OnceUpon::drawMenuIngame() { +void OnceUpon::drawIngameMenu() { Surface menu(320, 34, 1); _vm->_video->drawPackedSprite("icon.cmp", menu); - // Draw the menu in a special way + // Draw the menu in a special way, button by button for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) { const MenuButton &button = kIngameButtons[i]; @@ -863,16 +963,15 @@ void OnceUpon::drawMenuDifficulty() { difficulties->draw((uint) _difficulty, *_vm->_draw->_backSurface, &_plettre, 1); // Draw a border around the current difficulty - _vm->_draw->_backSurface->drawRect(kMainMenuDifficultyButton[_difficulty].left, - kMainMenuDifficultyButton[_difficulty].top, - kMainMenuDifficultyButton[_difficulty].right, - kMainMenuDifficultyButton[_difficulty].bottom, - difficulties->getLines()[_difficulty].color); + drawButtonBorder(kMainMenuDifficultyButton[_difficulty], difficulties->getLines()[_difficulty].color); delete difficulties; } -void OnceUpon::clearMenuIngame(const Surface &background) { +void OnceUpon::clearIngameMenu(const Surface &background) { + if (_vm->shouldQuit()) + return; + // Find the area encompassing the whole ingame menu int16 left = 0x7FFF; @@ -900,6 +999,8 @@ void OnceUpon::clearMenuIngame(const Surface &background) { } int OnceUpon::checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue) const { + // Look through all buttons, and return the ID of the button we're in + for (uint i = 0; i < count; i++) { const MenuButton &button = buttons[i]; @@ -907,6 +1008,7 @@ int OnceUpon::checkButton(const MenuButton *buttons, uint count, int16 x, int16 return (int)button.id; } + // We're in none of these buttons, return the fail value return failValue; } @@ -931,12 +1033,12 @@ void OnceUpon::drawButtonBorder(const MenuButton &button, uint8 color) { } enum AnimalNamesState { - kANStateChoose, - kANStateNames, - kANStateFinish + kANStateChoose, // We're in the animal chooser + kANStateNames, // We're in the language chooser + kANStateFinish // We're finished }; -void OnceUpon::doAnimalNames(uint count, const MenuButton *buttons, const char * const *names) { +void OnceUpon::handleAnimalNames(uint count, const MenuButton *buttons, const char * const *names) { fadeOut(); clearScreen(); setGamePalette(19); @@ -1100,45 +1202,8 @@ void OnceUpon::anPlayAnimalName(const Common::String &animal, uint language) { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 78, 123, 239, 145); } -void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, - int16 x, int16 y) const { - - // A special way of drawing something: - // Draw every other line "downwards", wait a bit after each line - // Then, draw the remaining lines "upwards" and again wait a bit after each line. - - if (_vm->shouldQuit()) - return; - - const int16 width = right - left + 1; - const int16 height = bottom - top + 1; - - if ((width <= 0) || (height <= 0)) - return; - - for (int16 i = 0; i < height; i += 2) { - if (_vm->shouldQuit()) - return; - - _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); - - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); - _vm->_draw->blitInvalidated(); - - _vm->_util->longDelay(1); - } - - for (int16 i = (height & 1) ? height : (height - 1); i >= 0; i -= 2) { - if (_vm->shouldQuit()) - return; - - _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); - - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); - _vm->_draw->blitInvalidated(); - - _vm->_util->longDelay(1); - } +void OnceUpon::playGame() { + warning("OnceUpon::playGame(): TODO"); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 6f8b67a627..08c8803c67 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -38,18 +38,67 @@ namespace OnceUpon { class OnceUpon : public PreGob { public: + /** Number of languages we support. */ static const uint kLanguageCount = 5; + OnceUpon(GobEngine *vm); ~OnceUpon(); + protected: - enum MenuType { - kMenuTypeMainStart = 0, ///< The big main menu at game start. - kMenuTypeMainIngame, ///< The big main menu during the game. - kMenuTypeIngame ///< The small popup menu during the game. + /** A description of a menu button. */ + struct MenuButton { + bool needDraw; ///< Does the button need drawing? + + int16 left; ///< Left coordinate of the button. + int16 top; ///< Top coordinate of the button. + int16 right; ///< Right coordinate of the button. + int16 bottom; ///< Bottom coordinate of the button. + + int16 srcLeft; ///< Left coordinate of the button's sprite. + int16 srcTop; ///< Top coordinate of the button's sprite. + int16 srcRight; ///< Right coordinate of the button's sprite. + int16 srcBottom; ///< Right coordinate of the button's sprite. + + int16 dstX; ///< Destination X coordinate of the button's sprite. + int16 dstY; ///< Destination Y coordinate of the button's sprite. + + uint id; ///< The button's ID. }; + + void init(); + void deinit(); + + /** Handle the copy protection. + * + * @param colors Colors the copy protection animals can be. + * @param shapes The shape that's the correct answer for each animal in each color. + * @param obfuscate Extra obfuscate table. correctShape = shapes[colors][obfuscate[animal]]. + * @return true if the user guessed the correct shape, false otherwise. + */ + bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); + + /** Show the intro. */ + void showIntro(); + + /** Handle the start menu. + * + * @param animalsButton Definition of the menu button that leads to the animal names screen. Can be 0. + * @param animalCount Number of animals in the animal names screen. + * @param animalButtons Definition of the buttons that make up the animals in the animal names screen. + * @param animalNames File prefixes for the name of each animal. + */ + void doStartMenu(const MenuButton *animalsButton, uint animalCount, + const MenuButton *animalButtons, const char * const *animalNames); + + /** Play the game proper. */ + void playGame(); + + +private: + /** All actions a user can request in a menu. */ enum MenuAction { kMenuActionNone = 0, ///< No action. kMenuActionAnimals , ///< Do the animal names. @@ -59,6 +108,7 @@ protected: kMenuActionQuit ///< Quit the game. }; + /** Difficulty levels. */ enum Difficulty { kDifficultyBeginner = 0, kDifficultyIntermediate = 1, @@ -66,115 +116,148 @@ protected: kDifficultyMAX }; + /** The different sounds common in the game. */ enum Sound { kSoundClick = 0, kSoundMAX }; - struct MenuButton { - bool needDraw; - int16 left, top, right, bottom; - int16 srcLeft, srcTop, srcRight, srcBottom; - int16 dstX, dstY; - uint id; - }; + /** A complete screen backup. */ + struct ScreenBackup { + Surface *screen; ///< Screen contents. + int palette; ///< Screen palette. - static const uint kSectionCount = 15; + bool changedCursor; ///< Did we change the cursor? + bool cursorVisible; ///< Was the cursor visible? + ScreenBackup(); + ~ScreenBackup(); + }; - void init(); - void deinit(); - void setAnimalsButton(const MenuButton *animalsButton); + /** The number of game sections. */ + static const uint kSectionCount = 15; - void setGamePalette(uint palette); - void setGameCursor(); + static const MenuButton kMainMenuDifficultyButton[]; ///< Difficulty buttons. + static const MenuButton kSectionButtons[]; ///< Section buttons. - Common::String fixString(const Common::String &str) const; - void fixTXTStrings(TXTFile &txt) const; + static const MenuButton kIngameButtons[]; ///< Ingame menu buttons. - bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); + static const MenuButton kAnimalNamesBack; ///< "Back" button in the animal names screens. + static const MenuButton kLanguageButtons[]; ///< Language buttons in the animal names screen. - void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen. - void showIntro(); ///< Show the whole intro. + /** All general game sounds we know about. */ + static const char *kSound[kSoundMAX]; - void showChapter(int chapter); ///< Show a chapter intro text. - void showByeBye(); ///< Show the "bye bye" screen + // -- General helpers -- - MenuAction doMenu(MenuType type); + void setGamePalette(uint palette); ///< Set a game palette. + void setGameCursor(); ///< Set the default game cursor. - void doAnimalNames(uint count, const MenuButton *buttons, const char * const *names); + /** Set the state of an ANIObject. */ + void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; + /** Draw this sprite in a fancy, animated line-by-line way. */ void drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y) const; + /** Backup the screen contents. */ + void backupScreen(ScreenBackup &backup, bool setDefaultCursor = false); + /** Restore the screen contents with a previously made backup. */ + void restoreScreen(ScreenBackup &backup); - // Fonts - Font *_jeudak; - Font *_lettre; - Font *_plettre; - Font *_glettre; + Common::String fixString(const Common::String &str) const; ///< Fix a string if necessary. + void fixTXTStrings(TXTFile &txt) const; ///< Fix all strings in a TXT. - Difficulty _difficulty; - uint8 _section; -private: - static const MenuButton kMainMenuDifficultyButton[]; - static const MenuButton kSectionButtons[]; - static const MenuButton kIngameButtons[]; + // -- Copy protection helpers -- - static const MenuButton kAnimalNamesBack; - static const MenuButton kLanguageButtons[]; + /** Set up the copy protection. */ + int8 cpSetup(const uint8 colors[7], const uint8 shapes[7 * 20], + const uint8 obfuscate[4], const Surface sprites[2]); + /** Find the shape under these coordinates. */ + int8 cpFindShape(int16 x, int16 y) const; + /** Display the "You are wrong" screen. */ + void cpWrong(); - static const char *kSound[kSoundMAX]; + // -- Show different game screens -- - void setCopyProtectionPalette(); + void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen. + void showQuote(); ///< Show the quote about fairytales. + void showTitle(); ///< Show the Once Upon A Time title. + void showChapter(int chapter); ///< Show a chapter intro text. + void showByeBye(); ///< Show the "bye bye" screen. - void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; + /** Handle the "listen to animal names" part. */ + void handleAnimalNames(uint count, const MenuButton *buttons, const char * const *names); - // Copy protection helpers - int8 cpSetup(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4], const Surface sprites[2]); - int8 cpFindShape(int16 x, int16 y) const; - void cpWrong(); - // Intro parts - void showQuote(); - void showTitle(); - - // Title music - void playTitleMusic(); - void playTitleMusicDOS(); - void playTitleMusicAmiga(); - void playTitleMusicAtariST(); - void stopTitleMusic(); - - // Menu helpers - MenuAction doMenuMainStart(); - MenuAction doMenuMainIngame(); - MenuAction doMenuIngame(); - - void drawMenuMainStart(); - void drawMenuMainIngame(); - void drawMenuIngame(); + // -- Title music helpers -- + + void playTitleMusic(); ///< Play the title music. + void playTitleMusicDOS(); ///< Play the title music of the DOS version. + void playTitleMusicAmiga(); ///< Play the title music of the Amiga version. + void playTitleMusicAtariST(); ///< Play the title music of the Atari ST version. + void stopTitleMusic(); ///< Stop the title music. + + + // -- Menu helpers -- + + MenuAction handleStartMenu(const MenuButton *animalsButton); ///< Handle the start menu. + MenuAction handleMainMenu(); ///< Handle the main menu. + MenuAction handleIngameMenu(); ///< Handle the ingame menu. + + void drawStartMenu(const MenuButton *animalsButton); ///< Draw the start menu. + void drawMainMenu(); ///< Draw the main menu. + void drawIngameMenu(); ///< Draw the ingame menu. + + /** Draw the difficulty label. */ void drawMenuDifficulty(); - void clearMenuIngame(const Surface &background); + /** Clear the ingame menu in an animated way. */ + void clearIngameMenu(const Surface &background); + + // -- Menu button helpers -- + + /** Find the button under these coordinates. */ int checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue = -1) const; - void drawButton(Surface &dest, const Surface &src, const MenuButton &button) const; + + /** Draw a menu button. */ + void drawButton (Surface &dest, const Surface &src, const MenuButton &button) const; + /** Draw multiple menu buttons. */ void drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count) const; + + /** Draw a border around a button. */ void drawButtonBorder(const MenuButton &button, uint8 color); - // Animal names helpers + + // -- Animal names helpers -- + + /** Set up the animal chooser. */ void anSetupChooser(); + /** Set up the language chooser for one animal. */ void anSetupNames(const MenuButton &animal); + /** Play / Display the name of an animal in one language. */ void anPlayAnimalName(const Common::String &animal, uint language); + + /** Did we open the game archives? */ bool _openedArchives; - const MenuButton *_animalsButton; + // Fonts + Font *_jeudak; + Font *_lettre; + Font *_plettre; + Font *_glettre; + + /** The current palette. */ + int _palette; + + Difficulty _difficulty; ///< The current difficulty. + uint8 _section; ///< The current game section. }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index a1a3d65a58..e62a59042b 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -51,7 +51,10 @@ protected: static const char *kLanguageSuffixLong [5]; - void initScreen(); ///< Initialize the game screen. + // -- Graphics -- + + /** Initialize the game screen. */ + void initScreen(); void fadeOut(); ///< Fade to black. void fadeIn(); ///< Fade to the current palette. @@ -65,51 +68,86 @@ protected: */ void setPalette(const byte *palette, uint16 size); ///< Change the palette + /** Add a new cursor that can be manipulated to the stack. */ void addCursor(); + /** Remove the top-most cursor from the stack. */ void removeCursor(); + /** Set the current cursor. */ void setCursor(Surface &sprite, int16 hotspotX, int16 hotspotY); + /** Set the current cursor. */ void setCursor(Surface &sprite, int16 left, int16 top, int16 right, int16 bottom, int16 hotspotX, int16 hotspotY); + /** Show the cursor. */ void showCursor(); + /** Hide the cursor. */ void hideCursor(); + /** Is the cursor currently visible? */ bool isCursorVisible() const; + /** Remove an animation from the screen. */ + void clearAnim(ANIObject &ani); + /** Draw an animation to the screen, advancing it. */ + void drawAnim(ANIObject &ani); + /** Clear and draw an animation to the screen, advancing it. */ + void redrawAnim(ANIObject &ani); + + /** Wait for the frame to end, handling screen updates and optionally update input. */ + void endFrame(bool doInput); + + + // -- Sound -- + + /** Load all sounds that can be played interactively in the game. */ void loadSounds(const char * const *sounds, uint soundCount); + /** Free all loaded sound. */ void freeSounds(); + /** Play a loaded sound. */ void playSound(uint sound, int16 frequency = 0, int16 repCount = 0); + /** Stop all sound playback. */ void stopSound(); + /** Play a sound until it ends or is interrupted by a keypress. */ void playSoundFile(const Common::String &file, int16 frequency = 0, int16 repCount = 0, bool interruptible = true); - void endFrame(bool doInput); + // -- Input -- + + /** Check mouse and keyboard input. */ int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + /** Wait for mouse or keyboard input. */ int16 waitInput (int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + /** Wait for mouse or keyboard input, but don't care about what was done with the mouse. */ int16 waitInput(); + /** Did we have mouse or keyboard input? */ bool hasInput(); - void clearAnim(ANIObject &ani); - void drawAnim(ANIObject &ani); - void redrawAnim(ANIObject &ani); + // -- TXT helpers -- + + /** Get the name of a localized file. */ Common::String getLocFile(const Common::String &file) const; + /** Open a TXT file. */ TXTFile *loadTXT(const Common::String &txtFile, TXTFile::Format format) const; + /** Called by loadTXT() to fix strings within the TXT file. */ virtual void fixTXTStrings(TXTFile &txt) const; GobEngine *_vm; private: + /** Load a sound file. */ bool loadSound(SoundDesc &sound, const Common::String &file) const; - bool _fadedOut; ///< Did we fade out? + /** Did we fade out? */ + bool _fadedOut; + /** All loaded sounds. */ Common::Array _sounds; }; -- cgit v1.2.3