ILLUSIONS: Implement more script opcodes and related functions

This commit is contained in:
johndoe123 2014-03-19 20:39:16 +01:00 committed by Eugene Sandulenko
parent e881db0732
commit 48ef46c02d
12 changed files with 176 additions and 6 deletions

View File

@ -138,19 +138,28 @@ Common::Error IllusionsEngine::run() {
#endif
#if 1
// Actor/graphics test
// Actor/graphics/script test
/* TODO 0x0010000B LinkIndex 0x00060AAB 0x00060556
*/
_resSys->loadResource(0x000D0001, 0, 0);
_resSys->loadResource(0x0011000B, 0, 0);
_resSys->loadResource(0x0010000B, 0, 0);
#if 0
_controls->placeActor(0x00050009, Common::Point(0, 0), 0x00060573, 0x00040001, 0);
Control *control = *_controls->_controls.begin();
control->setActorFrameIndex(1);
control->appearActor();
#endif
_scriptMan->startScriptThread(0x00020004, 0, 0, 0, 0);
//_camera->panToPoint(Common::Point(800, 0), 500, 0);
while (!shouldQuit()) {
_scriptMan->_threads->updateThreads();
updateActors();
updateSequences();
updateGraphics();
@ -358,4 +367,13 @@ int IllusionsEngine::convertPanXCoord(int16 x) {
return 0;
}
Common::Point IllusionsEngine::getNamedPointPosition(uint32 namedPointId) {
// TODO
return Common::Point(320, 240);
}
void IllusionsEngine::playVideo(uint32 videoId, uint32 objectId, uint32 priority, uint32 threadId) {
}
} // End of namespace Illusions

View File

@ -111,6 +111,8 @@ public:
int updateGraphics();
int getRandom(int max);
int convertPanXCoord(int16 x);
Common::Point getNamedPointPosition(uint32 namedPointId);
void playVideo(uint32 videoId, uint32 objectId, uint32 value, uint32 threadId);
#if 0

View File

@ -61,6 +61,11 @@ bool Screen::isDisplayOn() {
return _displayOn;
}
void Screen::setDisplayOn(bool isOn) {
_displayOn = isOn;
// TODO Clear screen when off
}
uint16 Screen::getColorKey2() {
return _colorKey2;
}

View File

@ -38,6 +38,7 @@ public:
Graphics::Surface *allocSurface(int16 width, int16 height);
Graphics::Surface *allocSurface(SurfInfo &surfInfo);
bool isDisplayOn();
void setDisplayOn(bool isOn);
uint16 getColorKey2();
void updateSprites();
void drawSurface10(int16 destX, int16 destY, Graphics::Surface *surface, Common::Rect &srcRect, uint16 colorKey);

View File

@ -157,6 +157,20 @@ uint32 ScriptMan::startTempScriptThread(byte *scriptCodeIp, uint32 callingThread
return tempThreadId;
}
void ScriptMan::setCurrFontId(uint32 fontId) {
_fontId = fontId;
}
bool ScriptMan::enterScene(uint32 sceneId, uint32 threadId) {
ProgInfo *progInfo = _scriptResource->getProgInfo(sceneId & 0xFFFF);
if (!progInfo) {
// TODO dumpActiveScenes(_someSceneId2, threadId);
sceneId = _theSceneId;
}
_activeScenes.push(sceneId);
return progInfo != 0;
}
void ScriptMan::newScriptThread(uint32 threadId, uint32 callingThreadId, uint notifyFlags,
byte *scriptCodeIp, uint32 value8, uint32 valueC, uint32 value10) {
ScriptThread *scriptThread = new ScriptThread(_vm, threadId, callingThreadId,

View File

@ -77,6 +77,8 @@ public:
uint32 value8, uint32 valueC, uint32 value10);
uint32 startTempScriptThread(byte *scriptCodeIp, uint32 callingThreadId,
uint32 value8, uint32 valueC, uint32 value10);
void setCurrFontId(uint32 fontId);
bool enterScene(uint32 sceneId, uint32 threadId);
public:
IllusionsEngine *_vm;
@ -92,6 +94,8 @@ public:
bool _doScriptThreadInit;
uint32 _nextTempThreadId;
uint32 _fontId;
ThreadList *_threads;
ScriptOpcodes *_scriptOpcodes;

View File

@ -22,6 +22,9 @@
#include "illusions/illusions.h"
#include "illusions/scriptopcodes.h"
#include "illusions/actor.h"
#include "illusions/input.h"
#include "illusions/screen.h"
#include "illusions/scriptman.h"
#include "illusions/scriptresource.h"
#include "illusions/scriptthread.h"
@ -76,8 +79,20 @@ void ScriptOpcodes::initOpcodes() {
for (uint i = 0; i < 256; ++i)
_opcodes[i] = 0;
// Register opcodes
OPCODE(2, opSuspend);
OPCODE(3, opYield);
OPCODE(6, opStartScriptThread);
OPCODE(16, opLoadResource);
OPCODE(20, opEnterScene);
OPCODE(39, opSetDisplay);
OPCODE(42, opIncBlockCounter);
OPCODE(46, opPlaceActor);
OPCODE(87, opDeactivateButton);
OPCODE(88, opActivateButton);
OPCODE(126, opDebug126);
OPCODE(144, opPlayVideo);
OPCODE(175, opSetSceneIdThreadId);
OPCODE(177, opSetFontId);
}
#undef OPCODE
@ -92,7 +107,48 @@ void ScriptOpcodes::freeOpcodes() {
// Convenience macros
#define ARG_SKIP(x) opCall.skip(x);
#define ARG_INT16(name) int16 name = opCall.readSint16(); debug("ARG_INT16(" #name " = %d)", name);
#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %d)", name);
#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %08X)", name);
void ScriptOpcodes::opSuspend(ScriptThread *scriptThread, OpCall &opCall) {
opCall._result = kTSSuspend;
}
void ScriptOpcodes::opYield(ScriptThread *scriptThread, OpCall &opCall) {
opCall._result = kTSYield;
}
void ScriptOpcodes::opStartScriptThread(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(threadId);
_vm->_scriptMan->startScriptThread(threadId, opCall._threadId,
scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10);
}
void ScriptOpcodes::opLoadResource(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(resourceId);
// NOTE Skipped checking for stalled resources
uint32 sceneId = _vm->_scriptMan->_activeScenes.getCurrentScene();
_vm->_resSys->loadResource(resourceId, sceneId, opCall._threadId);
}
void ScriptOpcodes::opEnterScene(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(sceneId);
uint scenesCount = _vm->_scriptMan->_activeScenes.getActiveScenesCount();
if (scenesCount > 0) {
uint32 currSceneId;
_vm->_scriptMan->_activeScenes.getActiveSceneInfo(scenesCount - 1, &currSceneId, 0);
// TODO krnfileDump(currSceneId);
}
if (!_vm->_scriptMan->enterScene(sceneId, opCall._threadId))
opCall._result = kTSTerminate;
}
void ScriptOpcodes::opSetDisplay(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(flag);
_vm->_screen->setDisplayOn(flag != 0);
}
void ScriptOpcodes::opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(index)
@ -101,8 +157,53 @@ void ScriptOpcodes::opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall
_vm->_scriptMan->_scriptResource->_blockCounters.set(index + 1, value);
}
void ScriptOpcodes::opPlaceActor(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(objectId);
ARG_UINT32(actorTypeId);
ARG_UINT32(sequenceId);
ARG_UINT32(namedPointId);
Common::Point pos = _vm->getNamedPointPosition(namedPointId);
_vm->_controls->placeActor(actorTypeId, pos, sequenceId, objectId, opCall._threadId);
}
void ScriptOpcodes::opDeactivateButton(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(button)
_vm->_input->deactivateButton(button);
}
void ScriptOpcodes::opActivateButton(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(button)
_vm->_input->activateButton(button);
}
void ScriptOpcodes::opDebug126(ScriptThread *scriptThread, OpCall &opCall) {
// NOTE Prints some debug text
}
void ScriptOpcodes::opPlayVideo(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(objectId);
ARG_UINT32(videoId);
ARG_UINT32(priority);
// TODO _vm->playVideo(videoId, objectId, value, opCall._threadId);
//DEBUG Resume calling thread, later done by the video player
_vm->notifyThreadId(opCall._threadId);
}
void ScriptOpcodes::opSetSceneIdThreadId(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(sceneId);
ARG_UINT32(threadId);
_vm->_scriptMan->setSceneIdThreadId(sceneId, threadId);
}
void ScriptOpcodes::opSetFontId(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(fontId);
_vm->_scriptMan->setCurrFontId(fontId);
}
} // End of namespace Illusions

View File

@ -56,9 +56,21 @@ protected:
void initOpcodes();
void freeOpcodes();
// Opcodes
// Opcodes
void opSuspend(ScriptThread *scriptThread, OpCall &opCall);
void opYield(ScriptThread *scriptThread, OpCall &opCall);
void opStartScriptThread(ScriptThread *scriptThread, OpCall &opCall);
void opLoadResource(ScriptThread *scriptThread, OpCall &opCall);
void opEnterScene(ScriptThread *scriptThread, OpCall &opCall);
void opSetDisplay(ScriptThread *scriptThread, OpCall &opCall);
void opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall);
void opPlaceActor(ScriptThread *scriptThread, OpCall &opCall);
void opDeactivateButton(ScriptThread *scriptThread, OpCall &opCall);
void opActivateButton(ScriptThread *scriptThread, OpCall &opCall);
void opDebug126(ScriptThread *scriptThread, OpCall &opCall);
void opPlayVideo(ScriptThread *scriptThread, OpCall &opCall);
void opSetSceneIdThreadId(ScriptThread *scriptThread, OpCall &opCall);
void opSetFontId(ScriptThread *scriptThread, OpCall &opCall);
};

View File

@ -212,4 +212,10 @@ byte *ScriptResource::getThreadCode(uint32 threadId) {
return _data + _codeOffsets[(threadId & 0xFFFF) - 1];
}
ProgInfo *ScriptResource::getProgInfo(uint32 index) {
if (index > 0 && index <= _progInfosCount)
return &_progInfos[index - 1];
return 0;
}
} // End of namespace Illusions

View File

@ -99,6 +99,7 @@ public:
~ScriptResource();
void load(byte *data, uint32 dataSize);
byte *getThreadCode(uint32 threadId);
ProgInfo *getProgInfo(uint32 index);
public:
byte *_data;
uint32 _dataSize;

View File

@ -39,14 +39,14 @@ ScriptThread::ScriptThread(IllusionsEngine *vm, uint32 threadId, uint32 callingT
int ScriptThread::onUpdate() {
OpCall opCall;
opCall._result = kTSRun;
while (!_terminated && opCall._result == 4) {
while (!_terminated && opCall._result == kTSRun) {
opCall._op = _scriptCodeIp[0];
opCall._opSize = _scriptCodeIp[1] >> 1;
opCall._threadId = _scriptCodeIp[1] & 1 ? _threadId : 0;
opCall._code = _scriptCodeIp + 2;
opCall._deltaOfs = 0;
opCall._deltaOfs = opCall._opSize;
execOpcode(opCall);
_scriptCodeIp += opCall._opSize + opCall._deltaOfs;
_scriptCodeIp += opCall._deltaOfs;
}
if (_terminated)
opCall._result = kTSTerminate;
@ -55,22 +55,27 @@ int ScriptThread::onUpdate() {
void ScriptThread::onSuspend() {
// TODO
debug("ScriptThread::onSuspend()");
}
void ScriptThread::onNotify() {
// TODO
debug("ScriptThread::onNotify()");
}
void ScriptThread::onPause() {
// TODO
debug("ScriptThread::onPause()");
}
void ScriptThread::onResume() {
// TODO
debug("ScriptThread::onResume()");
}
void ScriptThread::onTerminated() {
// TODO
debug("ScriptThread::onTerminated()");
}
void ScriptThread::execOpcode(OpCall &opCall) {

View File

@ -91,6 +91,7 @@ int Thread::update() {
int status = kTSYield;
if (!_terminated && _pauseCtr <= 0) {
status = onUpdate();
debug("Thread status: %d", status);
if (status == kTSTerminate)
terminate();
else if (status == kTSSuspend)