diff options
author | Christopher Page | 2008-07-21 22:46:39 +0000 |
---|---|---|
committer | Christopher Page | 2008-07-21 22:46:39 +0000 |
commit | 09f4fd946ee4b3fd6d9780e080b9bc95fbcd0a69 (patch) | |
tree | e4aae52f4e6872f8cd6bed9ddab5de6d0521f7d2 /engines/parallaction | |
parent | 0cae5552db214a7e11c552205e03fd5c0c38f6fd (diff) | |
parent | e09eb75ef77d6e76b763b3a47540a530013a887f (diff) | |
download | scummvm-rg350-09f4fd946ee4b3fd6d9780e080b9bc95fbcd0a69.tar.gz scummvm-rg350-09f4fd946ee4b3fd6d9780e080b9bc95fbcd0a69.tar.bz2 scummvm-rg350-09f4fd946ee4b3fd6d9780e080b9bc95fbcd0a69.zip |
Merged revisions 33052-33053,33056-33058,33061-33064,33068,33070,33072,33075,33078-33079,33083,33086-33087,33089,33094-33096,33098-33099,33104,33108-33109,33114-33117,33120,33135-33146,33160,33162,33165,33167-33169 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk
svn-id: r33183
Diffstat (limited to 'engines/parallaction')
-rw-r--r-- | engines/parallaction/callables_ns.cpp | 1 | ||||
-rw-r--r-- | engines/parallaction/dialogue.cpp | 389 | ||||
-rw-r--r-- | engines/parallaction/exec_ns.cpp | 17 | ||||
-rw-r--r-- | engines/parallaction/gfxbase.cpp | 3 | ||||
-rw-r--r-- | engines/parallaction/graphics.cpp | 10 | ||||
-rw-r--r-- | engines/parallaction/graphics.h | 2 | ||||
-rw-r--r-- | engines/parallaction/input.cpp | 55 | ||||
-rw-r--r-- | engines/parallaction/input.h | 11 | ||||
-rw-r--r-- | engines/parallaction/parallaction.cpp | 42 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 14 | ||||
-rw-r--r-- | engines/parallaction/parallaction_br.cpp | 12 | ||||
-rw-r--r-- | engines/parallaction/parallaction_ns.cpp | 6 | ||||
-rw-r--r-- | engines/parallaction/walk.cpp | 1 |
13 files changed, 350 insertions, 213 deletions
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index 7c053715f6..ed60a193ce 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -424,6 +424,7 @@ void Parallaction_ns::_c_testResult(void *parm) { } _inTestResult = true; + _gfx->freeLabels(); _gfx->updateScreen(); _disk->selectArchive("disk1"); diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp index a771f960a9..96491bf084 100644 --- a/engines/parallaction/dialogue.cpp +++ b/engines/parallaction/dialogue.cpp @@ -42,13 +42,23 @@ namespace Parallaction { #define ANSWER_CHARACTER_X 10 #define ANSWER_CHARACTER_Y 80 + class DialogueManager { + enum { + RUN_QUESTION, + RUN_ANSWER, + NEXT_QUESTION, + NEXT_ANSWER, + DIALOGUE_OVER + } _state; + Parallaction *_vm; - SpeakData *_data; Dialogue *_dialogue; bool _askPassword; + int _passwordLen; + bool _passwordChanged; bool isNpc; GfxObj *_questioner; @@ -59,93 +69,70 @@ class DialogueManager { uint16 _visAnswers[5]; int _numVisAnswers; + int _answerId; + + int _selection, _oldSelection; + + uint32 _mouseButtons; + Common::Point _mousePos; + bool _isKeyDown; + uint16 _downKey; + + public: - DialogueManager(Parallaction *vm, SpeakData *data) : _vm(vm), _data(data) { - _dialogue = _data->_dialogue; - isNpc = scumm_stricmp(_data->_name, "yourself") && _data->_name[0] != '\0'; - _questioner = isNpc ? _vm->_disk->loadTalk(_data->_name) : _vm->_char._talk; - _answerer = _vm->_char._talk; - } + DialogueManager(Parallaction *vm, ZonePtr z); + ~DialogueManager(); - ~DialogueManager() { - if (isNpc) { - delete _questioner; - } + bool isOver() { + return _state == DIALOGUE_OVER; } - void run(); + ZonePtr _z; + CommandList *_cmdList; + protected: - void displayQuestion(); + bool displayQuestion(); bool displayAnswers(); bool displayAnswer(uint16 i); - uint16 getAnswer(); - int16 selectAnswer(); - uint16 askPassword(); + int16 selectAnswer1(); + int16 selectAnswerN(); + int16 askPassword(); int16 getHoverAnswer(int16 x, int16 y); -}; - -uint16 DialogueManager::askPassword() { - debugC(3, kDebugExec, "checkDialoguePassword()"); + void runQuestion(); + void runAnswer(); + void nextQuestion(); + void nextAnswer(); - uint16 passwordLen = 0; - _password[0] = '\0'; - - _vm->_balloonMan->setDialogueBalloon(_q->_answers[0]->_text, 1, 3); - int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y); - _vm->_gfx->setItemFrame(id, 0); - - Common::Event e; - bool changed = true; // force first refresh - - while (true) { - e.kbd.ascii = 0; - - if (g_system->getEventManager()->pollEvent(e)) { - if ((e.type == Common::EVENT_KEYDOWN) && isdigit(e.kbd.ascii)) { - _password[passwordLen] = e.kbd.ascii; - passwordLen++; - _password[passwordLen] = '\0'; - changed = true; - } - } - - if (changed) { - _vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3); - _vm->_gfx->updateScreen(); - changed = false; - } - - if ((passwordLen == MAX_PASSWORD_LENGTH) || (e.kbd.ascii == Common::KEYCODE_RETURN)) { - - if ((!scumm_stricmp(_vm->_char.getBaseName(), _doughName) && !scumm_strnicmp(_password, "1732461", 7)) || - (!scumm_stricmp(_vm->_char.getBaseName(), _donnaName) && !scumm_strnicmp(_password, "1622", 4)) || - (!scumm_stricmp(_vm->_char.getBaseName(), _dinoName) && !scumm_strnicmp(_password, "179", 3))) { + bool checkPassword(); + void resetPassword(); + void accumPassword(uint16 ascii); +}; - break; +DialogueManager::DialogueManager(Parallaction *vm, ZonePtr z) : _vm(vm), _z(z) { + _dialogue = _z->u.speak->_dialogue; + isNpc = scumm_stricmp(_z->u.speak->_name, "yourself") && _z->u.speak->_name[0] != '\0'; + _questioner = isNpc ? _vm->_disk->loadTalk(_z->u.speak->_name) : _vm->_char._talk; + _answerer = _vm->_char._talk; - } else { - passwordLen = 0; - _password[0] = '\0'; - changed = true; - } + _askPassword = false; + _q = _dialogue->_questions[0]; - } + _cmdList = 0; + _answerId = 0; - g_system->delayMillis(20); + _state = displayQuestion() ? RUN_QUESTION : NEXT_ANSWER; +} +DialogueManager::~DialogueManager() { + if (isNpc) { + delete _questioner; } - - _vm->hideDialogueStuff(); - - return 0; - + _z = nullZonePtr; } - - bool DialogueManager::displayAnswer(uint16 i) { Answer *a = _q->_answers[i]; @@ -161,7 +148,7 @@ bool DialogueManager::displayAnswer(uint16 i) { assert(id >= 0); _visAnswers[id] = i; - _askPassword = (strstr(a->_text, "%p") != NULL); + _askPassword = (strstr(a->_text, "%P") != NULL); _numVisAnswers++; return true; @@ -178,134 +165,244 @@ bool DialogueManager::displayAnswers() { displayAnswer(i); } + if (_askPassword) { + resetPassword(); +// _vm->_balloonMan->setDialogueBalloon(_q->_answers[0]->_text, 1, 3); + int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y); + _vm->_gfx->setItemFrame(id, 0); + } else + if (_numVisAnswers == 1) { + int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y); + _vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF); + _vm->_balloonMan->setBalloonText(0, _q->_answers[_visAnswers[0]]->_text, 0); + } else + if (_numVisAnswers > 1) { + int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y); + _vm->_gfx->setItemFrame(id, _q->_answers[_visAnswers[0]]->_mood & 0xF); + _oldSelection = -1; + _selection = 0; + } + return _numVisAnswers > 0; } -void DialogueManager::displayQuestion() { - - if (!scumm_stricmp(_q->_text, "NULL")) return; +bool DialogueManager::displayQuestion() { + if (!scumm_stricmp(_q->_text, "NULL")) return false; _vm->_balloonMan->setSingleBalloon(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, _q->_mood & 0x10, 0); int id = _vm->_gfx->setItem(_questioner, QUESTION_CHARACTER_X, QUESTION_CHARACTER_Y); _vm->_gfx->setItemFrame(id, _q->_mood & 0xF); - _vm->_gfx->updateScreen(); - _vm->_input->waitUntilLeftClick(); - _vm->hideDialogueStuff(); + return true; +} - return; + +bool DialogueManager::checkPassword() { + return ((!scumm_stricmp(_vm->_char.getBaseName(), _doughName) && !scumm_strnicmp(_password, "1732461", 7)) || + (!scumm_stricmp(_vm->_char.getBaseName(), _donnaName) && !scumm_strnicmp(_password, "1622", 4)) || + (!scumm_stricmp(_vm->_char.getBaseName(), _dinoName) && !scumm_strnicmp(_password, "179", 3))); } -uint16 DialogueManager::getAnswer() { +void DialogueManager::resetPassword() { + _passwordLen = 0; + _password[0] = '\0'; + _passwordChanged = true; +} - uint16 answer = 0; +void DialogueManager::accumPassword(uint16 ascii) { + if (!isdigit(ascii)) { + return; + } - if (_askPassword == false) { - answer = selectAnswer(); - } else { - answer = askPassword(); + _password[_passwordLen] = ascii; + _passwordLen++; + _password[_passwordLen] = '\0'; + _passwordChanged = true; +} + +int16 DialogueManager::askPassword() { + + if (_isKeyDown) { + accumPassword(_downKey); + } + + if (_passwordChanged) { + _vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3); + _passwordChanged = false; } - debugC(3, kDebugExec, "runDialogue: user selected answer #%i", answer); + if ((_passwordLen == MAX_PASSWORD_LENGTH) || ((_isKeyDown) && (_downKey == Common::KEYCODE_RETURN))) { + if (checkPassword()) { + return 0; + } else { + resetPassword(); + } + } - return answer; + return -1; } -void DialogueManager::run() { +int16 DialogueManager::selectAnswer1() { - _askPassword = false; - CommandList *cmdlist = NULL; + if (_mouseButtons == kMouseLeftUp) { + return 0; + } - _q = _dialogue->_questions[0]; - int16 answer; + return -1; +} - while (_q) { +int16 DialogueManager::selectAnswerN() { - answer = 0; + _selection = _vm->_balloonMan->hitTestDialogueBalloon(_mousePos.x, _mousePos.y); - displayQuestion(); + if (_selection != _oldSelection) { + if (_oldSelection != -1) { + _vm->_balloonMan->setBalloonText(_oldSelection, _q->_answers[_visAnswers[_oldSelection]]->_text, 3); + } if (_vm->quit()) - return; + return -1; + + if (_selection != -1) { + _vm->_balloonMan->setBalloonText(_selection, _q->_answers[_visAnswers[_selection]]->_text, 0); + _vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[_selection]]->_mood & 0xF); + } + } - if (_q->_answers[0] == NULL) break; + _oldSelection = _selection; - if (scumm_stricmp(_q->_answers[0]->_text, "NULL")) { - if (!displayAnswers()) break; - answer = getAnswer(); + if ((_mouseButtons == kMouseLeftUp) && (_selection != -1)) { + return _visAnswers[_selection]; + } - if (_vm->quit()) - return; + return -1; +} - cmdlist = &_q->_answers[answer]->_commands; - } +void DialogueManager::runQuestion() { + debugC(9, kDebugDialogue, "runQuestion\n"); - _q = _q->_answers[answer]->_following._question; + if (_mouseButtons == kMouseLeftUp) { + _vm->hideDialogueStuff(); + _state = NEXT_ANSWER; } - if (cmdlist) - _vm->_cmdExec->run(*cmdlist); - } -int16 DialogueManager::selectAnswer() { - int16 numAvailableAnswers = _numVisAnswers; +void DialogueManager::nextAnswer() { + debugC(9, kDebugDialogue, "nextAnswer\n"); + + if (_q->_answers[0] == NULL) { + _state = DIALOGUE_OVER; + return; + } + + if (!scumm_stricmp(_q->_answers[0]->_text, "NULL")) { + _answerId = 0; + _state = NEXT_QUESTION; + return; + } - int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y); - _vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF); + _state = displayAnswers() ? RUN_ANSWER : DIALOGUE_OVER; +} + +void DialogueManager::runAnswer() { + debugC(9, kDebugDialogue, "runAnswer\n"); - if (numAvailableAnswers == 1) { - _vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 0); - _vm->_input->waitUntilLeftClick(); + if (_askPassword) { + _answerId = askPassword(); + } else + if (_numVisAnswers == 1) { + _answerId = selectAnswer1(); + } else { + _answerId = selectAnswerN(); + } + + if (_answerId != -1) { + _cmdList = &_q->_answers[_answerId]->_commands; _vm->hideDialogueStuff(); - return 0; + _state = NEXT_QUESTION; } +} - int oldSelection = -1; - int selection = 0; - - uint32 event; - Common::Point p; - while (!_vm->quit()) { - - _vm->_input->readInput(); - _vm->_input->getCursorPos(p); - event = _vm->_input->getLastButtonEvent(); - selection = _vm->_balloonMan->hitTestDialogueBalloon(p.x, p.y); - - if (selection != oldSelection) { - if (oldSelection != -1) { - _vm->_balloonMan->setBalloonText(oldSelection, _q->_answers[_visAnswers[oldSelection]]->_text, 3); - } - - if (selection != -1) { - _vm->_balloonMan->setBalloonText(selection, _q->_answers[_visAnswers[selection]]->_text, 0); - _vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[selection]]->_mood & 0xF); - } - } +void DialogueManager::nextQuestion() { + debugC(9, kDebugDialogue, "nextQuestion\n"); + + _q = _q->_answers[_answerId]->_following._question; + if (_q == 0) { + _state = DIALOGUE_OVER; + } else { + _state = displayQuestion() ? RUN_QUESTION : NEXT_ANSWER; + } +} + +void DialogueManager::run() { + + // cache event data + _mouseButtons = _vm->_input->getLastButtonEvent(); + _vm->_input->getCursorPos(_mousePos); + _isKeyDown = _vm->_input->getLastKeyDown(_downKey); - if ((selection != -1) && (event == kMouseLeftUp)) { - break; + switch (_state) { + case RUN_QUESTION: + runQuestion(); + break; + + case NEXT_ANSWER: + nextAnswer(); + break; + + case NEXT_QUESTION: + nextQuestion(); + break; + + case RUN_ANSWER: + runAnswer(); + break; + + case DIALOGUE_OVER: + if (_cmdList) { + _vm->_cmdExec->run(*_cmdList); } + break; - _vm->_gfx->updateScreen(); - g_system->delayMillis(20); + default: + error("unknown state in DialogueManager"); - oldSelection = selection; } - _vm->hideDialogueStuff(); +} - return _visAnswers[selection]; +void Parallaction::enterDialogueMode(ZonePtr z) { + debugC(1, kDebugDialogue, "Parallaction::enterDialogueMode(%s)", z->u.speak->_name); + _dialogueMan = new DialogueManager(this, z); + _input->_inputMode = Input::kInputModeDialogue; } +void Parallaction::exitDialogueMode() { + debugC(1, kDebugDialogue, "Parallaction::exitDialogueMode()"); + _input->_inputMode = Input::kInputModeGame; -void Parallaction::runDialogue(SpeakData *data) { - debugC(1, kDebugExec, "runDialogue: starting dialogue '%s'", data->_name); + // The current instance of _dialogueMan must be destroyed before the zone commands + // are executed, because they may create another instance of _dialogueMan that + // overwrite the current one. This would cause headaches (and it did, actually). + ZonePtr z = _dialogueMan->_z; + delete _dialogueMan; + _dialogueMan = 0; - DialogueManager man(this, data); - man.run(); + _cmdExec->run(z->_commands, z); +} + +void Parallaction::runDialogueFrame() { + if (_input->_inputMode != Input::kInputModeDialogue) { + return; + } + + _dialogueMan->run(); + + if (_dialogueMan->isOver()) { + exitDialogueMode(); + } return; } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index c77c70cd6e..913e7ae648 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -224,7 +224,11 @@ DECLARE_COMMAND_OPCODE(start) { DECLARE_COMMAND_OPCODE(speak) { - _vm->_activeZone = _ctxt.cmd->u._zone; + if ((_ctxt.cmd->u._zone->_type & 0xFFFF) == kZoneSpeak) { + _vm->enterDialogueMode(_ctxt.cmd->u._zone); + } else { + _vm->_activeZone = _ctxt.cmd->u._zone; + } } @@ -322,6 +326,7 @@ DECLARE_COMMAND_OPCODE(stop) { void Parallaction_ns::drawAnimations() { + debugC(9, kDebugExec, "Parallaction_ns::drawAnimations()\n"); uint16 layer = 0; @@ -362,6 +367,8 @@ void Parallaction_ns::drawAnimations() { } } + debugC(9, kDebugExec, "Parallaction_ns::drawAnimations done()\n"); + return; } @@ -417,7 +424,6 @@ label1: return; } - void CommandExec::run(CommandList& list, ZonePtr z) { if (list.size() == 0) { debugC(3, kDebugExec, "runCommands: nothing to do"); @@ -542,11 +548,8 @@ uint16 Parallaction::runZone(ZonePtr z) { break; case kZoneSpeak: - runDialogue(z->u.speak); - if (_vm->quit()) - return 0; - break; - + enterDialogueMode(z); + return 0; } debugC(3, kDebugExec, "runZone completed"); diff --git a/engines/parallaction/gfxbase.cpp b/engines/parallaction/gfxbase.cpp index 9e7eb12ed8..e8250ac8fd 100644 --- a/engines/parallaction/gfxbase.cpp +++ b/engines/parallaction/gfxbase.cpp @@ -267,9 +267,6 @@ void Gfx::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte } -// this is the maximum size of an unpacked frame in BRA -byte _unpackedBitmap[640*401]; - #if 0 void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, byte transparentColor) { diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 32d0e303eb..9b9ea8605a 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -33,6 +33,11 @@ namespace Parallaction { +// this is the size of the receiving buffer for unpacked frames, +// since BRA uses some insanely big animations. +#define MAXIMUM_UNPACKED_BITMAP_SIZE 640*401 + + void Gfx::registerVar(const Common::String &name, int32 initialValue) { if (_vars.contains(name)) { warning("Variable '%s' already registered, ignoring initial value.\n", name.c_str()); @@ -752,6 +757,9 @@ Gfx::Gfx(Parallaction* vm) : _halfbrite = false; _hbCircleRadius = 0; + _unpackedBitmap = new byte[MAXIMUM_UNPACKED_BITMAP_SIZE]; + assert(_unpackedBitmap); + registerVar("background_mode", 1); _varBackgroundMode = 1; @@ -769,6 +777,8 @@ Gfx::~Gfx() { freeBackground(); freeLabels(); + delete []_unpackedBitmap; + return; } diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 09f4b2f244..a7242ba6f4 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -547,6 +547,8 @@ public: uint _screenX; // scrolling position uint _screenY; + byte *_unpackedBitmap; + protected: Parallaction* _vm; bool _halfbrite; diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp index e57b95678f..d625199e2b 100644 --- a/engines/parallaction/input.cpp +++ b/engines/parallaction/input.cpp @@ -42,12 +42,14 @@ uint16 Input::readInput() { uint16 KeyDown = 0; _mouseButtons = kMouseNone; + _lastKeyDownAscii = -1; Common::EventManager *eventMan = _vm->_system->getEventManager(); while (eventMan->pollEvent(e)) { switch (e.type) { case Common::EVENT_KEYDOWN: + _lastKeyDownAscii = e.kbd.ascii; if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd') _vm->_debugger->attach(); if (_vm->getFeatures() & GF_DEMO) break; @@ -97,6 +99,11 @@ uint16 Input::readInput() { } +bool Input::getLastKeyDown(uint16 &ascii) { + ascii = _lastKeyDownAscii; + return (_lastKeyDownAscii != -1); +} + // FIXME: see comment for readInput() void Input::waitForButtonEvent(uint32 buttonEventMask, int32 timeout) { @@ -192,11 +199,38 @@ InputData* Input::updateInput() { case kInputModeGame: updateGameInput(); break; + + case kInputModeDialogue: + readInput(); + break; } return &_inputData; } +void Input::trackMouse(ZonePtr z) { + if ((z != _hoverZone) && (_hoverZone)) { + stopHovering(); + return; + } + + if (!z) { + return; + } + + if ((!_hoverZone) && ((z->_flags & kFlagsNoName) == 0)) { + _hoverZone = z; + _vm->_gfx->showFloatingLabel(_hoverZone->_label); + return; + } +} + +void Input::stopHovering() { + _hoverZone = nullZonePtr; + _vm->_gfx->hideFloatingLabel(); +} + + bool Input::translateGameInput() { if ((_engineFlags & kEnginePauseJobs) || (_engineFlags & kEngineInventory)) { @@ -231,23 +265,10 @@ bool Input::translateGameInput() { return true; } - if ((z != _hoverZone) && (_hoverZone)) { - _hoverZone = nullZonePtr; - _inputData._event = kEvExitZone; - return true; - } - - if (!z) { - _inputData._event = kEvNone; - return true; - } - - if ((!_hoverZone) && ((z->_flags & kFlagsNoName) == 0)) { - _hoverZone = z; - _inputData._event = kEvEnterZone; - _inputData._label = z->_label; - return true; - } + trackMouse(z); + if (!z) { + return true; + } if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || ((z->_type & 0xFFFF) == kZoneCommand))) { diff --git a/engines/parallaction/input.h b/engines/parallaction/input.h index e06fe96705..f260352dba 100644 --- a/engines/parallaction/input.h +++ b/engines/parallaction/input.h @@ -66,6 +66,7 @@ class Input { Common::Point _mousePos; uint16 _mouseButtons; + int32 _lastKeyDownAscii; bool _mouseHidden; ZonePtr _hoverZone; @@ -73,7 +74,8 @@ class Input { public: enum { kInputModeGame = 0, - kInputModeComment = 1 + kInputModeComment = 1, + kInputModeDialogue = 2 }; @@ -99,14 +101,13 @@ public: uint16 readInput(); InputData* updateInput(); + void trackMouse(ZonePtr z); void waitUntilLeftClick(); void waitForButtonEvent(uint32 buttonEventMask, int32 timeout = -1); uint32 getLastButtonEvent() { return _mouseButtons; } + bool getLastKeyDown(uint16 &ascii); - void stopHovering() { - _hoverZone = nullZonePtr; - } - + void stopHovering(); }; } // namespace Parallaction diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index c998e26024..fff50b48df 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -164,6 +164,11 @@ void Parallaction::updateView() { } +void Parallaction::hideDialogueStuff() { + _gfx->freeItems(); + _balloonMan->freeBalloons(); +} + void Parallaction::freeCharacter() { debugC(1, kDebugExec, "freeCharacter()"); @@ -297,16 +302,6 @@ void Parallaction::showLocationComment(const char *text, bool end) { void Parallaction::processInput(InputData *data) { switch (data->_event) { - case kEvEnterZone: - debugC(2, kDebugInput, "processInput: kEvEnterZone"); - _gfx->showFloatingLabel(data->_label); - break; - - case kEvExitZone: - debugC(2, kDebugInput, "processInput: kEvExitZone"); - _gfx->hideFloatingLabel(); - break; - case kEvAction: debugC(2, kDebugInput, "processInput: kEvAction"); _input->stopHovering(); @@ -317,7 +312,6 @@ void Parallaction::processInput(InputData *data) { case kEvOpenInventory: _input->stopHovering(); - _gfx->hideFloatingLabel(); if (hitZone(kZoneYou, data->_mousePos.x, data->_mousePos.y) == 0) { setArrowCursor(); } @@ -367,25 +361,29 @@ void Parallaction::processInput(InputData *data) { void Parallaction::runGame() { InputData *data = _input->updateInput(); - if (data->_event != kEvNone) { - processInput(data); - } - if (_vm->quit()) return; - runPendingZones(); + if (_input->_inputMode == Input::kInputModeDialogue) { + runDialogueFrame(); + } else { + if (data->_event != kEvNone) { + processInput(data); + } - if (_vm->quit()) - return; + if (_vm->quit()) + return; - if (_engineFlags & kEngineChangeLocation) { - changeLocation(_location._name); - } + runPendingZones(); if (_vm->quit()) return; + if (_engineFlags & kEngineChangeLocation) { + changeLocation(_location._name); + } + } + _gfx->beginFrame(); if (_input->_inputMode == Input::kInputModeGame) { @@ -400,7 +398,6 @@ void Parallaction::runGame() { // change this to endFrame? updateView(); - } @@ -668,6 +665,7 @@ void Parallaction::beep() { } void Parallaction::scheduleLocationSwitch(const char *location) { + debugC(9, kDebugExec, "scheduleLocationSwitch(%s)\n", location); strcpy(_location._name, location); _engineFlags |= kEngineChangeLocation; } diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index a90f8c4f48..115099addd 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -113,8 +113,6 @@ enum EngineFlags { enum { kEvNone = 0, - kEvEnterZone = 1, - kEvExitZone = 2, kEvAction = 3, kEvOpenInventory = 4, kEvCloseInventory = 5, @@ -164,6 +162,7 @@ class Debugger; class Gfx; class SoundMan; class Input; +class DialogueManager; struct Location { @@ -281,8 +280,6 @@ public: uint16 runZone(ZonePtr z); void freeZones(); - void runDialogue(SpeakData*); - AnimationPtr findAnimation(const char *name); void freeAnimations(); @@ -425,10 +422,11 @@ public: void setupBalloonManager(); - void hideDialogueStuff() { - _gfx->freeItems(); - _balloonMan->freeBalloons(); - } + void hideDialogueStuff(); + DialogueManager *_dialogueMan; + void enterDialogueMode(ZonePtr z); + void exitDialogueMode(); + void runDialogueFrame(); }; diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index 090184e9fe..0c8058e4bd 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -212,13 +212,21 @@ void Parallaction_br::runPendingZones() { if (_activeZone) { z = _activeZone; // speak Zone or sound _activeZone = nullZonePtr; - runZone(z); // FIXME: BRA doesn't handle sound yet + if ((z->_type & 0xFFFF) == kZoneSpeak) { + enterDialogueMode(z); + } else { + runZone(z); // FIXME: BRA doesn't handle sound yet + } } if (_activeZone2) { z = _activeZone2; // speak Zone or sound _activeZone2 = nullZonePtr; - runZone(z); + if ((z->_type & 0xFFFF) == kZoneSpeak) { + enterDialogueMode(z); + } else { + runZone(z); // FIXME: BRA doesn't handle sound yet + } } } diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index e5baf1864d..e8264238a1 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -191,7 +191,7 @@ void Parallaction_ns::setArrowCursor() { debugC(1, kDebugInput, "setting mouse cursor to arrow"); // this stuff is needed to avoid artifacts with labels and selected items when switching cursors - _gfx->hideFloatingLabel(); + _input->stopHovering(); _input->_activeItem._id = 0; _system->setMouseCursor(_mouseArrow, MOUSEARROW_WIDTH, MOUSEARROW_HEIGHT, 0, 0, 0); @@ -302,12 +302,11 @@ void Parallaction_ns::changeLocation(char *location) { _soundMan->playLocationMusic(location); - _gfx->hideFloatingLabel(); + _input->stopHovering(); _gfx->freeLabels(); _zoneTrap = nullZonePtr; - _input->stopHovering(); if (_engineFlags & kEngineBlockInput) { setArrowCursor(); } @@ -420,6 +419,7 @@ void Parallaction_ns::changeCharacter(const char *name) { Common::String oldArchive = _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1"); _char._ani->gfxobj = _gfx->loadAnim(_char.getFullName()); _char._ani->gfxobj->setFlags(kGfxObjCharacter); + _char._ani->gfxobj->clearFlags(kGfxObjNormal); if (!_char.dummy()) { if (getPlatform() == Common::kPlatformAmiga) { diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index 40dfddb903..a717b615e6 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -354,6 +354,7 @@ void Parallaction_ns::walk(Character &character) { if (newPos == curPos) { debugC(1, kDebugWalk, "walk was blocked by an unforeseen obstacle"); finalizeWalk(character); + targetPos = newPos; // when walking is interrupted, targetPos must be hacked so that a still frame can be selected } } |