GOB: Reorganize and clean up PreGob / Once Upon A Time

This commit is contained in:
Sven Hesse 2012-07-02 04:18:12 +02:00
parent 24644c0012
commit 305ab6847a
7 changed files with 451 additions and 297 deletions

View File

@ -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();
// Handle the start menu
doStartMenu(&kAnimalsButtons, ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames);
if (_vm->shouldQuit())
return;
if (!_vm->shouldQuit())
showByeBye();
}
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

View File

@ -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

View File

@ -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();
// Handle the start menu
doStartMenu(&kAnimalsButtons, ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames);
if (_vm->shouldQuit())
return;
if (!_vm->shouldQuit())
showByeBye();
}
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

View File

@ -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

View File

@ -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();
void OnceUpon::doStartMenu(const MenuButton *animalsButton, uint animalCount,
const MenuButton *animalButtons, const char * const *animalNames) {
clearScreen();
// Set the cursor
addCursor();
setGameCursor();
// 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;
// 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();
// Restore the cursor
if (!cursorVisible)
hideCursor();
removeCursor();
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

View File

@ -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,49 +116,136 @@ 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.
bool changedCursor; ///< Did we change the cursor?
bool cursorVisible; ///< Was the cursor visible?
ScreenBackup();
~ScreenBackup();
};
/** The number of game sections. */
static const uint kSectionCount = 15;
static const MenuButton kMainMenuDifficultyButton[]; ///< Difficulty buttons.
static const MenuButton kSectionButtons[]; ///< Section buttons.
void init();
void deinit();
static const MenuButton kIngameButtons[]; ///< Ingame menu buttons.
void setAnimalsButton(const MenuButton *animalsButton);
static const MenuButton kAnimalNamesBack; ///< "Back" button in the animal names screens.
static const MenuButton kLanguageButtons[]; ///< Language buttons in the animal names screen.
void setGamePalette(uint palette);
void setGameCursor();
/** All general game sounds we know about. */
static const char *kSound[kSoundMAX];
Common::String fixString(const Common::String &str) const;
void fixTXTStrings(TXTFile &txt) const;
bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]);
// -- General helpers --
void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen.
void showIntro(); ///< Show the whole intro.
void setGamePalette(uint palette); ///< Set a game palette.
void setGameCursor(); ///< Set the default game cursor.
void showChapter(int chapter); ///< Show a chapter intro text.
void showByeBye(); ///< Show the "bye bye" screen
MenuAction doMenu(MenuType type);
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);
Common::String fixString(const Common::String &str) const; ///< Fix a string if necessary.
void fixTXTStrings(TXTFile &txt) const; ///< Fix all strings in a TXT.
// -- Copy protection helpers --
/** 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();
// -- Show different game screens --
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.
/** Handle the "listen to animal names" part. */
void handleAnimalNames(uint count, const MenuButton *buttons, const char * const *names);
// -- 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();
/** 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;
/** 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 --
/** 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;
// Fonts
Font *_jeudak;
@ -116,65 +253,11 @@ protected:
Font *_plettre;
Font *_glettre;
Difficulty _difficulty;
uint8 _section;
/** The current palette. */
int _palette;
private:
static const MenuButton kMainMenuDifficultyButton[];
static const MenuButton kSectionButtons[];
static const MenuButton kIngameButtons[];
static const MenuButton kAnimalNamesBack;
static const MenuButton kLanguageButtons[];
static const char *kSound[kSoundMAX];
void setCopyProtectionPalette();
void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const;
// 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();
void drawMenuDifficulty();
void clearMenuIngame(const Surface &background);
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;
void drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count) const;
void drawButtonBorder(const MenuButton &button, uint8 color);
// Animal names helpers
void anSetupChooser();
void anSetupNames(const MenuButton &animal);
void anPlayAnimalName(const Common::String &animal, uint language);
bool _openedArchives;
const MenuButton *_animalsButton;
Difficulty _difficulty; ///< The current difficulty.
uint8 _section; ///< The current game section.
};
} // End of namespace OnceUpon

View File

@ -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;
void loadSounds(const char * const *sounds, uint soundCount);
void freeSounds();
void playSound(uint sound, int16 frequency = 0, int16 repCount = 0);
void stopSound();
void playSoundFile(const Common::String &file, int16 frequency = 0, int16 repCount = 0, bool interruptible = true);
void endFrame(bool doInput);
int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons);
int16 waitInput (int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons);
int16 waitInput();
bool hasInput();
/** 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);
// -- 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();
// -- 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<SoundDesc> _sounds;
};