mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-27 13:42:02 +00:00
ILLUSIONS: Implement more script opcodes and related functions
This commit is contained in:
parent
e881db0732
commit
48ef46c02d
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user