aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/gui_ns.cpp
diff options
context:
space:
mode:
authorNicola Mettifogo2008-07-24 09:24:32 +0000
committerNicola Mettifogo2008-07-24 09:24:32 +0000
commit4936e5f7df8e2257b1af4ee3ab2fdcd8cb88e91b (patch)
tree80b4cb2cc25b29421920f062c39de6752ae63646 /engines/parallaction/gui_ns.cpp
parent69dac1d4f22f9a63a5a9030d4405ba071e5e8b89 (diff)
downloadscummvm-rg350-4936e5f7df8e2257b1af4ee3ab2fdcd8cb88e91b.tar.gz
scummvm-rg350-4936e5f7df8e2257b1af4ee3ab2fdcd8cb88e91b.tar.bz2
scummvm-rg350-4936e5f7df8e2257b1af4ee3ab2fdcd8cb88e91b.zip
* Moved end intro and end game sequences code to gui.
* Rewrote all gui code to be run inside the main loop * Added code to avoid crashes when a scene with no standard background is drawn svn-id: r33260
Diffstat (limited to 'engines/parallaction/gui_ns.cpp')
-rw-r--r--engines/parallaction/gui_ns.cpp1037
1 files changed, 727 insertions, 310 deletions
diff --git a/engines/parallaction/gui_ns.cpp b/engines/parallaction/gui_ns.cpp
index 6068a6a0dd..258463bbbe 100644
--- a/engines/parallaction/gui_ns.cpp
+++ b/engines/parallaction/gui_ns.cpp
@@ -24,6 +24,7 @@
*/
#include "common/system.h"
+#include "common/hashmap.h"
#include "parallaction/input.h"
#include "parallaction/parallaction.h"
@@ -32,318 +33,633 @@
namespace Parallaction {
-const char *introMsg1[] = {
- "INSERISCI IL CODICE",
- "ENTREZ CODE",
- "ENTER CODE",
- "GIB DEN KODE EIN"
-};
-const char *introMsg2[] = {
- "CODICE ERRATO",
- "CODE ERRONE",
- "WRONG CODE",
- "GIB DEN KODE EIN"
-};
+class MenuInputState;
-const char *introMsg3[] = {
- "PRESS LEFT MOUSE BUTTON",
- "TO SEE INTRO",
- "PRESS RIGHT MOUSE BUTTON",
- "TO START"
-};
+class MenuInputHelper {
+ typedef Common::HashMap<Common::String, MenuInputState*> StateMap;
-const char *newGameMsg[] = {
- "NUOVO GIOCO",
- "NEUF JEU",
- "NEW GAME",
- "NEUES SPIEL"
-};
+ StateMap _map;
+ MenuInputState *_state;
+ MenuInputState *_newState;
-const char *loadGameMsg[] = {
- "GIOCO SALVATO",
- "JEU SAUVE'",
- "SAVED GAME",
- "SPIEL GESPEICHERT"
-};
+public:
+ MenuInputHelper() : _state(0) {
+ }
+ ~MenuInputHelper();
-#define BLOCK_WIDTH 16
-#define BLOCK_HEIGHT 24
+ void setState(const Common::String &name) {
+ // bootstrap routine
+ _newState = getState(name);
+ assert(_newState);
+ }
-#define BLOCK_X 112
-#define BLOCK_Y 130
+ void addState(const Common::String &name, MenuInputState *state) {
+ _map.setVal(name, state);
+ }
-#define BLOCK_SELECTION_X (BLOCK_X-1)
-#define BLOCK_SELECTION_Y (BLOCK_Y-1)
+ MenuInputState *getState(const Common::String &name) {
+ return _map[name];
+ }
-#define BLOCK_X_OFFSET (BLOCK_WIDTH+1)
-#define BLOCK_Y_OFFSET 9
+ bool run();
+};
-// destination slots for code blocks
-//
-#define SLOT_X 61
-#define SLOT_Y 64
-#define SLOT_WIDTH (BLOCK_WIDTH+2)
+class MenuInputState {
-#define PASSWORD_LEN 6
+protected:
+ MenuInputHelper *_helper;
-#define CHAR_DINO 0
-#define CHAR_DONNA 1
-#define CHAR_DOUGH 2
+public:
+ MenuInputState(const Common::String &name, MenuInputHelper *helper) : _helper(helper), _name(name) {
+ debugC(3, kDebugExec, "MenuInputState(%s)", name.c_str());
+ _helper->addState(name, this);
+ }
-static const uint16 _amigaKeys[][PASSWORD_LEN] = {
- { 5, 3, 6, 2, 2, 7 }, // dino
- { 0, 3, 6, 2, 2, 6 }, // donna
- { 1, 3 ,7, 2, 4, 6 } // dough
-};
+ Common::String _name;
-static const uint16 _pcKeys[][PASSWORD_LEN] = {
- { 5, 3, 6, 1, 4, 7 }, // dino
- { 0, 2, 8, 5, 5, 1 }, // donna
- { 1, 7 ,7, 2, 2, 6 } // dough
-};
+ virtual ~MenuInputState() { }
-static const char *_charStartLocation[] = {
- "test.dino",
- "test.donna",
- "test.dough"
+ virtual MenuInputState* run() = 0;
+ virtual void enter() = 0;
};
-enum {
- NEW_GAME,
- LOAD_GAME
-};
+bool MenuInputHelper::run() {
+ if (_newState == 0) {
+ debugC(3, kDebugExec, "MenuInputHelper has set NULL state");
+ return false;
+ }
-enum {
- START_DEMO,
- START_INTRO,
- GAME_LOADED,
- SELECT_CHARACTER
-};
+ if (_newState != _state) {
+ debugC(3, kDebugExec, "MenuInputHelper changing state to '%s'", _newState->_name.c_str());
-void Parallaction_ns::guiStart() {
+ _newState->enter();
+ _state = _newState;
+ }
- _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1");
+ _newState = _state->run();
- guiSplash();
+ return true;
+}
- _language = guiChooseLanguage();
- _disk->setLanguage(_language);
+MenuInputHelper::~MenuInputHelper() {
+ StateMap::iterator b = _map.begin();
+ for ( ; b != _map.end(); b++) {
+ delete b->_value;
+ }
+ _map.clear();
+}
- int event;
- if (getFeatures() & GF_DEMO) {
- event = START_DEMO;
- } else {
- if (guiSelectGame() == NEW_GAME) {
- event = guiNewGame();
- } else {
- event = loadGame() ? GAME_LOADED : START_INTRO;
+class SplashInputState : public MenuInputState {
+protected:
+ Common::String _slideName;
+ uint32 _timeOut;
+ Common::String _nextState;
+ uint32 _startTime;
+
+ Parallaction_ns *_vm;
+
+public:
+ SplashInputState(Parallaction_ns *vm, const Common::String &name, MenuInputHelper *helper) : MenuInputState(name, helper), _vm(vm) {
+ }
+
+ virtual MenuInputState* run() {
+ uint32 curTime = g_system->getMillis();
+ if (curTime - _startTime > _timeOut) {
+ _vm->freeBackground();
+ return _helper->getState(_nextState);
}
+ return this;
}
- switch (event) {
- case START_DEMO:
- strcpy(_location._name, "fognedemo.dough");
- break;
+ virtual void enter() {
+ _vm->showSlide(_slideName.c_str());
+ _startTime = g_system->getMillis();
+ }
+};
- case START_INTRO:
- strcpy(_location._name, "fogne.dough");
- break;
+class SplashInputState0 : public SplashInputState {
- case GAME_LOADED:
- // nothing to do here
- return;
+public:
+ SplashInputState0(Parallaction_ns *vm, MenuInputHelper *helper) : SplashInputState(vm, "intro0", helper) {
+ _slideName = "intro";
+ _timeOut = 2000;
+ _nextState = "intro1";
+ }
+};
- case SELECT_CHARACTER:
- selectStartLocation();
- break;
+class SplashInputState1 : public SplashInputState {
+public:
+ SplashInputState1(Parallaction_ns *vm, MenuInputHelper *helper) : SplashInputState(vm, "intro1", helper) {
+ _slideName = "minintro";
+ _timeOut = 2000;
+ _nextState = "chooselanguage";
}
+};
- return;
-}
-void Parallaction_ns::selectStartLocation() {
- _inTestResult = false;
+class ChooseLanguageInputState : public MenuInputState {
+ #define BLOCK_WIDTH 16
+ #define BLOCK_HEIGHT 24
- int character = guiSelectCharacter();
- if (character == -1)
- error("invalid character selected from menu screen");
+ #define BLOCK_X 112
+ #define BLOCK_Y 130
- scheduleLocationSwitch(_charStartLocation[character]);
-}
+ #define BLOCK_SELECTION_X (BLOCK_X-1)
+ #define BLOCK_SELECTION_Y (BLOCK_Y-1)
+ #define BLOCK_X_OFFSET (BLOCK_WIDTH+1)
+ #define BLOCK_Y_OFFSET 9
-void Parallaction_ns::guiSplash() {
+ // destination slots for code blocks
+ //
+ #define SLOT_X 61
+ #define SLOT_Y 64
+ #define SLOT_WIDTH (BLOCK_WIDTH+2)
- showSlide("intro");
- _gfx->updateScreen();
- g_system->delayMillis(2000);
- freeBackground();
+ int _language;
+ bool _allowChoice;
+ Common::String _nextState;
- showSlide("minintro");
- _gfx->updateScreen();
- g_system->delayMillis(2000);
- freeBackground();
-}
+ static const Common::Rect _dosLanguageSelectBlocks[4];
+ static const Common::Rect _amigaLanguageSelectBlocks[4];
+ const Common::Rect *_blocks;
-int Parallaction_ns::guiNewGame() {
+ Parallaction_ns *_vm;
+
+public:
+ ChooseLanguageInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("chooselanguage", helper), _vm(vm) {
+ _allowChoice = false;
+ _nextState = "selectgame";
+
+ if (_vm->getPlatform() == Common::kPlatformAmiga) {
+ if (!(_vm->getFeatures() & GF_LANG_MULT)) {
+ if (_vm->getFeatures() & GF_DEMO) {
+ _language = 1; // Amiga Demo supports English
+ _nextState = "startdemo";
+ return;
+ } else {
+ _language = 0; // The only other non multi-lingual version just supports Italian
+ return;
+ }
+ }
- const char **v14 = introMsg3;
+ _blocks = _amigaLanguageSelectBlocks;
+ } else {
+ _blocks = _dosLanguageSelectBlocks;
+ }
- _disk->selectArchive("disk1");
+ _language = -1;
+ _allowChoice = true;
+ }
- setBackground("test", NULL, NULL);
+ virtual MenuInputState* run() {
+ if (!_allowChoice) {
+ _vm->setInternLanguage(_language);
+ return _helper->getState(_nextState);
+ }
- _gfx->updateScreen();
+ int event = _vm->_input->getLastButtonEvent();
+ if (event != kMouseLeftUp) {
+ return this;
+ }
- uint id[4];
- id[0] = _gfx->createLabel(_menuFont, v14[0], 1);
- id[1] = _gfx->createLabel(_menuFont, v14[1], 1);
- id[2] = _gfx->createLabel(_menuFont, v14[2], 1);
- id[3] = _gfx->createLabel(_menuFont, v14[3], 1);
- _gfx->showLabel(id[0], CENTER_LABEL_HORIZONTAL, 50);
- _gfx->showLabel(id[1], CENTER_LABEL_HORIZONTAL, 70);
- _gfx->showLabel(id[2], CENTER_LABEL_HORIZONTAL, 100);
- _gfx->showLabel(id[3], CENTER_LABEL_HORIZONTAL, 120);
+ Common::Point p;
+ _vm->_input->getCursorPos(p);
- _input->showCursor(false);
+ for (uint16 i = 0; i < 4; i++) {
+ if (_blocks[i].contains(p)) {
+ _vm->setInternLanguage(i);
+ _vm->beep();
+ _vm->_gfx->freeLabels();
+ return _helper->getState(_nextState);
+ }
+ }
- _gfx->updateScreen();
+ return this;
+ }
- _input->waitForButtonEvent(kMouseLeftUp | kMouseRightUp);
- uint32 event = _input->getLastButtonEvent();
+ virtual void enter() {
+ if (!_allowChoice) {
+ return;
+ }
- _input->showCursor(true);
+ // user can choose language in this version
+ _vm->showSlide("lingua");
- _gfx->freeLabels();
+ uint id = _vm->_gfx->createLabel(_vm->_introFont, "SELECT LANGUAGE", 1);
+ _vm->_gfx->showLabel(id, 60, 30);
- if (event != kMouseRightUp) {
- return START_INTRO;
+ _vm->setArrowCursor();
}
+};
- return SELECT_CHARACTER;
-}
-
-static const Common::Rect _dosLanguageSelectBlocks[4] = {
+const Common::Rect ChooseLanguageInputState::_dosLanguageSelectBlocks[4] = {
Common::Rect( 80, 110, 128, 180 ), // Italian
Common::Rect( 129, 85, 177, 155 ), // French
Common::Rect( 178, 60, 226, 130 ), // English
Common::Rect( 227, 35, 275, 105 ) // German
};
-static const Common::Rect _amigaLanguageSelectBlocks[4] = {
+const Common::Rect ChooseLanguageInputState::_amigaLanguageSelectBlocks[4] = {
Common::Rect( -1, -1, -1, -1 ), // Italian: not supported by Amiga multi-lingual version
Common::Rect( 129, 85, 177, 155 ), // French
Common::Rect( 178, 60, 226, 130 ), // English
Common::Rect( 227, 35, 275, 105 ) // German
};
+class SelectGameInputState : public MenuInputState {
+
+ int _choice, _oldChoice;
+ Common::String _nextState[2];
+
+ uint _labels[2];
+
+ Parallaction_ns *_vm;
+
+ static const char *newGameMsg[4];
+ static const char *loadGameMsg[4];
+
+public:
+ SelectGameInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("selectgame", helper), _vm(vm) {
+ _choice = 0;
+ _oldChoice = -1;
+
+ _nextState[0] = "newgame";
+ _nextState[1] = "loadgame";
+ }
+
+
+ virtual MenuInputState *run() {
+ int event = _vm->_input->getLastButtonEvent();
+
+ if (event == kMouseLeftUp) {
+ _vm->_gfx->freeLabels();
+ return _helper->getState(_nextState[_choice]);
+ }
+
+ Common::Point p;
+ _vm->_input->getCursorPos(p);
+ _choice = (p.x > 160) ? 1 : 0;
+
+ if (_choice != _oldChoice) {
+ if (_oldChoice != -1)
+ _vm->_gfx->hideLabel(_labels[_oldChoice]);
+
+ if (_choice != -1)
+ _vm->_gfx->showLabel(_labels[_choice], 60, 30);
+
+ _oldChoice = _choice;
+ }
+
+ return this;
+ }
+
+ virtual void enter() {
+ _vm->showSlide("restore");
+
+ _labels[0] = _vm->_gfx->createLabel(_vm->_introFont, newGameMsg[_vm->getInternLanguage()], 1);
+ _labels[1] = _vm->_gfx->createLabel(_vm->_introFont, loadGameMsg[_vm->getInternLanguage()], 1);
+ }
+
+};
+
+const char *SelectGameInputState::newGameMsg[4] = {
+ "NUOVO GIOCO",
+ "NEUF JEU",
+ "NEW GAME",
+ "NEUES SPIEL"
+};
+
+const char *SelectGameInputState::loadGameMsg[4] = {
+ "GIOCO SALVATO",
+ "JEU SAUVE'",
+ "SAVED GAME",
+ "SPIEL GESPEICHERT"
+};
+
+
+
+class LoadGameInputState : public MenuInputState {
+ bool _result;
+ Parallaction_ns *_vm;
+
+public:
+ LoadGameInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("loadgame", helper), _vm(vm) { }
+
+ virtual MenuInputState* run() {
+ if (!_result) {
+ _vm->scheduleLocationSwitch("fogne.dough");
+ }
+ return 0;
+ }
+
+ virtual void enter() {
+ _result = _vm->loadGame();
+ }
+};
+
+
-uint16 Parallaction_ns::guiChooseLanguage() {
+class NewGameInputState : public MenuInputState {
+ Parallaction_ns *_vm;
- const Common::Rect *blocks;
+ static const char *introMsg3[4];
- if (getPlatform() == Common::kPlatformAmiga) {
- if (!(getFeatures() & GF_LANG_MULT)) {
- if (getFeatures() & GF_DEMO) {
- return 1; // Amiga Demo supports English
- } else {
- return 0; // The only other non multi-lingual version just supports Italian
+public:
+ NewGameInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("newgame", helper), _vm(vm) {
+ }
+
+ virtual MenuInputState* run() {
+ int event = _vm->_input->getLastButtonEvent();
+
+ if (event == kMouseLeftUp || event == kMouseRightUp) {
+ _vm->_input->showCursor(true);
+ _vm->_gfx->freeLabels();
+
+ if (event == kMouseLeftUp) {
+ _vm->scheduleLocationSwitch("fogne.dough");
+ return 0;
}
+
+ return _helper->getState("selectcharacter");
}
- blocks = _amigaLanguageSelectBlocks;
- } else {
- blocks = _dosLanguageSelectBlocks;
+ return this;
+ }
+
+ virtual void enter() {
+ _vm->_disk->selectArchive("disk1");
+ _vm->setBackground("test", NULL, NULL);
+ _vm->_input->showCursor(false);
+
+ uint id[4];
+ id[0] = _vm->_gfx->createLabel(_vm->_menuFont, introMsg3[0], 1);
+ id[1] = _vm->_gfx->createLabel(_vm->_menuFont, introMsg3[1], 1);
+ id[2] = _vm->_gfx->createLabel(_vm->_menuFont, introMsg3[2], 1);
+ id[3] = _vm->_gfx->createLabel(_vm->_menuFont, introMsg3[3], 1);
+ _vm->_gfx->showLabel(id[0], CENTER_LABEL_HORIZONTAL, 50);
+ _vm->_gfx->showLabel(id[1], CENTER_LABEL_HORIZONTAL, 70);
+ _vm->_gfx->showLabel(id[2], CENTER_LABEL_HORIZONTAL, 100);
+ _vm->_gfx->showLabel(id[3], CENTER_LABEL_HORIZONTAL, 120);
}
+};
- // user can choose language in dos version
- showSlide("lingua");
+const char *NewGameInputState::introMsg3[4] = {
+ "PRESS LEFT MOUSE BUTTON",
+ "TO SEE INTRO",
+ "PRESS RIGHT MOUSE BUTTON",
+ "TO START"
+};
- uint id = _gfx->createLabel(_introFont, "SELECT LANGUAGE", 1);
- _gfx->showLabel(id, 60, 30);
- setArrowCursor();
- Common::Point p;
+class StartDemoInputState : public MenuInputState {
+ Parallaction_ns *_vm;
- int selection = -1;
- int event;
- while (selection == -1) {
- _input->readInput();
- event = _input->getLastButtonEvent();
+public:
+ StartDemoInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("startdemo", helper), _vm(vm) {
+ }
- if (event == kMouseLeftUp) {
- _input->getCursorPos(p);
- for (uint16 i = 0; i < 4; i++) {
- if (blocks[i].contains(p)) {
- selection = i;
- break;
- }
+ virtual MenuInputState* run() {
+ _vm->scheduleLocationSwitch("fognedemo.dough");
+ return 0;
+ }
+
+ virtual void enter() { }
+};
+
+class SelectCharacterInputState : public MenuInputState {
+
+ #define PASSWORD_LEN 6
+
+ #define CHAR_DINO 0
+ #define CHAR_DONNA 1
+ #define CHAR_DOUGH 2
+
+ static const Common::Rect codeSelectBlocks[9];
+ static const Common::Rect codeTrueBlocks[9];
+
+ Parallaction_ns *_vm;
+
+ int guiGetSelectedBlock(const Common::Point &p) {
+
+ int selection = -1;
+
+ for (uint16 i = 0; i < 9; i++) {
+ if (codeSelectBlocks[i].contains(p)) {
+ selection = i;
+ break;
}
}
- _gfx->updateScreen();
+ if ((selection != -1) && (_vm->getPlatform() == Common::kPlatformAmiga)) {
+ _vm->_gfx->invertBackground(codeTrueBlocks[selection]);
+ _vm->_gfx->updateScreen();
+ _vm->beep();
+ g_system->delayMillis(100);
+ _vm->_gfx->invertBackground(codeTrueBlocks[selection]);
+ _vm->_gfx->updateScreen();
+ }
+
+ return selection;
}
- beep();
+ byte _points[3];
+ bool _fail;
+ const uint16 (*_keys)[PASSWORD_LEN];
+ Graphics::Surface _block;
+ Graphics::Surface _emptySlots;
- _gfx->freeLabels();
+ uint _labels[2];
+ uint _len;
+ uint32 _startTime;
- return selection;
-}
+ enum {
+ CHOICE,
+ FAIL,
+ SUCCESS,
+ DELAY
+ };
+ uint _state;
+ static const char *introMsg1[4];
+ static const char *introMsg2[4];
-uint16 Parallaction_ns::guiSelectGame() {
-// printf("selectGame()\n");
+ static const uint16 _amigaKeys[3][PASSWORD_LEN];
+ static const uint16 _pcKeys[3][PASSWORD_LEN];
+ static const char *_charStartLocation[3];
- showSlide("restore");
- uint16 _si = 0;
- uint16 _di = 3;
+public:
+ SelectCharacterInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("selectcharacter", helper), _vm(vm) {
+ _keys = (_vm->getPlatform() == Common::kPlatformAmiga && (_vm->getFeatures() & GF_LANG_MULT)) ? _amigaKeys : _pcKeys;
+ _block.create(BLOCK_WIDTH, BLOCK_HEIGHT, 1);
+ }
- uint id0, id1;
- id0 = _gfx->createLabel(_introFont, loadGameMsg[_language], 1);
- id1 = _gfx->createLabel(_introFont, newGameMsg[_language], 1);
+ void cleanup() {
+ _points[0] = _points[1] = _points[2] = 0;
+ _vm->_gfx->hideLabel(_labels[1]);
+ _vm->_gfx->showLabel(_labels[0], 60, 30);
+ _fail = false;
+ _len = 0;
+ }
- Common::Point p;
+ void delay() {
+ if (g_system->getMillis() - _startTime < 2000) {
+ return;
+ }
+ cleanup();
+ _state = CHOICE;
+ }
- uint32 event = kMouseNone;
- while (event != kMouseLeftUp) {
+ void choice() {
+ int event = _vm->_input->getLastButtonEvent();
+ if (event != kMouseLeftUp) {
+ return;
+ }
- _input->readInput();
- _input->getCursorPos(p);
- event = _input->getLastButtonEvent();
+ Common::Point p;
+ _vm->_input->getCursorPos(p);
+ int _si = guiGetSelectedBlock(p);
- _si = (p.x > 160) ? 1 : 0;
+ if (_si != -1) {
+ _vm->_gfx->grabBackground(codeTrueBlocks[_si], _block);
+ _vm->_gfx->patchBackground(_block, _len * SLOT_WIDTH + SLOT_X, SLOT_Y, false);
- if (_si != _di) {
- if (_si != 0) {
- // load a game
- _gfx->hideLabel(id1);
- _gfx->showLabel(id0, 60, 30);
- } else {
- // new game
- _gfx->hideLabel(id0);
- _gfx->showLabel(id1, 60, 30);
+ if (_keys[0][_len] != _si && _keys[1][_len] != _si && _keys[2][_len] != _si) {
+ _fail = true;
}
- _di = _si;
+
+ // build user preference
+ _points[0] += (_keys[0][_len] == _si);
+ _points[1] += (_keys[1][_len] == _si);
+ _points[2] += (_keys[2][_len] == _si);
+
+ _len++;
}
- _gfx->updateScreen();
- g_system->delayMillis(30);
+ if (_len == PASSWORD_LEN) {
+ _state = _fail ? FAIL : SUCCESS;
+ }
}
- _gfx->freeLabels();
+ void fail() {
+ _vm->_gfx->patchBackground(_emptySlots, SLOT_X, SLOT_Y, false);
+ _vm->_gfx->hideLabel(_labels[0]);
+ _vm->_gfx->showLabel(_labels[1], 60, 30);
+ _startTime = g_system->getMillis();
+ _state = DELAY;
+ }
- return _si ? LOAD_GAME : NEW_GAME;
-}
+ void success() {
+ _vm->_gfx->freeLabels();
+ _vm->_gfx->setBlackPalette();
+ _emptySlots.free();
+
+ // actually select character
+ int character = -1;
+ if (_points[0] >= _points[1] && _points[0] >= _points[2]) {
+ character = CHAR_DINO;
+ } else
+ if (_points[1] >= _points[0] && _points[1] >= _points[2]) {
+ character = CHAR_DONNA;
+ } else
+ if (_points[2] >= _points[0] && _points[2] >= _points[1]) {
+ character = CHAR_DOUGH;
+ } else {
+ error("If you read this, either your CPU or transivity is broken (we believe the former).");
+ }
+
+ _vm->_inTestResult = false;
+ _vm->cleanupGame();
+ _vm->scheduleLocationSwitch(_charStartLocation[character]);
+ }
+
+ virtual MenuInputState* run() {
+ MenuInputState* nextState = this;
+
+ switch (_state) {
+ case DELAY:
+ delay();
+ break;
+
+ case CHOICE:
+ choice();
+ break;
+
+ case FAIL:
+ fail();
+ break;
+
+ case SUCCESS:
+ success();
+ nextState = 0;
+ break;
+
+ default:
+ error("unknown state in SelectCharacterInputState");
+ }
+
+ return nextState;
+ }
+
+ virtual void enter() {
+ _vm->setArrowCursor();
+ _vm->_soundMan->stopMusic();
+ _vm->_disk->selectArchive((_vm->getFeatures() & GF_DEMO) ? "disk0" : "disk1");
+ _vm->showSlide("password");
+
+ _emptySlots.create(BLOCK_WIDTH * 8, BLOCK_HEIGHT, 1);
+ Common::Rect rect(SLOT_X, SLOT_Y, SLOT_X + BLOCK_WIDTH * 8, SLOT_Y + BLOCK_HEIGHT);
+ _vm->_gfx->grabBackground(rect, _emptySlots);
+
+ _labels[0] = _vm->_gfx->createLabel(_vm->_introFont, introMsg1[_vm->getInternLanguage()], 1);
+ _labels[1] = _vm->_gfx->createLabel(_vm->_introFont, introMsg2[_vm->getInternLanguage()], 1);
+
+ cleanup();
+ _state = CHOICE;
+ }
+};
+
+const char *SelectCharacterInputState::introMsg1[4] = {
+ "INSERISCI IL CODICE",
+ "ENTREZ CODE",
+ "ENTER CODE",
+ "GIB DEN KODE EIN"
+};
+
+const char *SelectCharacterInputState::introMsg2[4] = {
+ "CODICE ERRATO",
+ "CODE ERRONE",
+ "WRONG CODE",
+ "GIB DEN KODE EIN"
+};
-static const Common::Rect codeSelectBlocks[9] = {
+const uint16 SelectCharacterInputState::_amigaKeys[][PASSWORD_LEN] = {
+ { 5, 3, 6, 2, 2, 7 }, // dino
+ { 0, 3, 6, 2, 2, 6 }, // donna
+ { 1, 3 ,7, 2, 4, 6 } // dough
+};
+
+const uint16 SelectCharacterInputState::_pcKeys[][PASSWORD_LEN] = {
+ { 5, 3, 6, 1, 4, 7 }, // dino
+ { 0, 2, 8, 5, 5, 1 }, // donna
+ { 1, 7 ,7, 2, 2, 6 } // dough
+};
+
+const char *SelectCharacterInputState::_charStartLocation[] = {
+ "test.dino",
+ "test.donna",
+ "test.dough"
+};
+
+
+const Common::Rect SelectCharacterInputState::codeSelectBlocks[9] = {
Common::Rect( 111, 129, 127, 153 ), // na
Common::Rect( 128, 120, 144, 144 ), // wa
Common::Rect( 145, 111, 161, 135 ), // ra
@@ -355,7 +671,7 @@ static const Common::Rect codeSelectBlocks[9] = {
Common::Rect( 247, 57, 263, 81 ) // ka
};
-static const Common::Rect codeTrueBlocks[9] = {
+const Common::Rect SelectCharacterInputState::codeTrueBlocks[9] = {
Common::Rect( 112, 130, 128, 154 ),
Common::Rect( 129, 121, 145, 145 ),
Common::Rect( 146, 112, 162, 136 ),
@@ -368,151 +684,252 @@ static const Common::Rect codeTrueBlocks[9] = {
};
-int Parallaction_ns::guiGetSelectedBlock(const Common::Point &p) {
+class ShowCreditsInputState : public MenuInputState {
+ Parallaction_ns *_vm;
+ int _current;
+ uint32 _startTime;
- int selection = -1;
+ struct Credit {
+ const char *_role;
+ const char *_name;
+ };
- for (uint16 i = 0; i < 9; i++) {
- if (codeSelectBlocks[i].contains(p)) {
- selection = i;
- break;
- }
- }
+ static const Credit _credits[6];
- if ((selection != -1) && (getPlatform() == Common::kPlatformAmiga)) {
- _gfx->invertBackground(codeTrueBlocks[selection]);
- _gfx->updateScreen();
- beep();
- g_system->delayMillis(100);
- _gfx->invertBackground(codeTrueBlocks[selection]);
- _gfx->updateScreen();
+public:
+ ShowCreditsInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("showcredits", helper), _vm(vm) {
}
- return selection;
-}
+ void drawCurrentLabel() {
+ uint id[2];
+ id[0] = _vm->_gfx->createLabel(_vm->_menuFont, _credits[_current]._role, 1);
+ id[1] = _vm->_gfx->createLabel(_vm->_menuFont, _credits[_current]._name, 1);
+ _vm->_gfx->showLabel(id[0], CENTER_LABEL_HORIZONTAL, 80);
+ _vm->_gfx->showLabel(id[1], CENTER_LABEL_HORIZONTAL, 100);
+ }
-//
-// character selection and protection
-//
-int Parallaction_ns::guiSelectCharacter() {
- debugC(1, kDebugMenu, "Parallaction_ns::guiselectCharacter()");
+ virtual MenuInputState* run() {
+ if (_current == -1) {
+ _startTime = g_system->getMillis();
+ _current = 0;
+ drawCurrentLabel();
+ return this;
+ }
- setArrowCursor();
- _soundMan->stopMusic();
+ int event = _vm->_input->getLastButtonEvent();
+ uint32 curTime = g_system->getMillis();
+ if ((event == kMouseLeftUp) || (curTime - _startTime > 5500)) {
+ _current++;
+ _startTime = curTime;
+ _vm->_gfx->freeLabels();
- _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1");
+ if (_current == 6) {
+ return _helper->getState("endintro");
+ }
- showSlide("password");
+ drawCurrentLabel();
+ }
+ return this;
+ }
- const uint16 (*keys)[PASSWORD_LEN] = (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_LANG_MULT)) ? _amigaKeys : _pcKeys;
- uint16 _di = 0;
- byte points[3] = { 0, 0, 0 };
+ virtual void enter() {
+ _current = -1;
+ }
+};
- bool fail;
+const ShowCreditsInputState::Credit ShowCreditsInputState::_credits[6] = {
+ {"Music and Sound Effects", "MARCO CAPRELLI"},
+ {"PC Version", "RICCARDO BALLARINO"},
+ {"Project Manager", "LOVRANO CANEPA"},
+ {"Production", "BRUNO BOZ"},
+ {"Special Thanks to", "LUIGI BENEDICENTI - GILDA and DANILO"},
+ {"Copyright 1992 Euclidea s.r.l ITALY", "All rights reserved"}
+};
- uint id[2];
- id[0] = _gfx->createLabel(_introFont, introMsg1[_language], 1);
- id[1] = _gfx->createLabel(_introFont, introMsg2[_language], 1);
+class EndIntroInputState : public MenuInputState {
+ Parallaction_ns *_vm;
+ bool _isDemo;
- Graphics::Surface v14;
- v14.create(BLOCK_WIDTH * 8, BLOCK_HEIGHT, 1);
- Common::Rect rect(SLOT_X, SLOT_Y, SLOT_X + BLOCK_WIDTH * 8, SLOT_Y + BLOCK_HEIGHT);
- _gfx->grabBackground(rect, v14);
+public:
+ EndIntroInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("endintro", helper), _vm(vm) {
+ _isDemo = (_vm->getFeatures() & GF_DEMO) != 0;
+ }
- Graphics::Surface block;
- block.create(BLOCK_WIDTH, BLOCK_HEIGHT, 1);
+ virtual MenuInputState* run() {
- Common::Point p;
+ int event = _vm->_input->getLastButtonEvent();
+ if (event != kMouseLeftUp) {
+ return this;
+ }
- while (true) {
+ if (_isDemo) {
+ _engineFlags |= kEngineQuit;
+ return 0;
+ }
- points[0] = 0;
- points[1] = 0;
- points[2] = 0;
- fail = false;
+ _vm->_gfx->freeLabels();
+ _engineFlags &= ~kEngineBlockInput;
+ return _helper->getState("selectcharacter");
+ }
- _gfx->hideLabel(id[1]);
- _gfx->showLabel(id[0], 60, 30);
+ virtual void enter() {
+ _vm->_soundMan->stopMusic();
- _di = 0;
- int event;
- while (_di < PASSWORD_LEN) {
- _input->readInput();
- event = _input->getLastButtonEvent();
- if (event == kMouseLeftUp) {
+ if (!_isDemo) {
+ int label = _vm->_gfx->createLabel(_vm->_menuFont, "CLICK MOUSE BUTTON TO START", 1);
+ _vm->_gfx->showLabel(label, CENTER_LABEL_HORIZONTAL, 80);
+ }
+ }
+};
- _input->getCursorPos(p);
- int _si = guiGetSelectedBlock(p);
+class EndPartInputState : public MenuInputState {
+ Parallaction_ns *_vm;
+ bool _allPartsComplete;
- if (_si != -1) {
- _gfx->grabBackground(codeTrueBlocks[_si], block);
- _gfx->patchBackground(block, _di * SLOT_WIDTH + SLOT_X, SLOT_Y, false);
+ // part completion messages
+ static const char *endMsg0[4];
+ static const char *endMsg1[4];
+ static const char *endMsg2[4];
+ static const char *endMsg3[4];
+ // game completion messages
+ static const char *endMsg4[4];
+ static const char *endMsg5[4];
+ static const char *endMsg6[4];
+ static const char *endMsg7[4];
- if (keys[0][_di] == _si) {
- points[0]++;
- } else
- if (keys[1][_di] == _si) {
- points[1]++;
- } else
- if (keys[2][_di] == _si) {
- points[2]++;
- } else {
- fail = true;
- }
- // build user preference
- points[0] += (keys[0][_di] == _si);
- points[1] += (keys[1][_di] == _si);
- points[2] += (keys[2][_di] == _si);
+public:
+ EndPartInputState(Parallaction_ns *vm, MenuInputHelper *helper) : MenuInputState("endpart", helper), _vm(vm) {
+ }
- _di++;
- }
- }
- _gfx->updateScreen();
+ virtual MenuInputState* run() {
+ int event = _vm->_input->getLastButtonEvent();
+ if (event != kMouseLeftUp) {
+ return this;
}
- if (!fail) {
- break;
+ _vm->_gfx->freeLabels();
+
+ if (_allPartsComplete) {
+ _vm->scheduleLocationSwitch("estgrotta.drki");
+ return 0;
}
- _gfx->patchBackground(v14, SLOT_X, SLOT_Y, false);
+ return _helper->getState("selectcharacter");
+ }
- _gfx->hideLabel(id[0]);
- _gfx->showLabel(id[1], 60, 30);
+ virtual void enter() {
+ _allPartsComplete = _vm->allPartsComplete();
- _gfx->updateScreen();
+ uint id[4];
+ if (_allPartsComplete) {
+ id[0] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg4[_language], 1);
+ id[1] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg5[_language], 1);
+ id[2] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg6[_language], 1);
+ id[3] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg7[_language], 1);
+ } else {
+ id[0] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg0[_language], 1);
+ id[1] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg1[_language], 1);
+ id[2] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg2[_language], 1);
+ id[3] = _vm->_gfx->createLabel(_vm->_menuFont, endMsg3[_language], 1);
+ }
- g_system->delayMillis(2000);
+ _vm->_gfx->showLabel(id[0], CENTER_LABEL_HORIZONTAL, 70);
+ _vm->_gfx->showLabel(id[1], CENTER_LABEL_HORIZONTAL, 100);
+ _vm->_gfx->showLabel(id[2], CENTER_LABEL_HORIZONTAL, 130);
+ _vm->_gfx->showLabel(id[3], CENTER_LABEL_HORIZONTAL, 160);
}
+};
+
+// part completion messages
+const char *EndPartInputState::endMsg0[] = {"COMPLIMENTI!", "BRAVO!", "CONGRATULATIONS!", "PRIMA!"};
+const char *EndPartInputState::endMsg1[] = {"HAI FINITO QUESTA PARTE", "TU AS COMPLETE' CETTE AVENTURE", "YOU HAVE COMPLETED THIS PART", "DU HAST EIN ABENTEUER ERFOLGREICH"};
+const char *EndPartInputState::endMsg2[] = {"ORA COMPLETA IL RESTO ", "AVEC SUCCES.", "NOW GO ON WITH THE REST OF", "ZU ENDE GEFUHRT"};
+const char *EndPartInputState::endMsg3[] = {"DELL' AVVENTURA", "CONTINUE AVEC LES AUTRES", "THIS ADVENTURE", "MACH' MIT DEN ANDEREN WEITER"};
+// game completion messages
+const char *EndPartInputState::endMsg4[] = {"COMPLIMENTI!", "BRAVO!", "CONGRATULATIONS!", "PRIMA!"};
+const char *EndPartInputState::endMsg5[] = {"HAI FINITO LE TRE PARTI", "TU AS COMPLETE' LES TROIS PARTIES", "YOU HAVE COMPLETED THE THREE PARTS", "DU HAST DREI ABENTEURE ERFOLGREICH"};
+const char *EndPartInputState::endMsg6[] = {"DELL' AVVENTURA", "DE L'AVENTURE", "OF THIS ADVENTURE", "ZU ENDE GEFUHRT"};
+const char *EndPartInputState::endMsg7[] = {"ED ORA IL GRAN FINALE ", "ET MAINTENANT LE GRAND FINAL", "NOW THE GREAT FINAL", "UND YETZT DER GROSSE SCHLUSS!"};
+
+void Parallaction_ns::startGui() {
+ _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1");
+
+ _menuHelper = new MenuInputHelper;
+ assert(_menuHelper);
+
+ new SelectGameInputState(this, _menuHelper);
+ new LoadGameInputState(this, _menuHelper);
+ new NewGameInputState(this, _menuHelper);
+ new StartDemoInputState(this, _menuHelper);
+ new SelectCharacterInputState(this, _menuHelper);
+ new ChooseLanguageInputState(this, _menuHelper);
+ new SplashInputState1(this, _menuHelper);
+ new SplashInputState0(this, _menuHelper);
+ _menuHelper->setState("intro0");
+
+ _input->_inputMode = Input::kInputModeMenu;
+}
+
+void Parallaction_ns::startCreditSequence() {
+ _menuHelper = new MenuInputHelper;
+ assert(_menuHelper);
- _gfx->freeLabels();
+ new ShowCreditsInputState(this, _menuHelper);
+ new EndIntroInputState(this, _menuHelper);
+ new SelectCharacterInputState(this, _menuHelper);
+ _menuHelper->setState("showcredits");
- _gfx->setBlackPalette();
- _gfx->updateScreen();
+ _input->_inputMode = Input::kInputModeMenu;
+}
- v14.free();
+void Parallaction_ns::startEndPartSequence() {
+ _menuHelper = new MenuInputHelper;
+ assert(_menuHelper);
+ new EndPartInputState(this, _menuHelper);
+ new SelectCharacterInputState(this, _menuHelper);
+ _menuHelper->setState("endpart");
+
+ _input->_inputMode = Input::kInputModeMenu;
+}
- // actually select character
- int character = -1;
- if (points[0] >= points[1] && points[0] >= points[2]) {
- character = CHAR_DINO;
- } else
- if (points[1] >= points[0] && points[1] >= points[2]) {
- character = CHAR_DONNA;
- } else
- if (points[2] >= points[0] && points[2] >= points[1]) {
- character = CHAR_DOUGH;
- } else {
- error("If you read this, either your CPU or transivity is broken (we believe the former).");
+void Parallaction::runGuiFrame() {
+ if (_input->_inputMode != Input::kInputModeMenu) {
+ return;
+ }
+
+ if (!_menuHelper) {
+ error("No menu helper defined!");
}
- return character;
+ bool res = _menuHelper->run();
+
+ if (!res) {
+ cleanupGui();
+ _input->_inputMode = Input::kInputModeGame;
+ }
+
+}
+
+void Parallaction::cleanupGui() {
+ delete _menuHelper;
+ _menuHelper = 0;
}
+void Parallaction::setInternLanguage(uint id) {
+ //TODO: assert id!
+
+ _language = id;
+ _disk->setLanguage(id);
+}
+
+uint Parallaction::getInternLanguage() {
+ return _language;
+}
} // namespace Parallaction