diff options
author | Johannes Schickel | 2008-04-16 23:09:07 +0000 |
---|---|---|
committer | Johannes Schickel | 2008-04-16 23:09:07 +0000 |
commit | 2b87cd1fa959304ee8a9aecdbd6cfc3ee317bcc3 (patch) | |
tree | ff363e3863d3960f5ac564714d25c3721c3938f0 /engines/kyra | |
parent | ac25887670858ef559a042776cd3c9e0166e955c (diff) | |
download | scummvm-rg350-2b87cd1fa959304ee8a9aecdbd6cfc3ee317bcc3.tar.gz scummvm-rg350-2b87cd1fa959304ee8a9aecdbd6cfc3ee317bcc3.tar.bz2 scummvm-rg350-2b87cd1fa959304ee8a9aecdbd6cfc3ee317bcc3.zip |
- Some more mask page handling fixes for Kyra3.
- Implemented a few scene animation opcodes
- basic run loop (all the user can do is quit though)
- music related fix
Wee you can see the squirrel animation and listen to the music now!
svn-id: r31523
Diffstat (limited to 'engines/kyra')
-rw-r--r-- | engines/kyra/animator_v3.cpp | 42 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.cpp | 169 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.h | 51 | ||||
-rw-r--r-- | engines/kyra/scene_v3.cpp | 30 | ||||
-rw-r--r-- | engines/kyra/screen.cpp | 6 | ||||
-rw-r--r-- | engines/kyra/script_v3.cpp | 18 |
6 files changed, 299 insertions, 17 deletions
diff --git a/engines/kyra/animator_v3.cpp b/engines/kyra/animator_v3.cpp index e2f89e4811..2eda54318f 100644 --- a/engines/kyra/animator_v3.cpp +++ b/engines/kyra/animator_v3.cpp @@ -201,8 +201,8 @@ void KyraEngine_v3::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) { uint16 flags = 0x4000; if (obj->flags & 0x800) flags |= 0x8000; - int x = obj->xPos2 - _sceneAnimMovie[obj->animNum]->xAdd(); - int y = obj->yPos1 - _sceneAnimMovie[obj->animNum]->yAdd(); + x = obj->xPos2 - _sceneAnimMovie[obj->animNum]->xAdd(); + y = obj->yPos2 - _sceneAnimMovie[obj->animNum]->yAdd(); _sceneAnimMovie[obj->animNum]->setDrawPage(2); _sceneAnimMovie[obj->animNum]->setX(x); _sceneAnimMovie[obj->animNum]->setY(y); @@ -332,4 +332,42 @@ void KyraEngine_v3::updateCharacterAnim(int charId) { updateCharPal(1); } +void KyraEngine_v3::updateSceneAnim(int anim, int newFrame) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::updateSceneAnim(%d, %d)", anim, newFrame); + AnimObj *animObject = &_animObjects[1+anim]; + if (!animObject->enabled) + return; + + animObject->needRefresh = 1; + + if (_sceneAnims[anim].flags & 2) + animObject->flags |= 1; + else + animObject->flags &= ~1; + + if (_sceneAnims[anim].flags & 4) { + animObject->shapePtr = _sceneShapes[newFrame]; + animObject->shapeIndex2 = 0xFFFF; + animObject->shapeIndex3 = 0xFFFF; + animObject->animNum = 0xFFFF; + } else { + animObject->shapePtr = 0; + animObject->shapeIndex3 = newFrame; + animObject->animNum = anim; + } + + animObject->xPos1 = _sceneAnims[anim].x; + animObject->yPos1 = _sceneAnims[anim].y; + animObject->xPos2 = _sceneAnims[anim].x2; + animObject->yPos2 = _sceneAnims[anim].y2; + + if (_sceneAnims[anim].flags & 0x20) { + _animList = deleteAnimListEntry(_animList, animObject); + if (!_animList) + _animList = initAnimList(_animList, animObject); + else + _animList = addToAnimListSorted(_animList, animObject); + } +} + } // end of namespace Kyra diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp index 0de35a0d20..024907c0e1 100644 --- a/engines/kyra/kyra_v3.cpp +++ b/engines/kyra/kyra_v3.cpp @@ -31,6 +31,7 @@ #include "kyra/text_v3.h" #include "kyra/vqa.h" #include "kyra/gui.h" +#include "kyra/timer.h" #include "common/system.h" #include "common/config-manager.h" @@ -92,6 +93,8 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _unk4 = 0; _loadingState = false; _noStartupChat = false; + _lastProcessedSceneScript = 0; + _specialSceneScriptRunFlag = false; } KyraEngine_v3::~KyraEngine_v3() { @@ -201,7 +204,7 @@ int KyraEngine_v3::go() { uninitMainMenu(); startup(); - // XXX + runLoop(); running = false; break; @@ -333,7 +336,7 @@ void KyraEngine_v3::playMusicTrack(int track, int force) { _musicSoundChannel = _soundDigital->playSound(stream); } - _musicSoundChannel = track; + _curMusicTrack = track; } void KyraEngine_v3::stopMusicTrack() { @@ -869,15 +872,177 @@ void KyraEngine_v3::updateCharPal(int unk1) { #pragma mark - +void KyraEngine_v3::runLoop() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::runLoop()"); + + _runFlag = true; + while (_runFlag && !_quitFlag) { + //XXX deathHandler + //XXX + int inputFlag = checkInput(0/*_mainButtonList*/); + removeInputTop(); + + update(); + _timer->update(); + + if (inputFlag == 198 || inputFlag == 199) { + _unk3 = _handItemSet; + Common::Point mouse = getMousePos(); + handleInput(mouse.x, mouse.y); + } + + _system->delayMillis(10); + } +} + +void KyraEngine_v3::handleInput(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::handleInput(%d, %d)"), x, y; +} + void KyraEngine_v3::update() { debugC(9, kDebugLevelMain, "KyraEngine_v3::update()"); + updateInput(); + + musicUpdate(0); + refreshAnimObjectsIfNeed(); + musicUpdate(0); + //XXX + updateSpecialSceneScripts(); //XXX + musicUpdate(0); _screen->updateScreen(); } #pragma mark - +void KyraEngine_v3::updateInput() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::updateInput()"); + Common::Event event; + + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_QUIT: + _quitFlag = true; + break; + + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE) + _eventList.push_back(Event(event, true)); + else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL) + _quitFlag = true; + else + _eventList.push_back(event); + break; + + case Common::EVENT_LBUTTONDOWN: + _eventList.push_back(Event(event, true)); + break; + + case Common::EVENT_LBUTTONUP: + case Common::EVENT_MOUSEMOVE: + _eventList.push_back(event); + break; + + default: + break; + } + } +} + +int KyraEngine_v3::checkInput(Button *buttonList, bool mainLoop) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::checkInput(%p, %d)", (const void*)buttonList, mainLoop); + updateInput(); + + int keys = 0; + + while (_eventList.size()) { + Common::Event event = *_eventList.begin(); + bool breakLoop = false; + + switch (event.type) { + case Common::EVENT_KEYDOWN: + /*if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' && + (event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && mainLoop) { + const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990); + + if (event.kbd.flags == Common::KBD_CTRL) { + loadGame(saveLoadSlot); + _eventList.clear(); + breakLoop = true; + } else { + char savegameName[14]; + sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0'); + saveGame(saveLoadSlot, savegameName); + } + } else if (event.kbd.flags == Common::KBD_CTRL) { + if (event.kbd.keycode == 'd') + _debugger->attach(); + }*/ + break; + + case Common::EVENT_MOUSEMOVE: { + Common::Point pos = getMousePos(); + _mouseX = pos.x; + _mouseY = pos.y; + _screen->updateScreen(); + } break; + + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: { + Common::Point pos = getMousePos(); + _mouseX = pos.x; + _mouseY = pos.y; + keys = event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800); + breakLoop = true; + } break; + + default: + break; + } + + //if (_debugger->isAttached()) + // _debugger->onFrame(); + + if (breakLoop) + break; + + _eventList.erase(_eventList.begin()); + } + + return /*_gui->processButtonList(buttonList, */keys/* | 0x8000)*/; +} + +void KyraEngine_v3::removeInputTop() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::removeInputTop()"); + if (!_eventList.empty()) + _eventList.erase(_eventList.begin()); +} + +bool KyraEngine_v3::skipFlag() const { + debugC(9, kDebugLevelMain, "KyraEngine_v3::skipFlag()"); + for (Common::List<Event>::const_iterator i = _eventList.begin(); i != _eventList.end(); ++i) { + if (i->causedSkip) + return true; + } + return false; +} + +void KyraEngine_v3::resetSkipFlag(bool removeEvent) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::resetSkipFlag(%d)", removeEvent); + for (Common::List<Event>::iterator i = _eventList.begin(); i != _eventList.end(); ++i) { + if (i->causedSkip) { + if (removeEvent) + _eventList.erase(i); + else + i->causedSkip = false; + return; + } + } +} + +#pragma mark - + int KyraEngine_v3::getDrawLayer(int x, int y) { debugC(9, kDebugLevelMain, "KyraEngine_v3::getDrawLayer(%d, %d)", x, y); int layer = _screen->getLayer(x, y) - 1; diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_v3.h index 5c112f42a4..f8c00567a7 100644 --- a/engines/kyra/kyra_v3.h +++ b/engines/kyra/kyra_v3.h @@ -29,7 +29,9 @@ #include "kyra/kyra.h" #include "kyra/screen_v3.h" #include "kyra/script.h" + #include "common/hashmap.h" +#include "common/list.h" namespace Kyra { @@ -38,6 +40,7 @@ class Screen_v3; class MainMenu; class WSAMovieV2; class TextDisplayer_v3; +struct Button; class KyraEngine_v3 : public KyraEngine { public: @@ -53,22 +56,48 @@ public: virtual Movie *createWSAMovie(); private: + Screen_v3 *_screen; + SoundDigital *_soundDigital; + int init(); void preinit(); void startup(); - - void update(); - void runStartupScript(int script, int unk1); void setupOpcodeTable(); + // run bool _runFlag; bool _unkInputFlag; - Screen_v3 *_screen; - SoundDigital *_soundDigital; + void runLoop(); + void handleInput(int x, int y); + + void update(); + + // - Input + void updateInput(); + int checkInput(Button *buttonList, bool mainLoop = false); + void removeInputTop(); + + int _mouseX, _mouseY; + int _mouseState; + + struct Event { + Common::Event event; + bool causedSkip; + + Event() : event(), causedSkip(false) {} + Event(Common::Event e) : event(e), causedSkip(false) {} + Event(Common::Event e, bool skip) : event(e), causedSkip(skip) {} + + operator Common::Event() const { return event; } + }; + Common::List<Event> _eventList; + + bool skipFlag() const; + void resetSkipFlag(bool removeEvent = true); // sound specific private: @@ -98,10 +127,6 @@ private: WSAMovieV2 *_menuAnim; MainMenu *_menu; - // game speed - bool skipFlag() const { return false; } - void resetSkipFlag(bool) {} - // timer void setupTimers() {} void setWalkspeed(uint8) {} @@ -237,6 +262,8 @@ private: void freeSceneShapes(); void freeSceneAnims(); + void updateSceneAnim(int anim, int newFrame); + // voice int _currentTalkFile; void openTalkFile(int file); @@ -286,6 +313,10 @@ private: bool _specialSceneScriptState[10]; ScriptState _sceneSpecialScripts[10]; uint32 _sceneSpecialScriptsTimer[10]; + int _lastProcessedSceneScript; + bool _specialSceneScriptRunFlag; + + void updateSpecialSceneScripts(); int8 _sceneDatPalette[45]; int8 _sceneDatLayerTable[15]; @@ -372,7 +403,9 @@ private: int o3_setSceneFilename(ScriptState *script); int o3_getRand(ScriptState *script); int o3_defineRoomEntrance(ScriptState *script); + int o3_setSpecialSceneScriptRunTime(ScriptState *script); int o3_defineSceneAnim(ScriptState *script); + int o3_updateSceneAnim(ScriptState *script); int o3_defineScene(ScriptState *script); int o3_setSpecialSceneScriptState(ScriptState *script); int o3_clearSpecialSceneScriptState(ScriptState *script); diff --git a/engines/kyra/scene_v3.cpp b/engines/kyra/scene_v3.cpp index 54fb02b4d1..19d5b35f7c 100644 --- a/engines/kyra/scene_v3.cpp +++ b/engines/kyra/scene_v3.cpp @@ -620,6 +620,36 @@ void KyraEngine_v3::initSceneScreen(int unk1) { //XXX when loading from main menu } +void KyraEngine_v3::updateSpecialSceneScripts() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::updateSpecialSceneScripts()"); + uint32 nextTime = _system->getMillis() + _tickLength; + const int startScript = _lastProcessedSceneScript; + + while (_system->getMillis() <= nextTime) { + if (_sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis() && + !_specialSceneScriptState[_lastProcessedSceneScript]) { + _specialSceneScriptRunFlag = true; + + while (_specialSceneScriptRunFlag && _sceneSpecialScriptsTimer[_lastProcessedSceneScript] <= _system->getMillis()) { + if (!_scriptInterpreter->runScript(&_sceneSpecialScripts[_lastProcessedSceneScript])) + _specialSceneScriptRunFlag = false; + } + } + + if (!_scriptInterpreter->validScript(&_sceneSpecialScripts[_lastProcessedSceneScript])) { + _scriptInterpreter->startScript(&_sceneSpecialScripts[_lastProcessedSceneScript], 9+_lastProcessedSceneScript); + _specialSceneScriptRunFlag = false; + } + + ++_lastProcessedSceneScript; + if (_lastProcessedSceneScript >= 10) + _lastProcessedSceneScript = 0; + + if (_lastProcessedSceneScript == startScript) + return; + } +} + void KyraEngine_v3::runSceneScript4(int unk1) { debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript4(%d)", unk1); _sceneScriptState.regs[4] = _itemInHand; diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 5539683556..a21cf171f9 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -3197,8 +3197,10 @@ void ScreenEx::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFun clearOverlayRect(_curPage, x, y, w, h); temp = h; + int curY = y; while (h--) { src += srcOffset; + ++curY; int cW = w; switch (plotFunc) { @@ -3244,7 +3246,7 @@ void ScreenEx::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFun while (cW--) { uint8 d = *src++; uint8 t = _shapePages[0][dst - origDst] & 7; - if (unk1 < t) + if (unk1 < t || curY <= _maskMinY || curY >= _maskMaxY) d = _shapePages[1][dst - origDst]; *dst++ = d; } @@ -3256,7 +3258,7 @@ void ScreenEx::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFun uint8 d = *src++; if (d) { uint8 t = _shapePages[0][dst - origDst] & 7; - if (unk1 < t) + if (unk1 < t || curY <= _maskMinY || curY >= _maskMaxY) d = _shapePages[1][dst - origDst]; *dst++ = d; } else { diff --git a/engines/kyra/script_v3.cpp b/engines/kyra/script_v3.cpp index f346c6a857..a0afc69838 100644 --- a/engines/kyra/script_v3.cpp +++ b/engines/kyra/script_v3.cpp @@ -103,6 +103,13 @@ int KyraEngine_v3::o3_defineRoomEntrance(ScriptState *script) { return 0; } +int KyraEngine_v3::o3_setSpecialSceneScriptRunTime(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + assert(stackPos(0) >= 0 && stackPos(0) < 10); + _sceneSpecialScriptsTimer[stackPos(0)] = _system->getMillis() + stackPos(1) * _tickLength; + return 0; +} + int KyraEngine_v3::o3_defineSceneAnim(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_defineSceneAnim(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s')", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), @@ -160,6 +167,13 @@ int KyraEngine_v3::o3_defineSceneAnim(ScriptState *script) { return 9; } +int KyraEngine_v3::o3_updateSceneAnim(ScriptState *script) { + debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_updateSceneAnim(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + updateSceneAnim(stackPos(0), stackPos(1)); + _specialSceneScriptRunFlag = false; + return 0; +} + int KyraEngine_v3::o3_defineScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v3::o3_defineScene(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); @@ -362,11 +376,11 @@ void KyraEngine_v3::setupOpcodeTable() { Opcode(o3_dummy), Opcode(o3_defineRoomEntrance), OpcodeUnImpl(), - OpcodeUnImpl(), + Opcode(o3_setSpecialSceneScriptRunTime), // 0x70 Opcode(o3_defineSceneAnim), Opcode(o3_dummy), - OpcodeUnImpl(), + Opcode(o3_updateSceneAnim), Opcode(o3_dummy), // 0x74 OpcodeUnImpl(), |