diff options
| -rw-r--r-- | engines/macventure/macventure.cpp | 24 | ||||
| -rw-r--r-- | engines/macventure/macventure.h | 24 | ||||
| -rw-r--r-- | engines/macventure/script.cpp | 994 | ||||
| -rw-r--r-- | engines/macventure/script.h | 188 | ||||
| -rw-r--r-- | engines/macventure/world.cpp | 54 | ||||
| -rw-r--r-- | engines/macventure/world.h | 17 | 
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(); | 
