aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/pregob/onceupon/onceupon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/pregob/onceupon/onceupon.cpp')
-rw-r--r--engines/gob/pregob/onceupon/onceupon.cpp355
1 files changed, 210 insertions, 145 deletions
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