aboutsummaryrefslogtreecommitdiff
path: root/engines/macventure
diff options
context:
space:
mode:
authorBorja Lorente2016-06-18 23:14:17 +0200
committerBorja Lorente2016-08-14 18:29:11 +0200
commit96f9910c79849c980a09ff733f4710ba9d414dc9 (patch)
tree61d9aea54d5ea51933bd6a4f60c2cd27d6736dd7 /engines/macventure
parent9b052d0a973971a50b4f0df918489e0fc6dd9fdb (diff)
downloadscummvm-rg350-96f9910c79849c980a09ff733f4710ba9d414dc9.tar.gz
scummvm-rg350-96f9910c79849c980a09ff733f4710ba9d414dc9.tar.bz2
scummvm-rg350-96f9910c79849c980a09ff733f4710ba9d414dc9.zip
MACVENTURE: Add opcodes for script engine
Diffstat (limited to 'engines/macventure')
-rw-r--r--engines/macventure/macventure.cpp24
-rw-r--r--engines/macventure/macventure.h24
-rw-r--r--engines/macventure/script.cpp994
-rw-r--r--engines/macventure/script.h188
-rw-r--r--engines/macventure/world.cpp54
-rw-r--r--engines/macventure/world.h17
6 files changed, 1281 insertions, 20 deletions
diff --git a/engines/macventure/macventure.cpp b/engines/macventure/macventure.cpp
index 78884cf1bf..f2a2f43f51 100644
--- a/engines/macventure/macventure.cpp
+++ b/engines/macventure/macventure.cpp
@@ -92,7 +92,7 @@ Common::Error MacVentureEngine::run() {
// Big class instantiation
_gui = new Gui(this, _resourceManager);
_world = new World(this, _resourceManager);
- _scriptEngine = new ScriptEngine(_world);
+ _scriptEngine = new ScriptEngine(this, _world);
_paused = false;
_halted = true;
@@ -193,6 +193,14 @@ void MacVentureEngine::gameChanged() {
_gameChanged = true;
}
+void MacVentureEngine::winGame() {
+ _gameState = kGameStateWinnig;
+}
+
+void MacVentureEngine::loseGame() {
+ _gameState = kGameStateLosing;
+}
+
void MacVentureEngine::enqueueObject(ObjID id) {
QueuedObject obj;
obj.parent = _world->getObjAttr(id, kAttrParentObject);
@@ -206,6 +214,13 @@ void MacVentureEngine::enqueueObject(ObjID id) {
_objQueue.push_back(obj);
}
+void MacVentureEngine::enqueueText(TextQueueID type, ObjID target, ObjID source, ObjID text) {
+}
+
+void MacVentureEngine::printTexts() {
+ debug("Printing texts..");
+}
+
const GlobalSettings& MacVentureEngine::getGlobalSettings() const {
return _globalSettings;
}
@@ -284,6 +299,9 @@ bool MacVentureEngine::updateState() {
return true;
}
+void MacVentureEngine::revert() {
+}
+
void MacVentureEngine::runObjQueue() {
}
@@ -360,6 +378,10 @@ const HuffmanLists * MacVentureEngine::getDecodingHuffman() const {
return _textHuffman;
}
+uint32 MacVentureEngine::randBetween(uint32 min, uint32 max) {
+ return _rnd->getRandomNumber(max - min) + min;
+}
+
// Data loading
bool MacVentureEngine::loadGlobalSettings() {
diff --git a/engines/macventure/macventure.h b/engines/macventure/macventure.h
index 457d685992..3ae195aef0 100644
--- a/engines/macventure/macventure.h
+++ b/engines/macventure/macventure.h
@@ -124,6 +124,12 @@ enum ObjectQueueID {
kAnimateBack = 14
};
+enum TextQueueID {
+ kTextNumber = 1,
+ kTextNewLine = 2,
+ kTextPlain = 3
+};
+
struct QueuedObject {
ObjectQueueID id;
ObjID object;
@@ -152,8 +158,17 @@ public:
void refreshReady();
void preparedToRun();
void gameChanged();
+ void winGame();
+ void loseGame();
+
+ bool updateState();
+ void revert();
void enqueueObject(ObjID id);
+ void enqueueText(TextQueueID type, ObjID target, ObjID source, ObjID text);
+
+ void runObjQueue();
+ void printTexts();
// Data retrieval
bool isPaused();
@@ -162,14 +177,13 @@ public:
Common::String getFilePath(FilePathID id) const;
bool isOldText() const;
const HuffmanLists *getDecodingHuffman() const;
+ uint32 randBetween(uint32 min, uint32 max);
private:
void processEvents();
bool runScriptEngine();
void endGame();
- bool updateState();
- void runObjQueue();
void updateControls();
void resetVars();
@@ -181,6 +195,8 @@ private:
ControlAction referenceToAction(ControlReference id);
uint objectsToApplyCommand();
+ const char* getGameFileName() const;
+
private: // Attributes
const ADGameDescription *_gameDescription;
@@ -217,10 +233,6 @@ private: // Attributes
Common::List<ObjID> _currentSelection;
Common::Point _deltaPoint;
-private: // Methods
-
- const char* getGameFileName() const;
-
};
diff --git a/engines/macventure/script.cpp b/engines/macventure/script.cpp
index 7e594f5a11..b0d5ef0011 100644
--- a/engines/macventure/script.cpp
+++ b/engines/macventure/script.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "common/system.h"
+
#include "macventure/macventure.h"
#include "macventure/script.h"
#include "macventure/world.h"
@@ -27,7 +29,8 @@
namespace MacVenture {
-ScriptEngine::ScriptEngine(World * world) {
+ScriptEngine::ScriptEngine(MacVentureEngine * engine, World * world) {
+ _engine = engine;
_world = world;
_scripts = new Container("Shadowgate II/Shadow Filter");
}
@@ -133,7 +136,7 @@ bool ScriptEngine::loadScript(EngineFrame * frame, uint32 scriptID) {
}
bool ScriptEngine::resumeFunc(EngineFrame * frame) {
- bool fail = runFunc();
+ bool fail = runFunc(frame);
if (fail) return fail;
frame->scripts.remove_at(0);
if (frame->scripts.size())
@@ -141,11 +144,986 @@ bool ScriptEngine::resumeFunc(EngineFrame * frame) {
return false;
}
-bool ScriptEngine::runFunc() {
+bool ScriptEngine::runFunc(EngineFrame *frame) {
debug(7, "SCRIPT: I'm running the function");
+ ScriptAsset &script = frame->scripts.front();
+ EngineState *state = &frame->state;
+ byte op;
+ while (script.hasNext()) {
+ op = script.fetch();
+ if (!(op & 0x80)) {
+ state->push(op);
+ } else {
+ switch (op) {
+ case 0x80: //get attribute
+ op80GATT(state, frame);
+ break;
+ case 0x81: //set attribute
+ op81SATT(state, frame);
+ break;
+ case 0x82: //sum children attribute
+ op82SUCH(state, frame);
+ break;
+ case 0x83: //push selected control
+ op83PUCT(state, frame);
+ break;
+ case 0x84: //push selected object
+ op84PUOB(state, frame);
+ break;
+ case 0x85: //push target
+ op85PUTA(state, frame);
+ break;
+ case 0x86: //push deltax
+ op86PUDX(state, frame);
+ break;
+ case 0x87: //push deltay
+ op87PUDY(state, frame);
+ break;
+ case 0x88: //push immediate.b
+ op88PUIB(state, frame, &script);
+ break;
+ case 0x89: //push immediate
+ op89PUI(state, frame, &script);
+ break;
+ case 0x8a: //get global
+ op8aGGLO(state, frame);
+ break;
+ case 0x8b: //set global
+ op8bSGLO(state, frame);
+ break;
+ case 0x8c: //random
+ op8cRAND(state, frame);
+ break;
+ case 0x8d: //copy
+ op8dCOPY(state, frame);
+ break;
+ case 0x8e: //copyn
+ op8eCOPYN(state, frame);
+ break;
+ case 0x8f: //swap
+ op8fSWAP(state, frame);
+ break;
+ case 0x90: //swapn
+ op90SWAPN(state, frame);
+ break;
+ case 0x91: //pop
+ op91POP(state, frame);
+ break;
+ case 0x92: //copy+1
+ op92COPYP(state, frame);
+ break;
+ case 0x93: //copy+n
+ op93COPYPN(state, frame);
+ break;
+ case 0x94: //shuffle
+ op94SHUFF(state, frame);
+ break;
+ case 0x95: //sort
+ op95SORT(state, frame);
+ break;
+ case 0x96: //clear stack
+ op96CLEAR(state, frame);
+ break;
+ case 0x97: //get stack size
+ op97SIZE(state, frame);
+ break;
+ case 0x98: //add
+ op98ADD(state, frame);
+ break;
+ case 0x99: //subtract
+ op99SUB(state, frame);
+ break;
+ case 0x9a: //multiply
+ op9aMUL(state, frame);
+ break;
+ case 0x9b: //divide
+ op9bDIV(state, frame);
+ break;
+ case 0x9c: //mod
+ op9cMOD(state, frame);
+ break;
+ case 0x9d: //divmod
+ op9dDMOD(state, frame);
+ break;
+ case 0x9e: //abs
+ op9eABS(state, frame);
+ break;
+ case 0x9f: //neg
+ op9fNEG(state, frame);
+ break;
+ case 0xa0: //and
+ opa0AND(state, frame);
+ break;
+ case 0xa1: //or
+ opa1OR(state, frame);
+ break;
+ case 0xa2: //xor
+ opa2XOR(state, frame);
+ break;
+ case 0xa3: //not
+ opa3NOT(state, frame);
+ break;
+ case 0xa4: //logical and
+ opa4LAND(state, frame);
+ break;
+ case 0xa5: //logical or
+ opa5LOR(state, frame);
+ break;
+ case 0xa6: //logical xor
+ opa6LXOR(state, frame);
+ break;
+ case 0xa7: //logical not
+ opa7LNOT(state, frame);
+ break;
+ case 0xa8: //gt? unsigned
+ opa8GTU(state, frame);
+ break;
+ case 0xa9: //lt? unsigned
+ opa9LTU(state, frame);
+ break;
+ case 0xaa: //gt? signed
+ opaaGTS(state, frame);
+ break;
+ case 0xab: //lt? signed
+ opabLTS(state, frame);
+ break;
+ case 0xac: //eq?
+ opacEQ(state, frame);
+ break;
+ case 0xad: //eq string?
+ opadEQS(state, frame);
+ break;
+ case 0xae: //contains
+ opaeCONT(state, frame);
+ break;
+ case 0xaf: //contains word
+ opafCONTW(state, frame);
+ break;
+ case 0xb0: //bra
+ opb0BRA(state, frame, &script);
+ break;
+ case 0xb1: //bra.b
+ opb1BRAB(state, frame, &script);
+ break;
+ case 0xb2: //beq
+ opb2BEQ(state, frame, &script);
+ break;
+ case 0xb3: //beq.b
+ opb3BEQB(state, frame, &script);
+ break;
+ case 0xb4: //bne
+ opb4BNE(state, frame, &script);
+ break;
+ case 0xb5: //bne.b
+ opb5BNEB(state, frame, &script);
+ break;
+ case 0xb6: //call later
+ opb6CLAT(state, frame);
+ break;
+ case 0xb7: //cancel call
+ opb7CCA(state, frame);
+ break;
+ case 0xb8: //cancel low priority
+ opb8CLOW(state, frame);
+ break;
+ case 0xb9: //cancel high priority
+ opb9CHI(state, frame);
+ break;
+ case 0xba: //cancel priority range
+ opbaCRAN(state, frame);
+ break;
+ case 0xbb: //fork
+ opbbFORK(state, frame);
+ break;
+ case 0xbc: //call
+ opbcCALL(state, frame, &script);
+ break;
+ case 0xbd: //focus object
+ opbdFOOB(state, frame);
+ break;
+ case 0xbe: //swap objects
+ opbeSWOB(state, frame);
+ break;
+ case 0xbf: //snap object
+ opbfSNOB(state, frame);
+ break;
+ case 0xc0: //toggle exits
+ opc0TEXI(state, frame);
+ break;
+ case 0xc1: //print text
+ opc1PTXT(state, frame);
+ break;
+ case 0xc2: //print newline
+ opc2PNEW(state, frame);
+ break;
+ case 0xc3: //print text+nl
+ opc3PTNE(state, frame);
+ break;
+ case 0xc4: //print nl+text+nl
+ opc4PNTN(state, frame);
+ break;
+ case 0xc5: //print number
+ opc5PNUM(state, frame);
+ break;
+ case 0xc6: //push 2
+ opc6P2(state, frame);
+ break;
+ case 0xc7: //play sound in background
+ opc7PLBG(state, frame);
+ break;
+ case 0xc8: //play sound and wait
+ opc8PLAW(state, frame);
+ break;
+ case 0xc9: //wait for sound to finish?
+ opc9WAIT(state, frame);
+ break;
+ case 0xca: //get current time
+ opcaTIME(state, frame);
+ break;
+ case 0xcb: //get current day
+ opcbDAY(state, frame);
+ break;
+ case 0xcc: //get children
+ opccCHLD(state, frame);
+ break;
+ case 0xcd: //get num children
+ opcdNCHLD(state, frame);
+ break;
+ case 0xce: //get engine version
+ opceVERS(state, frame);
+ break;
+ case 0xcf: //push scenario number
+ opcfPSCE(state, frame);
+ break;
+ case 0xd0: //push 1
+ opd0P1(state, frame);
+ break;
+ case 0xd1: //get object dimensions
+ opd1GOBD(state, frame);
+ break;
+ case 0xd2: //get overlap percent
+ opd2GOVP(state, frame);
+ break;
+ case 0xd3: //capture children
+ opd3CAPC(state, frame);
+ break;
+ case 0xd4: //release children
+ opd4RELC(state, frame);
+ break;
+ case 0xd5: //show speech dialog
+ opd5DLOG(state, frame);
+ return true;
+ case 0xd6: //activate command
+ opd6ACMD(state, frame);
+ break;
+ case 0xd7: //lose game
+ opd7LOSE(state, frame);
+ break;
+ case 0xd8: //win game
+ opd8WIN(state, frame);
+ break;
+ case 0xd9: //sleep
+ opd9SLEEP(state, frame);
+ return true;
+ case 0xda: //click to continue
+ opdaCLICK(state, frame);
+ return true;
+ case 0xdb: //run queue
+ opdbROBQ(state, frame);
+ break;
+ case 0xdc: //run sound queue
+ opdcRSQ(state, frame);
+ break;
+ case 0xdd: //run text queue
+ opddRTQ(state, frame);
+ break;
+ case 0xde: //update screen
+ opdeUPSC(state, frame);
+ break;
+ case 0xdf: //flash main window
+ opdfFMAI(state, frame);
+ return true;
+ case 0xe0: //cache graphic and object
+ ope0CHGR(state, frame);
+ break;
+ case 0xe1: //cache sound
+ ope1CHSO(state, frame);
+ break;
+ case 0xe2: //muldiv
+ ope2MDIV(state, frame);
+ break;
+ case 0xe3: //update object
+ ope3UPOB(state, frame);
+ break;
+ case 0xe4: //currently playing event?
+ ope4PLEV(state, frame);
+ break;
+ case 0xe5: //wait for event to finish
+ ope5WEV(state, frame);
+ break;
+ case 0xe6: //get fibonacci (joke)
+ ope6GFIB(state, frame);
+ break;
+ case 0xe7: //calc fibonacci
+ ope7CFIB(state, frame);
+ break;
+ default:
+ op00NOOP(op);
+ }
+ }
+ }
return false;
}
+word ScriptEngine::neg16(word val) {
+ if (val & 0x8000)
+ val = -((val ^ 0xFFFF) + 1);
+ return val;
+}
+
+word ScriptEngine::neg8(word val) {
+ if (val & 0x80)
+ val = -((val ^ 0xff) + 1);
+ return val;
+}
+
+word ScriptEngine::sumChildrenAttr(word obj, word attr, bool recursive) {
+ word sum = 0;
+ Common::Array<ObjID> children = _world->getChildren(obj, recursive);
+ for (Common::Array<ObjID>::const_iterator it = children.begin(); it != children.end(); it++) {
+ sum += _world->getObjAttr(*it, attr);
+ }
+ return sum;
+}
+
+void MacVenture::ScriptEngine::op80GATT(EngineState * state, EngineFrame * frame) {
+ word obj = state->pop();
+ word attr = state->pop();
+ state->push(_world->getObjAttr(obj, attr));
+}
+
+void ScriptEngine::op81SATT(EngineState * state, EngineFrame * frame) {
+ word obj = state->pop();
+ word attr = state->pop();
+ word val = neg16(state->pop());
+ _world->setObjAttr(obj, attr, val);
+}
+
+void ScriptEngine::op82SUCH(EngineState * state, EngineFrame * frame) {
+ word obj = state->pop();
+ word attr = state->pop();
+ word recursive = neg16(state->pop());
+ state->push(sumChildrenAttr(obj, attr, recursive));
+}
+
+void ScriptEngine::op83PUCT(EngineState * state, EngineFrame * frame) {
+ state->push(frame->action);
+}
+
+void ScriptEngine::op84PUOB(EngineState * state, EngineFrame * frame) {
+ state->push(frame->src);
+}
+
+void ScriptEngine::op85PUTA(EngineState * state, EngineFrame * frame) {
+ state->push(frame->dest);
+}
+
+void ScriptEngine::op86PUDX(EngineState * state, EngineFrame * frame) {
+ state->push(frame->x);
+}
+
+void ScriptEngine::op87PUDY(EngineState * state, EngineFrame * frame) {
+ state->push(frame->y);
+}
+
+void ScriptEngine::op88PUIB(EngineState * state, EngineFrame * frame, ScriptAsset *asset) {
+ state->push(asset->fetch());
+}
+
+void ScriptEngine::op89PUI(EngineState * state, EngineFrame * frame, ScriptAsset * asset) {
+ word val = asset->fetch();
+ val <<= 8;
+ val = val | asset->fetch();
+ state->push(val);
+}
+
+void ScriptEngine::op8aGGLO(EngineState * state, EngineFrame * frame) {
+ word idx = state->pop();
+ state->push(_world->getGlobal(idx));
+}
+
+void ScriptEngine::op8bSGLO(EngineState * state, EngineFrame * frame) {
+ word idx = state->pop();
+ word val = neg16(state->pop());
+ _world->setGlobal(idx, val);
+ _engine->gameChanged();
+}
+
+void ScriptEngine::op8cRAND(EngineState * state, EngineFrame * frame) {
+ word max = state->pop();
+ state->push(_engine->randBetween(0, max));
+}
+
+void ScriptEngine::op8dCOPY(EngineState * state, EngineFrame * frame) {
+ word val = state->pop();
+ state->push(val);
+ state->push(val);
+}
+
+void ScriptEngine::op8eCOPYN(EngineState * state, EngineFrame * frame) {
+ word n = state->pop();
+ word offs = n - 1;
+ word val;
+ while (n) {
+ val = state->peek(offs);
+ state->push(val);
+ }
+}
+
+void ScriptEngine::op8fSWAP(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push(b);
+ state->push(a);
+}
+
+void ScriptEngine::op90SWAPN(EngineState * state, EngineFrame * frame) {
+ word idx = state->pop();
+ word a = state->peek(idx);
+ word b = state->peek(0);
+ state->poke(idx, b);
+ state->poke(0, a);
+}
+
+void ScriptEngine::op91POP(EngineState * state, EngineFrame * frame) {
+ state->pop();
+}
+
+void ScriptEngine::op92COPYP(EngineState * state, EngineFrame * frame) {
+ word val = state->peek(1);
+ state->push(val);
+}
+
+void ScriptEngine::op93COPYPN(EngineState * state, EngineFrame * frame) {
+ word idx = state->pop();
+ word val = state->peek(idx);
+ state->push(val);
+}
+
+void ScriptEngine::op94SHUFF(EngineState * state, EngineFrame * frame) {
+ word a = state->pop();
+ word b = state->pop();
+ word c = state->pop();
+ state->push(a);
+ state->push(c);
+ state->push(b);
+}
+
+void ScriptEngine::op95SORT(EngineState * state, EngineFrame * frame) {
+ word step = neg16(state->pop());
+ word num = neg16(state->pop());
+ step %= num;
+ if (step<0) step += num;
+ word end = 0;
+ word start = 0;
+ for (word i = 1;i<num;i++)
+ {
+ start += step;
+ if (start >= num) start -= num;
+ if (start == end)
+ {
+ end++;
+ start = end;
+ }
+ else
+ {
+ word a = state->peek(end);
+ word b = state->peek(start);
+ state->poke(end, b);
+ state->poke(start, a);
+ }
+ }
+}
+
+void ScriptEngine::op96CLEAR(EngineState * state, EngineFrame * frame) {
+ state->clear();
+}
+
+void ScriptEngine::op97SIZE(EngineState * state, EngineFrame * frame) {
+ state->push(state->size());
+}
+
+void ScriptEngine::op98ADD(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push(a + b);
+}
+
+void ScriptEngine::op99SUB(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push(a - b);
+}
+
+void ScriptEngine::op9aMUL(EngineState * state, EngineFrame * frame) {
+ int16 b = state->pop();
+ int16 a = state->pop();
+ state->push(a * b);
+}
+
+void ScriptEngine::op9bDIV(EngineState * state, EngineFrame * frame) {
+ int16 b = state->pop();
+ int16 a = state->pop();
+ state->push((a / b) | 0);
+}
+
+void ScriptEngine::op9cMOD(EngineState * state, EngineFrame * frame) {
+ int16 b = state->pop();
+ int16 a = state->pop();
+ state->push(a % b);
+}
+
+void ScriptEngine::op9dDMOD(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push(a % b);
+ state->push((a / b) | 0);
+}
+
+void ScriptEngine::op9eABS(EngineState * state, EngineFrame * frame) {
+ word val = neg16(state->pop());
+ if (val<0) val = -val;
+ state->push(val);
+}
+
+void ScriptEngine::op9fNEG(EngineState * state, EngineFrame * frame) {
+ word val = -neg16(state->pop());
+ state->push(val);
+}
+
+void ScriptEngine::opa0AND(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push(a & b);
+}
+
+void ScriptEngine::opa1OR(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push(a | b);
+}
+
+void ScriptEngine::opa2XOR(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push(a ^ b);
+}
+
+void ScriptEngine::opa3NOT(EngineState * state, EngineFrame * frame) {
+ word a = state->pop();
+ state->push(a ^ 0xFFFF);
+}
+
+void ScriptEngine::opa4LAND(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push((a && b) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opa5LOR(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push((a || b) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opa6LXOR(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push((!a != !b) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opa7LNOT(EngineState * state, EngineFrame * frame) {
+ word a = state->pop();
+ state->push((a == 0) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opa8GTU(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push((a > b) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opa9LTU(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push((a < b) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opaaGTS(EngineState * state, EngineFrame * frame) {
+ word b = neg16(state->pop());
+ word a = neg16(state->pop());
+ state->push((a > b) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opabLTS(EngineState * state, EngineFrame * frame) {
+ word b = neg16(state->pop());
+ word a = neg16(state->pop());
+ state->push((a < b) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opacEQ(EngineState * state, EngineFrame * frame) {
+ word b = neg16(state->pop());
+ word a = neg16(state->pop());
+ state->push((a == b) ? 0xFFFF : 0);
+}
+
+void ScriptEngine::opadEQS(EngineState * state, EngineFrame * frame) {
+ Common::String b = _world->getText(state->pop());
+ Common::String a = _world->getText(state->pop());
+ state->push((a == b) ? 1 : 0);
+}
+
+void ScriptEngine::opaeCONT(EngineState * state, EngineFrame * frame) {
+ Common::String needle = _world->getText(state->pop());
+ Common::String haystack = _world->getText(state->pop());
+ haystack.toLowercase();
+ state->push(haystack.contains(needle) ? 1 : 0);
+}
+
+void ScriptEngine::opafCONTW(EngineState * state, EngineFrame * frame) {
+ Common::String needle = _world->getText(state->pop());
+ Common::String haystack = _world->getText(state->pop());
+ haystack.toLowercase();
+ state->push(haystack.contains(needle) ? 1 : 0);
+}
+
+void ScriptEngine::opb0BRA(EngineState * state, EngineFrame * frame, ScriptAsset *asset) {
+ word val = asset->fetch();
+ val <<= 8;
+ val = val | asset->fetch();
+ val = neg16(val);
+ asset->branch(val);
+}
+
+void ScriptEngine::opb1BRAB(EngineState * state, EngineFrame * frame, ScriptAsset *asset) {
+ word val = asset->fetch();
+ val = neg8(val);
+ asset->branch(val);
+}
+
+void ScriptEngine::opb2BEQ(EngineState * state, EngineFrame * frame, ScriptAsset *asset) {
+ word val = asset->fetch();
+ val <<= 8;
+ val = val | asset->fetch();
+ val = neg16(val);
+ word b = state->pop();
+ if (b != 0) asset->branch(val);
+}
+
+void ScriptEngine::opb3BEQB(EngineState * state, EngineFrame * frame, ScriptAsset *asset) {
+ word val = asset->fetch();
+ val = neg8(val);
+ word b = state->pop();
+ if (b != 0) asset->branch(val);
+}
+
+void ScriptEngine::opb4BNE(EngineState * state, EngineFrame * frame, ScriptAsset *asset) {
+ word val = asset->fetch();
+ val <<= 8;
+ val = val | asset->fetch();
+ val = neg16(val);
+ word b = state->pop();
+ if (b == 0) asset->branch(val);
+}
+
+void ScriptEngine::opb5BNEB(EngineState * state, EngineFrame * frame, ScriptAsset *asset) {
+ word val = asset->fetch();
+ val = neg8(val);
+ word b = state->pop();
+ if (b == 0) asset->branch(val);
+}
+
+void ScriptEngine::opb6CLAT(EngineState * state, EngineFrame * frame) {
+ word rank = state->pop();
+ word func = state->pop();
+ frame->saves.push_back(FunCall(rank, func));
+}
+
+void ScriptEngine::opb7CCA(EngineState * state, EngineFrame * frame) {
+ word func = state->pop();
+ for (int i = 0; i < frame->saves.size(); i++) {
+ if (frame->saves[i].func == func)
+ frame->saves[i].rank = 0;
+ }
+}
+
+void ScriptEngine::opb8CLOW(EngineState * state, EngineFrame * frame) {
+ word hi = state->pop();
+ for (int i = 0;i<frame->saves.size();i++)
+ if (frame->saves[i].rank <= hi)
+ frame->saves[i].rank = 0;
+}
+
+void ScriptEngine::opb9CHI(EngineState * state, EngineFrame * frame) {
+ word lo = state->pop();
+ for (int i = 0;i<frame->saves.size();i++)
+ if (frame->saves[i].rank >= lo)
+ frame->saves[i].rank = 0;
+}
+
+void ScriptEngine::opbaCRAN(EngineState * state, EngineFrame * frame) {
+ word hi = state->pop();
+ word lo = state->pop();
+ for (int i = 0;i<frame->saves.size();i++)
+ if (frame->saves[i].rank >= lo &&
+ frame->saves[i].rank <= hi)
+ frame->saves[i].rank = 0;
+}
+
+void ScriptEngine::opbbFORK(EngineState * state, EngineFrame * frame) {
+ EngineFrame newframe;
+ newframe.action = (ControlAction)state->pop();
+ newframe.src = state->pop();
+ newframe.dest = state->pop();
+ newframe.x = state->pop();
+ newframe.y = state->pop();
+ _frames.push_back(newframe);
+}
+
+void ScriptEngine::opbcCALL(EngineState * state, EngineFrame * frame, ScriptAsset *script) {
+ word id = state->pop();
+ ScriptAsset newfun = ScriptAsset(id, _scripts);
+ frame->scripts.remove_at(0);
+ frame->scripts.insert_at(0, newfun);
+ script = &frame->scripts.front();
+}
+
+void ScriptEngine::opbdFOOB(EngineState * state, EngineFrame * frame) {
+ word obj = state->pop();
+ _engine->enqueueObject(obj);
+}
+
+void ScriptEngine::opbeSWOB(EngineState * state, EngineFrame * frame) {
+ op00NOOP(0xbe);
+}
+
+void ScriptEngine::opbfSNOB(EngineState * state, EngineFrame * frame) {
+ op00NOOP(0xbf);
+}
+
+void ScriptEngine::opc0TEXI(EngineState * state, EngineFrame * frame) {
+ op00NOOP(0xc0);
+}
+
+void ScriptEngine::opc1PTXT(EngineState * state, EngineFrame * frame) {
+ word tid = state->pop();
+ _engine->enqueueText(kTextPlain, frame->dest, frame->src, tid);
+}
+
+void ScriptEngine::opc2PNEW(EngineState * state, EngineFrame * frame) {
+ _engine->enqueueText(kTextNewLine, frame->dest, frame->src, 0);
+}
+
+void ScriptEngine::opc3PTNE(EngineState * state, EngineFrame * frame) {
+ word tid = state->pop();
+ _engine->enqueueText(kTextPlain, frame->dest, frame->src, tid);
+ _engine->enqueueText(kTextNewLine, frame->dest, frame->src, 0);
+}
+
+void ScriptEngine::opc4PNTN(EngineState * state, EngineFrame * frame) {
+ word tid = state->pop();
+ _engine->enqueueText(kTextNewLine, frame->dest, frame->src, 0);
+ _engine->enqueueText(kTextPlain, frame->dest, frame->src, tid);
+ _engine->enqueueText(kTextNewLine, frame->dest, frame->src, 0);
+}
+
+void ScriptEngine::opc5PNUM(EngineState * state, EngineFrame * frame) {
+ word tid = state->pop();
+ _engine->enqueueText(kTextNumber, frame->dest, frame->src, tid);
+}
+
+void ScriptEngine::opc6P2(EngineState * state, EngineFrame * frame) {
+ state->push(2);
+}
+
+void ScriptEngine::opc7PLBG(EngineState * state, EngineFrame * frame) {
+ state->pop();
+ op00NOOP(0xc7);
+}
+
+void ScriptEngine::opc8PLAW(EngineState * state, EngineFrame * frame) {
+ state->pop();
+ op00NOOP(0xc8);
+}
+
+void ScriptEngine::opc9WAIT(EngineState * state, EngineFrame * frame) {
+ op00NOOP(0xc9);
+}
+
+void ScriptEngine::opcaTIME(EngineState * state, EngineFrame * frame) {
+ for (int i = 0; i < 6; i++) // Dummy
+ state->push(0x00);
+ op00NOOP(0xca);
+}
+
+void ScriptEngine::opcbDAY(EngineState * state, EngineFrame * frame) {
+ state->push(9);
+}
+
+void ScriptEngine::opccCHLD(EngineState * state, EngineFrame * frame) {
+ bool recursive = state->pop() != 0;
+ word obj = state->pop();
+ Common::Array<ObjID> children = _world->getChildren(obj, recursive);
+ for (Common::Array<ObjID>::const_iterator it = children.begin(); it != children.end(); it++) {
+ state->push(*it);
+ }
+ state->push(children.size());
+}
+
+void ScriptEngine::opcdNCHLD(EngineState * state, EngineFrame * frame) {
+ bool recursive = state->pop() != 0;
+ word obj = state->pop();
+ Common::Array<ObjID> children = _world->getChildren(obj, recursive);
+ state->push(children.size());
+}
+
+void ScriptEngine::opceVERS(EngineState * state, EngineFrame * frame) {
+ state->push(86);
+}
+
+void ScriptEngine::opcfPSCE(EngineState * state, EngineFrame * frame) {
+ state->push(0); //Not release
+}
+
+void ScriptEngine::opd0P1(EngineState * state, EngineFrame * frame) {
+ state->push(1);
+}
+
+void ScriptEngine::opd1GOBD(EngineState * state, EngineFrame * frame) {
+ word obj = state->pop();
+ Common::Rect bounds(0, 0, 1, 1); //= _world->getObjBounds(obj);
+ state->push(bounds.width());
+ state->push(bounds.height());
+}
+
+void ScriptEngine::opd2GOVP(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ state->push(0);//_world->getOverlapPercent(b, a));
+}
+
+void ScriptEngine::opd3CAPC(EngineState * state, EngineFrame * frame) {
+ word obj = state->pop();
+ _world->captureChildren(obj);
+}
+
+void ScriptEngine::opd4RELC(EngineState * state, EngineFrame * frame) {
+ word obj = state->pop();
+ _world->releaseChildren(obj);
+}
+
+void ScriptEngine::opd5DLOG(EngineState * state, EngineFrame * frame) {
+ word txt = state->pop();
+ op00NOOP(0xd5);
+}
+
+void ScriptEngine::opd6ACMD(EngineState * state, EngineFrame * frame) {
+ _engine->activateCommand((ControlReference)state->pop());
+}
+
+void ScriptEngine::opd7LOSE(EngineState * state, EngineFrame * frame) {
+ _engine->loseGame();
+}
+
+void ScriptEngine::opd8WIN(EngineState * state, EngineFrame * frame) {
+ _engine->winGame();
+}
+
+void ScriptEngine::opd9SLEEP(EngineState * state, EngineFrame * frame) {
+ word ticks = state->pop();
+ g_system->delayMillis((ticks / 60) * 1000);
+ _engine->preparedToRun();
+}
+
+void ScriptEngine::opdaCLICK(EngineState * state, EngineFrame * frame) {
+ //_engine->updateScreen(false);
+ //clickToContinue();
+ op00NOOP(0xda);
+}
+
+void ScriptEngine::opdbROBQ(EngineState * state, EngineFrame * frame) {
+ _engine->runObjQueue();
+}
+
+void ScriptEngine::opdcRSQ(EngineState * state, EngineFrame * frame) {
+ op00NOOP(0xdc);
+}
+
+void ScriptEngine::opddRTQ(EngineState * state, EngineFrame * frame) {
+ _engine->printTexts();
+}
+
+void ScriptEngine::opdeUPSC(EngineState * state, EngineFrame * frame) {
+ //_engine->updateScreen(false);
+ op00NOOP(0xde);
+}
+
+void ScriptEngine::opdfFMAI(EngineState * state, EngineFrame * frame) {
+ word ticks = state->pop();
+ g_system->delayMillis((ticks / 60) * 1000);
+ _engine->revert();
+}
+
+void ScriptEngine::ope0CHGR(EngineState * state, EngineFrame * frame) {
+ word txt = state->pop();
+ op00NOOP(0xe0);
+}
+
+void ScriptEngine::ope1CHSO(EngineState * state, EngineFrame * frame) {
+ word txt = state->pop();
+ op00NOOP(0xe1);
+}
+
+void ScriptEngine::ope2MDIV(EngineState * state, EngineFrame * frame) {
+ word b = state->pop();
+ word a = state->pop();
+ a *= b;
+ word c = state->pop();
+ a /= c;
+ state->push(a | 0);
+}
+
+void ScriptEngine::ope3UPOB(EngineState * state, EngineFrame * frame) {
+ word obj = state->pop();
+ _world->updateObj(obj);
+}
+
+void ScriptEngine::ope4PLEV(EngineState * state, EngineFrame * frame) {
+ state->push(0);
+ op00NOOP(0xe4);
+}
+
+void ScriptEngine::ope5WEV(EngineState * state, EngineFrame * frame) {
+ op00NOOP(0xe5);
+}
+
+void ScriptEngine::ope6GFIB(EngineState * state, EngineFrame * frame) {
+ state->push(0);
+ op00NOOP(0xe6);
+}
+
+void ScriptEngine::ope7CFIB(EngineState * state, EngineFrame * frame) {
+ state->pop();
+ op00NOOP(0xe7);
+}
+
+void ScriptEngine::op00NOOP(byte op) {
+ debug("SCRIPT: Opcode not implemented => %x", op);
+}
+
+
+
+
ScriptAsset::ScriptAsset(ObjID id, Container * container) {
_id = id;
_container = container;
@@ -156,12 +1134,20 @@ void ScriptAsset::reset() {
_ip = 0x0;
}
-uint8 ScriptAsset::fecth() {
+uint8 ScriptAsset::fetch() {
uint8 ins = _instructions[_ip];
_ip++;
return ins;
}
+bool ScriptAsset::hasNext() {
+ return _ip < _instructions.size();
+}
+
+void ScriptAsset::branch(word amount) {
+ _ip += amount;
+}
+
void ScriptAsset::loadInstructions() {
uint32 amount = _container->getItemByteSize(_id);
Common::SeekableReadStream *res = _container->getItem(_id);
diff --git a/engines/macventure/script.h b/engines/macventure/script.h
index d66a867eca..e56c6e7440 100644
--- a/engines/macventure/script.h
+++ b/engines/macventure/script.h
@@ -51,6 +51,7 @@ enum ControlAction {
};
typedef uint32 ObjID;
+typedef int16 word;
class ScriptAsset {
public:
@@ -58,7 +59,9 @@ public:
~ScriptAsset() {}
void reset();
- uint8 fecth();
+ uint8 fetch();
+ bool hasNext();
+ void branch(word amount);
private:
@@ -72,13 +75,61 @@ private:
uint32 _ip; // Instruction pointer
};
-struct EngineState {
- uint8 stack[0x80];
- uint8 sp;
-
+class EngineState {
+public:
EngineState() {
+ clear();
+ }
+
+ void push(word data) {
+ stack[sp] = unneg16(data);
+ sp--;
+ }
+
+ word pop() {
+ byte v = stack[sp];
+ sp++;
+ return v;
+ }
+
+ word peek(word off) {
+ return stack[sp + off];
+ }
+
+ void poke(word off, word val) {
+ stack[sp + off] = unneg16(val);
+ }
+
+ void clear() {
sp = 0x80;
}
+
+ word size() {
+ return 0x80 - sp;
+ }
+
+private:
+ word unneg16(word data) {
+ if (data < 0)
+ data = ((-data) ^ 0xFFFF) + 1;
+
+ return data;
+ }
+
+private:
+
+ word stack[0x80];
+ word sp;
+};
+
+struct FunCall {
+ word func;
+ word rank;
+
+ FunCall(word f, word r) {
+ func = f;
+ rank = r;
+ }
};
struct EngineFrame {
@@ -89,6 +140,7 @@ struct EngineFrame {
int y;
EngineState state;
Common::Array<ScriptAsset> scripts;
+ Common::Array<FunCall> saves;
uint32 familyIdx;
bool haltedInFirst;
@@ -98,7 +150,7 @@ struct EngineFrame {
class ScriptEngine {
public:
- ScriptEngine(World *world);
+ ScriptEngine(MacVentureEngine *engine, World *world);
~ScriptEngine();
public:
@@ -110,9 +162,131 @@ private:
bool execFrame(bool execAll);
bool loadScript(EngineFrame * frame, uint32 scriptID);
bool resumeFunc(EngineFrame * frame);
- bool runFunc();
+ bool runFunc(EngineFrame * frame);
+
+private:
+
+ // Aux
+ word neg16(word val);
+ word neg8(word val);
+ word sumChildrenAttr(word obj, word attr, bool recursive);
+
+ // Opcodes
+ void op80GATT(EngineState *state, EngineFrame *frame); //get attribute
+ void op81SATT(EngineState *state, EngineFrame *frame); //set attribute
+ void op82SUCH(EngineState *state, EngineFrame *frame); //sum children attribute
+ void op83PUCT(EngineState *state, EngineFrame *frame); //push selected control
+ void op84PUOB(EngineState *state, EngineFrame *frame); //push selected object
+ void op85PUTA(EngineState *state, EngineFrame *frame); //push target
+ void op86PUDX(EngineState *state, EngineFrame *frame); //push deltax
+ void op87PUDY(EngineState *state, EngineFrame *frame); //push deltay
+ void op88PUIB(EngineState *state, EngineFrame *frame, ScriptAsset *asset);//push immediate.b
+ void op89PUI(EngineState *state, EngineFrame *frame, ScriptAsset *asset);//push immediate
+ void op8aGGLO(EngineState *state, EngineFrame *frame); //get global
+ void op8bSGLO(EngineState *state, EngineFrame *frame); //set global
+ void op8cRAND(EngineState *state, EngineFrame *frame); //random
+ void op8dCOPY(EngineState *state, EngineFrame *frame); //copy
+ void op8eCOPYN(EngineState *state, EngineFrame *frame); //copyn
+ void op8fSWAP(EngineState *state, EngineFrame *frame); //swap
+
+ void op90SWAPN(EngineState *state, EngineFrame *frame); //swapn
+ void op91POP(EngineState *state, EngineFrame *frame); //pop
+ void op92COPYP(EngineState *state, EngineFrame *frame); //copy+1
+ void op93COPYPN(EngineState *state, EngineFrame *frame);//copy+n
+ void op94SHUFF(EngineState *state, EngineFrame *frame); //shuffle
+ void op95SORT(EngineState *state, EngineFrame *frame); //sort
+ void op96CLEAR(EngineState *state, EngineFrame *frame); //clear stack
+ void op97SIZE(EngineState *state, EngineFrame *frame); //get stack size
+ void op98ADD(EngineState *state, EngineFrame *frame); //add
+ void op99SUB(EngineState *state, EngineFrame *frame); //subtract
+ void op9aMUL(EngineState *state, EngineFrame *frame); //multiply
+ void op9bDIV(EngineState *state, EngineFrame *frame); //divide
+ void op9cMOD(EngineState *state, EngineFrame *frame); //mod
+ void op9dDMOD(EngineState *state, EngineFrame *frame); //divmod
+ void op9eABS(EngineState *state, EngineFrame *frame); //abs
+ void op9fNEG(EngineState *state, EngineFrame *frame); //neg
+
+ void opa0AND(EngineState *state, EngineFrame *frame); //and
+ void opa1OR(EngineState *state, EngineFrame *frame); //or
+ void opa2XOR(EngineState *state, EngineFrame *frame); //xor
+ void opa3NOT(EngineState *state, EngineFrame *frame); //not
+ void opa4LAND(EngineState *state, EngineFrame *frame); //logical and
+ void opa5LOR(EngineState *state, EngineFrame *frame); //logical or
+ void opa6LXOR(EngineState *state, EngineFrame *frame); //logical xor
+ void opa7LNOT(EngineState *state, EngineFrame *frame); //logical not
+ void opa8GTU(EngineState *state, EngineFrame *frame); //gt? unsigned
+ void opa9LTU(EngineState *state, EngineFrame *frame); //lt? unsigned
+ void opaaGTS(EngineState *state, EngineFrame *frame); //gt? signed
+ void opabLTS(EngineState *state, EngineFrame *frame); //lt? signed
+ void opacEQ(EngineState *state, EngineFrame *frame); //eq?
+ void opadEQS(EngineState *state, EngineFrame *frame); //eq string?
+ void opaeCONT(EngineState *state, EngineFrame *frame); //contains
+ void opafCONTW(EngineState *state, EngineFrame *frame); //contains word
+
+ void opb0BRA(EngineState *state, EngineFrame *frame, ScriptAsset *asset); //bra
+ void opb1BRAB(EngineState *state, EngineFrame *frame, ScriptAsset *asset); //bra.b
+ void opb2BEQ(EngineState *state, EngineFrame *frame, ScriptAsset *asset); //beq
+ void opb3BEQB(EngineState *state, EngineFrame *frame, ScriptAsset *asset); //beq.b
+ void opb4BNE(EngineState *state, EngineFrame *frame, ScriptAsset *asset); //bne
+ void opb5BNEB(EngineState *state, EngineFrame *frame, ScriptAsset *asset); //bne.b
+ void opb6CLAT(EngineState *state, EngineFrame *frame); //call later
+ void opb7CCA(EngineState *state, EngineFrame *frame); //cancel call
+ void opb8CLOW(EngineState *state, EngineFrame *frame); //cancel low priority
+ void opb9CHI(EngineState *state, EngineFrame *frame); //cancel high priority
+ void opbaCRAN(EngineState *state, EngineFrame *frame); //cancel priority range
+ void opbbFORK(EngineState *state, EngineFrame *frame); //fork
+ void opbcCALL(EngineState *state, EngineFrame *frame, ScriptAsset *script); //call
+ void opbdFOOB(EngineState *state, EngineFrame *frame); //focus object
+ void opbeSWOB(EngineState *state, EngineFrame *frame); //swap objects
+ void opbfSNOB(EngineState *state, EngineFrame *frame); //snap object
+
+ void opc0TEXI(EngineState *state, EngineFrame *frame); //toggle exits
+ void opc1PTXT(EngineState *state, EngineFrame *frame); //print text
+ void opc2PNEW(EngineState *state, EngineFrame *frame); //print newline
+ void opc3PTNE(EngineState *state, EngineFrame *frame); //print text+nl
+ void opc4PNTN(EngineState *state, EngineFrame *frame); //print nl+text+nl
+ void opc5PNUM(EngineState *state, EngineFrame *frame); //print number
+ void opc6P2(EngineState *state, EngineFrame *frame); //push 2
+ void opc7PLBG(EngineState *state, EngineFrame *frame); //play sound in background
+ void opc8PLAW(EngineState *state, EngineFrame *frame); //play sound and wait
+ void opc9WAIT(EngineState *state, EngineFrame *frame); //wait for sound to finish?
+ void opcaTIME(EngineState *state, EngineFrame *frame); //get current time
+ void opcbDAY(EngineState *state, EngineFrame *frame); //get current day
+ void opccCHLD(EngineState *state, EngineFrame *frame); //get children
+ void opcdNCHLD(EngineState *state, EngineFrame *frame); //get num children
+ void opceVERS(EngineState *state, EngineFrame *frame); //get engine version
+ void opcfPSCE(EngineState *state, EngineFrame *frame); //push scenario number
+
+ void opd0P1(EngineState *state, EngineFrame *frame); //push 1
+ void opd1GOBD(EngineState *state, EngineFrame *frame); //get object dimensions
+ void opd2GOVP(EngineState *state, EngineFrame *frame); //get overlap percent
+ void opd3CAPC(EngineState *state, EngineFrame *frame); //capture children
+ void opd4RELC(EngineState *state, EngineFrame *frame); //release children
+ void opd5DLOG(EngineState *state, EngineFrame *frame); //show speech dialog
+ void opd6ACMD(EngineState *state, EngineFrame *frame); //activate command
+ void opd7LOSE(EngineState *state, EngineFrame *frame); //lose game
+ void opd8WIN(EngineState *state, EngineFrame *frame); //win game
+ void opd9SLEEP(EngineState *state, EngineFrame *frame); //sleep
+ void opdaCLICK(EngineState *state, EngineFrame *frame); //click to continue
+ void opdbROBQ(EngineState *state, EngineFrame *frame); //run queue
+ void opdcRSQ(EngineState *state, EngineFrame *frame); //run sound queue
+ void opddRTQ(EngineState *state, EngineFrame *frame); //run text queue
+ void opdeUPSC(EngineState *state, EngineFrame *frame); //update screen
+ void opdfFMAI(EngineState *state, EngineFrame *frame); //flash main window
+
+ void ope0CHGR(EngineState *state, EngineFrame *frame); //cache graphic and object
+ void ope1CHSO(EngineState *state, EngineFrame *frame); //cache sound
+ void ope2MDIV(EngineState *state, EngineFrame *frame); //muldiv
+ void ope3UPOB(EngineState *state, EngineFrame *frame); //update object
+ void ope4PLEV(EngineState *state, EngineFrame *frame); //currently playing event?
+ void ope5WEV(EngineState *state, EngineFrame *frame); //wait for event to finish
+ void ope6GFIB(EngineState *state, EngineFrame *frame); //get fibonacci (joke)
+ void ope7CFIB(EngineState *state, EngineFrame *frame); //calc fibonacci
+
+ void op00NOOP(byte op);
private:
+ MacVentureEngine *_engine;
World *_world;
Common::Array<EngineFrame> _frames;
Container *_scripts;
diff --git a/engines/macventure/world.cpp b/engines/macventure/world.cpp
index 2cd50ff82a..2f603c5ddc 100644
--- a/engines/macventure/world.cpp
+++ b/engines/macventure/world.cpp
@@ -102,6 +102,56 @@ Common::Array<ObjID> World::getChildren(ObjID objID, bool recursive) {
return Common::Array<ObjID>();
}
+WindowReference World::getObjWindow(ObjID objID) {
+ switch (objID) {
+ case 0xfffc: return kExitsWindow;
+ case 0xfffd: return kSelfWindow;
+ case 0xfffe: return kOutConsoleWindow;
+ case 0xffff: return kCommandsWindow;
+ }
+
+ return findObjWindow(objID);
+}
+
+WindowReference World::findObjWindow(ObjID objID) {
+ return kMainGameWindow;
+}
+
+Attribute World::getGlobal(uint32 attrID) {
+ return _saveGame->getGlobals()[attrID];
+}
+
+void World::setGlobal(uint32 attrID, Attribute value) {
+ _saveGame->setGlobal(attrID, value);
+}
+
+void World::updateObj(ObjID objID) {
+ WindowReference win;
+ if (getObjAttr(1, kAttrParentObject) == objID) {
+ win = kMainGameWindow;
+ } else {
+ win = getObjWindow(objID);
+ }
+ if (win) {
+ //focusObjWin(objID);
+ _engine->runObjQueue();
+ //_engine->updateWindow(win);
+ }
+}
+
+void World::captureChildren(ObjID objID) {
+}
+
+void World::releaseChildren(ObjID objID) {
+}
+
+Common::String World::getText(ObjID objID) {
+ TextAsset text = TextAsset(objID, _gameText, _engine->isOldText(), _engine->getDecodingHuffman());
+
+ return *text.decode();
+}
+
+
bool World::loadStartGameFileName() {
Common::SeekableReadStream *res;
@@ -186,6 +236,10 @@ const AttributeGroup * SaveGame::getGroup(uint32 groupID) {
return &(_groups[groupID]);
}
+void SaveGame::setGlobal(uint32 attrID, Attribute value) {
+ _globals[attrID] = value;
+}
+
const Common::Array<uint16>& MacVenture::SaveGame::getGlobals() {
return _globals;
}
diff --git a/engines/macventure/world.h b/engines/macventure/world.h
index 3893aca445..370582665b 100644
--- a/engines/macventure/world.h
+++ b/engines/macventure/world.h
@@ -67,9 +67,11 @@ public:
Attribute getAttr(ObjID objID, uint32 attrID);
void setAttr(uint32 attrID, ObjID objID, Attribute value);
+ void setGlobal(uint32 attrID, Attribute value);
+ const Common::Array<uint16> &getGlobals();
+
const Common::Array<AttributeGroup> &getGroups();
const AttributeGroup *getGroup(uint32 groupID);
- const Common::Array<uint16> &getGlobals();
const Common::String &getText();
private:
@@ -88,11 +90,22 @@ public:
World(MacVentureEngine *engine, Common::MacResManager *resMan);
~World();
- uint32 getObjAttr(ObjID objID, uint32 attrID);
+
void setObjAttr(ObjID objID, uint32 attrID, Attribute value);
+ void setGlobal(uint32 attrID, Attribute value);
+ void updateObj(ObjID objID);
+ void captureChildren(ObjID objID);
+ void releaseChildren(ObjID objID);
+
+ uint32 getObjAttr(ObjID objID, uint32 attrID);
+ Attribute getGlobal(uint32 attrID);
+ Common::String getText(ObjID objID);
+
bool isObjActive(ObjID obj);
Common::Array<ObjID> getFamily(ObjID objID, bool recursive);
Common::Array<ObjID> getChildren(ObjID objID, bool recursive);
+ WindowReference getObjWindow(ObjID objID);
+ WindowReference findObjWindow(ObjID objID);
private:
bool loadStartGameFileName();