aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorJohannes Schickel2008-04-16 23:09:07 +0000
committerJohannes Schickel2008-04-16 23:09:07 +0000
commit2b87cd1fa959304ee8a9aecdbd6cfc3ee317bcc3 (patch)
treeff363e3863d3960f5ac564714d25c3721c3938f0 /engines/kyra
parentac25887670858ef559a042776cd3c9e0166e955c (diff)
downloadscummvm-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.cpp42
-rw-r--r--engines/kyra/kyra_v3.cpp169
-rw-r--r--engines/kyra/kyra_v3.h51
-rw-r--r--engines/kyra/scene_v3.cpp30
-rw-r--r--engines/kyra/screen.cpp6
-rw-r--r--engines/kyra/script_v3.cpp18
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(),