mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-26 20:59:00 +00:00
GOB: Reorganize and clean up PreGob / Once Upon A Time
This commit is contained in:
parent
24644c0012
commit
305ab6847a
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user