diff options
| -rw-r--r-- | engines/gob/detection.cpp | 2 | ||||
| -rw-r--r-- | engines/gob/gob.cpp | 14 | ||||
| -rw-r--r-- | engines/gob/gob.h | 3 | ||||
| -rw-r--r-- | engines/gob/inter.h | 38 | ||||
| -rw-r--r-- | engines/gob/inter_v6.cpp | 866 | ||||
| -rw-r--r-- | engines/gob/module.mk | 2 | ||||
| -rw-r--r-- | engines/gob/parse.h | 6 | ||||
| -rw-r--r-- | engines/gob/parse_v1.cpp | 2 | ||||
| -rw-r--r-- | engines/gob/parse_v2.cpp | 122 | ||||
| -rw-r--r-- | engines/gob/video.h | 9 | ||||
| -rw-r--r-- | engines/gob/video_v6.cpp | 69 | 
11 files changed, 1099 insertions, 34 deletions
| diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 2de645ad76..6943301602 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -1798,7 +1798,7 @@ static const GOBGameDescription gameDescriptions[] = {  			kPlatformPC,  			Common::ADGF_NO_FLAGS  		}, -		kGameTypeDynasty, +		kGameTypeUrban,  		kFeatures640,  		"intro"  	}, diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 8057402985..bfe0756307 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -403,6 +403,20 @@ bool GobEngine::initGameParts() {  			_saveLoad = new SaveLoad_v4(this, _targetName.c_str());  			break; +		case kGameTypeUrban: +			_init = new Init_v3(this); +			_video = new Video_v6(this); +			_inter = new Inter_v6(this); +			_parse = new Parse_v2(this); +			_mult = new Mult_v2(this); +			_draw = new Draw_v2(this); +			_game = new Game_v2(this); +			_map = new Map_v4(this); +			_goblin = new Goblin_v4(this); +			_scenery = new Scenery_v2(this); +			_saveLoad = new SaveLoad_v4(this, _targetName.c_str()); +			break; +  		default:  			deinitGameParts();  			return false; diff --git a/engines/gob/gob.h b/engines/gob/gob.h index a48a99ec42..39950e3261 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -94,7 +94,8 @@ enum GameType {  	kGameTypeWeen,  	kGameTypeLostInTime,  	kGameTypeInca2, -	kGameTypeDynasty +	kGameTypeDynasty, +	kGameTypeUrban  };  enum Features { diff --git a/engines/gob/inter.h b/engines/gob/inter.h index ad59d0d15a..fe31722c6c 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -587,6 +587,44 @@ protected:  	void o5_gob200(OpGobParams ¶ms);  }; +class Inter_v6 : public Inter_v5 { +public: +	Inter_v6(GobEngine *vm); +	virtual ~Inter_v6() {} + +protected: +	typedef void (Inter_v6::*OpcodeDrawProcV6)(); +	typedef bool (Inter_v6::*OpcodeFuncProcV6)(OpFuncParams &); +	typedef void (Inter_v6::*OpcodeGoblinProcV6)(OpGobParams &); +	struct OpcodeDrawEntryV6 { +		OpcodeDrawProcV6 proc; +		const char *desc; +	}; +	struct OpcodeFuncEntryV6 { +		OpcodeFuncProcV6 proc; +		const char *desc; +	}; +	struct OpcodeGoblinEntryV6 { +		OpcodeGoblinProcV6 proc; +		const char *desc; +	}; +	const OpcodeDrawEntryV6 *_opcodesDrawV6; +	const OpcodeFuncEntryV6 *_opcodesFuncV6; +	const OpcodeGoblinEntryV6 *_opcodesGoblinV6; +	static const int _goblinFuncLookUp[][2]; + +	virtual void setupOpcodes(); +	virtual void executeDrawOpcode(byte i); +	virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); +	virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); +	virtual const char *getOpcodeDrawDesc(byte i); +	virtual const char *getOpcodeFuncDesc(byte i, byte j); +	virtual const char *getOpcodeGoblinDesc(int i); + +	bool o6_loadCursor(OpFuncParams ¶ms); +	bool o6_evaluateStore(OpFuncParams ¶ms); +}; +  } // End of namespace Gob  #endif // GOB_INTER_H diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp new file mode 100644 index 0000000000..d27bcc64b5 --- /dev/null +++ b/engines/gob/inter_v6.cpp @@ -0,0 +1,866 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/endian.h" +#include "common/file.h" + +#include "gob/gob.h" +#include "gob/inter.h" +#include "gob/global.h" +#include "gob/game.h" +#include "gob/parse.h" +#include "gob/draw.h" + +namespace Gob { + +#define OPCODE(x) _OPCODE(Inter_v6, x) + +const int Inter_v6::_goblinFuncLookUp[][2] = { +	{0, 0}, +	{1, 0}, +	{80, 1}, +	{81, 2}, +	{82, 3}, +	{83, 4}, +	{84, 5}, +	{85, 6}, +	{86, 7}, +	{87, 0}, +	{88, 0}, +	{89, 0}, +	{90, 0}, +	{91, 0}, +	{92, 8}, +	{93, 0}, +	{94, 0}, +	{95, 9}, +	{96, 10}, +	{97, 11}, +	{98, 12}, +	{99, 0}, +	{100, 13}, +	{200, 14}, +	{30, 24}, +	{32, 25}, +	{33, 26}, +	{34, 27}, +	{35, 28}, +	{36, 29}, +	{37, 30}, +	{40, 31}, +	{41, 32}, +	{42, 33}, +	{43, 34}, +	{44, 35}, +	{50, 36}, +	{52, 37}, +	{53, 38}, +	{100, 39}, +	{152, 40}, +	{200, 41}, +	{201, 42}, +	{202, 43}, +	{203, 44}, +	{204, 45}, +	{250, 46}, +	{251, 47}, +	{252, 48}, +	{500, 49}, +	{502, 50}, +	{503, 51}, +	{600, 52}, +	{601, 53}, +	{602, 54}, +	{603, 55}, +	{604, 56}, +	{605, 57}, +	{1000, 58}, +	{1001, 59}, +	{1002, 60}, +	{1003, 61}, +	{1004, 62}, +	{1005, 63}, +	{1006, 64}, +	{1008, 65}, +	{1009, 66}, +	{1010, 67}, +	{1011, 68}, +	{1015, 69}, +	{2005, 70} +}; + +Inter_v6::Inter_v6(GobEngine *vm) : Inter_v5(vm) { +	setupOpcodes(); +} + +void Inter_v6::setupOpcodes() { +	static const OpcodeDrawEntryV6 opcodesDraw[256] = { +		/* 00 */ +		OPCODE(o1_loadMult), +		OPCODE(o2_playMult), +		OPCODE(o2_freeMultKeys), +		{NULL, ""}, +		/* 04 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		OPCODE(o1_initCursor), +		/* 08 */ +		OPCODE(o1_initCursorAnim), +		OPCODE(o1_clearCursorAnim), +		OPCODE(o2_setRenderFlags), +		{NULL, ""}, +		/* 0C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 10 */ +		OPCODE(o1_loadAnim), +		OPCODE(o1_freeAnim), +		OPCODE(o1_updateAnim), +		OPCODE(o2_multSub), +		/* 14 */ +		OPCODE(o2_initMult), +		OPCODE(o1_freeMult), +		OPCODE(o1_animate), +		OPCODE(o2_loadMultObject), +		/* 18 */ +		OPCODE(o1_getAnimLayerInfo), +		OPCODE(o1_getObjAnimSize), +		OPCODE(o1_loadStatic), +		OPCODE(o1_freeStatic), +		/* 1C */ +		OPCODE(o2_renderStatic), +		OPCODE(o2_loadCurLayer), +		{NULL, ""}, +		{NULL, ""}, +		/* 20 */ +		OPCODE(o2_playCDTrack), +		OPCODE(o2_waitCDTrackEnd), +		OPCODE(o2_stopCD), +		OPCODE(o2_readLIC), +		/* 24 */ +		OPCODE(o2_freeLIC), +		OPCODE(o2_getCDTrackPos), +		{NULL, ""}, +		{NULL, ""}, +		/* 28 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 2C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 30 */ +		OPCODE(o2_loadFontToSprite), +		OPCODE(o1_freeFontToSprite), +		{NULL, ""}, +		{NULL, ""}, +		/* 34 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 38 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 3C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 40 */ +		OPCODE(o2_totSub), +		OPCODE(o2_switchTotSub), +		OPCODE(o2_copyVars), +		OPCODE(o2_pasteVars), +		/* 44 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 48 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 4C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 50 */ +		OPCODE(o2_loadMapObjects), +		OPCODE(o2_freeGoblins), +		OPCODE(o2_moveGoblin), +		OPCODE(o2_writeGoblinPos), +		/* 54 */ +		OPCODE(o2_stopGoblin), +		OPCODE(o2_setGoblinState), +		OPCODE(o2_placeGoblin), +		{NULL, ""}, +		/* 58 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 5C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 60 */ +		{NULL, ""}, +		OPCODE(o5_deleteFile), +		{NULL, ""}, +		{NULL, ""}, +		/* 64 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 68 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 6C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 70 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 74 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 78 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 7C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 80 */ +		OPCODE(o4_initScreen), +		OPCODE(o2_scroll), +		OPCODE(o2_setScrollOffset), +		OPCODE(o4_playVmdOrMusic), +		/* 84 */ +		OPCODE(o2_getImdInfo), +		OPCODE(o2_openItk), +		OPCODE(o2_closeItk), +		OPCODE(o2_setImdFrontSurf), +		/* 88 */ +		OPCODE(o2_resetImdFrontSurf), +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 8C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 90 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 94 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 98 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 9C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* A0 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* A4 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* A8 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* AC */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* B0 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* B4 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* B8 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* BC */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* C0 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* C4 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* C8 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* CC */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* D0 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* D4 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* D8 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* DC */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* E0 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* E4 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* E8 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* EC */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* F0 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* F4 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* F8 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* FC */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""} +	}; + +	static const OpcodeFuncEntryV6 opcodesFunc[80] = { +		/* 00 */ +		OPCODE(o1_callSub), +		OPCODE(o1_callSub), +		OPCODE(o1_printTotText), +		OPCODE(o6_loadCursor), +		/* 04 */ +		{NULL, ""}, +		OPCODE(o1_switch), +		OPCODE(o1_repeatUntil), +		OPCODE(o1_whileDo), +		/* 08 */ +		OPCODE(o1_if), +		OPCODE(o6_evaluateStore), +		OPCODE(o1_loadSpriteToPos), +		{NULL, ""}, +		/* 0C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 10 */ +		{NULL, ""}, +		OPCODE(o2_printText), +		OPCODE(o1_loadTot), +		OPCODE(o1_palLoad), +		/* 14 */ +		OPCODE(o1_keyFunc), +		OPCODE(o1_capturePush), +		OPCODE(o1_capturePop), +		OPCODE(o2_animPalInit), +		/* 18 */ +		OPCODE(o2_addCollision), +		OPCODE(o2_freeCollision), +		OPCODE(o3_getTotTextItemPart), +		{NULL, ""}, +		/* 1C */ +		{NULL, ""}, +		{NULL, ""}, +		OPCODE(o1_drawOperations), +		OPCODE(o1_setcmdCount), +		/* 20 */ +		OPCODE(o1_return), +		OPCODE(o1_renewTimeInVars), +		OPCODE(o1_speakerOn), +		OPCODE(o1_speakerOff), +		/* 24 */ +		OPCODE(o1_putPixel), +		OPCODE(o2_goblinFunc), +		OPCODE(o2_createSprite), +		OPCODE(o1_freeSprite), +		/* 28 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 2C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 30 */ +		OPCODE(o1_returnTo), +		OPCODE(o1_loadSpriteContent), +		OPCODE(o1_copySprite), +		OPCODE(o1_fillRect), +		/* 34 */ +		OPCODE(o1_drawLine), +		OPCODE(o1_strToLong), +		OPCODE(o1_invalidate), +		OPCODE(o1_setBackDelta), +		/* 38 */ +		OPCODE(o1_playSound), +		OPCODE(o2_stopSound), +		OPCODE(o2_loadSound), +		OPCODE(o1_freeSoundSlot), +		/* 3C */ +		OPCODE(o1_waitEndPlay), +		OPCODE(o1_playComposition), +		OPCODE(o2_getFreeMem), +		OPCODE(o2_checkData), +		/* 40 */ +		{NULL, ""}, +		OPCODE(o1_prepareStr), +		OPCODE(o1_insertStr), +		OPCODE(o1_cutStr), +		/* 44 */ +		OPCODE(o1_strstr), +		OPCODE(o5_istrlen), +		OPCODE(o1_setMousePos), +		OPCODE(o1_setFrameRate), +		/* 48 */ +		OPCODE(o1_animatePalette), +		OPCODE(o1_animateCursor), +		OPCODE(o1_blitCursor), +		OPCODE(o1_loadFont), +		/* 4C */ +		OPCODE(o1_freeFont), +		OPCODE(o2_readData), +		OPCODE(o2_writeData), +		OPCODE(o1_manageDataFile), +	}; + +	static const OpcodeGoblinEntryV6 opcodesGoblin[71] = { +		/* 00 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 04 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 08 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 0C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 10 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 14 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 18 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 1C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 20 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 24 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 28 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 2C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 30 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 34 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 38 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 3C */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 40 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +		/* 44 */ +		{NULL, ""}, +		{NULL, ""}, +		{NULL, ""}, +	}; + +	_opcodesDrawV6 = opcodesDraw; +	_opcodesFuncV6 = opcodesFunc; +	_opcodesGoblinV6 = opcodesGoblin; +} + +void Inter_v6::executeDrawOpcode(byte i) { +	debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", +			i, i, getOpcodeDrawDesc(i)); + +	OpcodeDrawProcV6 op = _opcodesDrawV6[i].proc; + +	if (op == NULL) +		warning("unimplemented opcodeDraw: %d", i); +	else +		(this->*op) (); +} + +bool Inter_v6::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { +	debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s) - %s, %d, %d", +			i, j, i, j, getOpcodeFuncDesc(i, j), _vm->_game->_curTotFile, +			(uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData), +			(uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData - params.counter - 4)); + +	if ((i > 4) || (j > 15)) { +		warning("unimplemented opcodeFunc: %d.%d", i, j); +		return false; +	} + +	OpcodeFuncProcV6 op = _opcodesFuncV6[i*16 + j].proc; + +	if (op == NULL) +		warning("unimplemented opcodeFunc: %d.%d", i, j); +	else +		return (this->*op) (params); + +	return false; +} + +void Inter_v6::executeGoblinOpcode(int i, OpGobParams ¶ms) { +	debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", +			i, i, getOpcodeGoblinDesc(i)); + +	OpcodeGoblinProcV6 op = NULL; + +	for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) +		if (_goblinFuncLookUp[j][0] == i) { +			op = _opcodesGoblinV6[_goblinFuncLookUp[j][1]].proc; +			break; +		} + +	_vm->_global->_inter_execPtr -= 2; + +	if (op == NULL) { +		warning("unimplemented opcodeGoblin: %d", i); + +		int16 paramCount = load16(); +		_vm->_global->_inter_execPtr += paramCount * 2; +	} else { +		params.extraData = i; + +		(this->*op) (params); +	} +} + +const char *Inter_v6::getOpcodeDrawDesc(byte i) { +	return _opcodesDrawV6[i].desc; +} + +const char *Inter_v6::getOpcodeFuncDesc(byte i, byte j) { +	if ((i > 4) || (j > 15)) +		return ""; + +	return _opcodesFuncV6[i*16 + j].desc; +} + +const char *Inter_v6::getOpcodeGoblinDesc(int i) { +	for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) +		if (_goblinFuncLookUp[j][0] == i) +			return _opcodesGoblinV6[_goblinFuncLookUp[j][1]].desc; +	return ""; +} + +bool Inter_v6::o6_loadCursor(OpFuncParams ¶ms) { +	Game::TotResItem *itemPtr; +	int16 width, height; +	byte *dataBuf; +	int32 offset; +	int16 id; +	int8 index; + +	id = load16(); + +	if (id == -1) { +		byte str[10]; + +		for (int i = 0; i < 9; i++) +			str[i] = *_vm->_global->_inter_execPtr++; + +		str[9] = '\0'; + +		uint16 var1 = load16(); +		int8 var2 = *_vm->_global->_inter_execPtr++; + +		warning("Urban Stub: loadCursor %d: \"%s\", %d, %d", id, str, var1, var2); + +	} else if (id == -2) { + +		uint16 var1 = load16(); +		uint16 var2 = load16(); +		int8 var3 = *_vm->_global->_inter_execPtr++; + +		warning("Urban Stub: loadCursor %d: %d, %d, %d", id, var1, var2, var3); + +	} else { +		index = (int8) *_vm->_global->_inter_execPtr++; + +		if ((index * _vm->_draw->_cursorWidth) >= _vm->_draw->_cursorSprites->getWidth()) +			return false; + +		itemPtr = &_vm->_game->_totResourceTable->items[id]; +		offset = itemPtr->offset; + +		if (offset < 0) { +			offset = (-offset - 1) * 4; +			dataBuf = _vm->_game->_imFileData + +				(int32) READ_LE_UINT32(_vm->_game->_imFileData + offset); +		} else +			dataBuf = _vm->_game->_totResourceTable->dataPtr + szGame_TotResTable + +				szGame_TotResItem * _vm->_game->_totResourceTable->itemsCount + +				offset; + +		width = itemPtr->width; +		height = itemPtr->height; + +		_vm->_video->fillRect(_vm->_draw->_cursorSprites, +				index * _vm->_draw->_cursorWidth, 0, +				index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, +				_vm->_draw->_cursorHeight - 1, 0); + +		_vm->_video->drawPackedSprite(dataBuf, width, height, +				index * _vm->_draw->_cursorWidth, 0, 0, _vm->_draw->_cursorSprites); +		_vm->_draw->_cursorAnimLow[index] = 0; +	} + +	return false; +} + +bool Inter_v6::o6_evaluateStore(OpFuncParams ¶ms) { +	byte *savedPos; +	int16 varOff; +	int16 token; +	int16 result; +	byte loopCount; +	uint16 var_6, var_A; + +	varOff = _vm->_parse->parseVarIndex(&var_6, &var_A); + +	if (var_6 != 0) { +		int16 var_4; + +		savedPos = _vm->_global->_inter_execPtr; + +		var_4 = _vm->_parse->parseVarIndex(&var_6, 0); + +		memcpy(_vm->_inter->_variables->getAddressOff8(varOff), +				_vm->_inter->_variables->getAddressOff8(var_4), var_6 * 4); + +		_vm->_global->_inter_execPtr = savedPos; +		evalExpr(&var_4); + +		return false; +	} + +	if (*_vm->_global->_inter_execPtr == 98) { +		_vm->_global->_inter_execPtr++; +		loopCount = *_vm->_global->_inter_execPtr++; + +		for (int i = 0; i < loopCount; i++) { +			uint8 c = *_vm->_global->_inter_execPtr++; +			uint16 n = load16(); + +			memset(_vm->_inter->_variables->getAddressOff8(varOff), c, n); + +			varOff += n; +		} + +		return false; + +	} else if (*_vm->_global->_inter_execPtr == 99) { +		_vm->_global->_inter_execPtr++; +		loopCount = *_vm->_global->_inter_execPtr++; +	} else +		loopCount = 1; + +	for (int i = 0; i < loopCount; i++) { +		token = evalExpr(&result); +		switch (var_A) { +		case 16: +		case 18: +			WRITE_VARO_UINT8(varOff + i, _vm->_global->_inter_resVal); +			break; + +		case 17: +		case 27: +			WRITE_VARO_UINT16(varOff + i * 2, _vm->_global->_inter_resVal); +			break; + +		case 23: +		case 26: +			WRITE_VAR_OFFSET(varOff + i * 4, _vm->_global->_inter_resVal); +			break; + +		case 24: +			WRITE_VARO_UINT16(varOff + i * 4, _vm->_global->_inter_resVal); +			break; + +		case 25: +		case 28: +			if (token == 20) +				WRITE_VARO_UINT8(varOff, result); +			else +				WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr); +			break; +		} +	} + +	return false; +} + +} // End of namespace Gob diff --git a/engines/gob/module.mk b/engines/gob/module.mk index c69f76b2c3..3ec542934f 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -31,6 +31,7 @@ MODULE_OBJS := \  	inter_v3.o \  	inter_v4.o \  	inter_v5.o \ +	inter_v6.o \  	map.o \  	map_v1.o \  	map_v2.o \ @@ -54,6 +55,7 @@ MODULE_OBJS := \  	video.o \  	video_v1.o \  	video_v2.o \ +	video_v6.o \  	sound/sound.o \  	sound/sounddesc.o \  	sound/pcspeaker.o \ diff --git a/engines/gob/parse.h b/engines/gob/parse.h index 7d451b5f79..15ec78b57f 100644 --- a/engines/gob/parse.h +++ b/engines/gob/parse.h @@ -33,7 +33,7 @@ public:  	void skipExpr(char stopToken);  	void printExpr(char stopToken);  	void printVarIndex(void); -	virtual int16 parseVarIndex(void) = 0; +	virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0) = 0;  	virtual int16 parseValExpr(byte stopToken = 99) = 0;  	virtual int16 parseExpr(byte stopToken, byte *resultPtr) = 0; @@ -60,7 +60,7 @@ public:  	Parse_v1(GobEngine *vm);  	virtual ~Parse_v1() {} -	virtual int16 parseVarIndex(void); +	virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0);  	virtual int16 parseValExpr(byte stopToken = 99);  	virtual int16 parseExpr(byte stopToken, byte *resultPtr);  }; @@ -70,7 +70,7 @@ public:  	Parse_v2(GobEngine *vm);  	virtual ~Parse_v2() {} -	virtual int16 parseVarIndex(void); +	virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0);  	virtual int16 parseValExpr(byte stopToken = 99);  	virtual int16 parseExpr(byte stopToken, byte *resultPtr);  }; diff --git a/engines/gob/parse_v1.cpp b/engines/gob/parse_v1.cpp index 3c5f90c068..ed8868397a 100644 --- a/engines/gob/parse_v1.cpp +++ b/engines/gob/parse_v1.cpp @@ -35,7 +35,7 @@ namespace Gob {  Parse_v1::Parse_v1(GobEngine *vm) : Parse(vm) {  } -int16 Parse_v1::parseVarIndex() { +int16 Parse_v1::parseVarIndex(uint16 *arg_0, uint16 *arg_4) {  	int16 temp2;  	byte *arrDesc;  	int16 dim; diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp index f26d051ab5..347a253204 100644 --- a/engines/gob/parse_v2.cpp +++ b/engines/gob/parse_v2.cpp @@ -35,7 +35,7 @@ namespace Gob {  Parse_v2::Parse_v2(GobEngine *vm) : Parse_v1(vm) {  } -int16 Parse_v2::parseVarIndex() { +int16 Parse_v2::parseVarIndex(uint16 *arg_0, uint16 *arg_4) {  	int16 temp2;  	byte *arrDesc;  	int16 dim; @@ -44,8 +44,74 @@ int16 Parse_v2::parseVarIndex() {  	int16 temp;  	int16 offset;  	int16 val; +	uint32 varPos = 0;  	operation = *_vm->_global->_inter_execPtr++; + +	while ((operation == 14) || (operation == 15)) { +		if (operation == 14) { +			uint16 n = _vm->_inter->load16(); +			varPos += n * 4; + +			if (arg_0) +				*arg_0 = READ_LE_UINT16(_vm->_global->_inter_execPtr); +			if (arg_4) +				*arg_4 = 14; + +			_vm->_global->_inter_execPtr += 2; +			if (*_vm->_global->_inter_execPtr == 97) +				_vm->_global->_inter_execPtr++; +		} else if (operation == 15) { +			uint16 n = _vm->_inter->load16(); +			varPos += n * 4; + +			uint16 var_0C = _vm->_inter->load16(); +			if (arg_0) +				*arg_0 = var_0C; +			if (arg_4) +				*arg_4 = 15; + +			uint8 var_A = *_vm->_global->_inter_execPtr++; + +			byte *var_12 = _vm->_global->_inter_execPtr; +			_vm->_global->_inter_execPtr += var_A; + +			uint16 var_6 = 0; + +			for (int i = 0; i < var_A; i++) { +				temp2 = parseValExpr(12); + +				//uint16 ax = sub_12063(temp2, var_12[i], varPos, 0); + +				uint16 ax; + +				if (temp2 < 0) { +					ax = 0; +				} else if (var_12[i] > temp2) { +					ax = temp2; +				} else { +					ax = var_12[i] - 1; +				} + +				var_6 = var_6 * var_12[i] + ax; +			} + +			varPos += var_6 * var_0C * 4; + +			if (*_vm->_global->_inter_execPtr == 97) +				_vm->_global->_inter_execPtr++; +		} + +		warning("v5+ Stub: parseVarIndex operation %d, offset %d", operation, varPos); + +		operation = *_vm->_global->_inter_execPtr++; +	} + +	if (arg_0) +		*arg_0 = 0; +	if (arg_4) +		*arg_4 = operation; +  	debugC(5, kDebugParser, "var parse = %d", operation);  	switch (operation) {  	case 16: @@ -62,24 +128,24 @@ int16 Parse_v2::parseVarIndex() {  			offset = arrDesc[dim] * offset + temp2;  		}  		if (operation == 16) -			return temp + offset; +			return varPos + temp + offset;  		if (operation == 26) -			return (temp + offset) * 4; +			return varPos + (temp + offset) * 4;  		if (operation == 27) -			return (temp + offset) * 2; +			return varPos + (temp + offset) * 2;  		temp *= 4;  		offset *= 4;  		if (*_vm->_global->_inter_execPtr == 13) {  			_vm->_global->_inter_execPtr++;  			temp += parseValExpr(12);  		} -		return offset * _vm->_global->_inter_animDataSize + temp; +		return varPos + offset * _vm->_global->_inter_animDataSize + temp;  	case 17: -		return _vm->_inter->load16() * 2; +		return varPos + _vm->_inter->load16() * 2;  	case 18: -		return _vm->_inter->load16(); +		return varPos + _vm->_inter->load16();  	case 23:  	case 24: @@ -93,7 +159,7 @@ int16 Parse_v2::parseVarIndex() {  			temp += val;  			debugC(5, kDebugParser, "parse subscript = %d", val);  		} -		return temp; +		return varPos + temp;  	default:  		return 0; @@ -203,29 +269,29 @@ int16 Parse_v2::parseValExpr(byte stopToken) {  					offset = arrDesc[dim] * offset + temp2;  				}  				if (operation == 16) -					*valPtr = (int8) READ_VARO_UINT8(temp + offset); +					*valPtr = (int8) READ_VARO_UINT8(varPos + temp + offset);  				else if (operation == 26) -					*valPtr = (uint16) READ_VARO_UINT32(temp * 4 + offset * 4); +					*valPtr = (uint16) READ_VARO_UINT32(varPos + temp * 4 + offset * 4);  				else if (operation == 27) -					*valPtr = READ_VARO_UINT16(temp * 2 + offset * 2); +					*valPtr = READ_VARO_UINT16(varPos + temp * 2 + offset * 2);  				else if (operation == 28) {  					_vm->_global->_inter_execPtr++;  					temp2 = parseValExpr(12); -					*valPtr = READ_VARO_UINT8(temp * 4 + +					*valPtr = READ_VARO_UINT8(varPos + temp * 4 +  							offset * 4 * _vm->_global->_inter_animDataSize + temp2);  				}  				break;  			case 17: -				*valPtr = READ_VARO_UINT16(_vm->_inter->load16() * 2); +				*valPtr = READ_VARO_UINT16(varPos + _vm->_inter->load16() * 2);  				break;  			case 18: -				*valPtr = (int8) READ_VARO_UINT8(_vm->_inter->load16()); +				*valPtr = (int8) READ_VARO_UINT8(varPos + _vm->_inter->load16());  				break;  			case 19: -				*valPtr = (uint16) READ_LE_UINT32(_vm->_global->_inter_execPtr); +				*valPtr = (uint16) READ_LE_UINT32(varPos + _vm->_global->_inter_execPtr);  				_vm->_global->_inter_execPtr += 4;  				break; @@ -242,14 +308,14 @@ int16 Parse_v2::parseValExpr(byte stopToken) {  				break;  			case 24: -				*valPtr = READ_VARO_UINT16(_vm->_inter->load16() * 4); +				*valPtr = READ_VARO_UINT16(varPos + _vm->_inter->load16() * 4);  				break;  			case 25:  				temp = _vm->_inter->load16() * 4;  				_vm->_global->_inter_execPtr++;  				temp += parseValExpr(12); -				*valPtr = READ_VARO_UINT8(temp); +				*valPtr = READ_VARO_UINT8(varPos + temp);  				break;  			case 29: @@ -505,20 +571,20 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) {  					offset = offset * arrDescPtr[dim] + temp2;  				}  				if (operation == 16) -					*valPtr = (int8) READ_VARO_UINT8(temp + offset); +					*valPtr = (int8) READ_VARO_UINT8(varPos + temp + offset);  				else if (operation == 26) -					*valPtr = READ_VARO_UINT32(temp * 4 + offset * 4); +					*valPtr = READ_VARO_UINT32(varPos + temp * 4 + offset * 4);  				else if (operation == 27) -					*valPtr = (int16) READ_VARO_UINT16(temp * 2 + offset * 2); +					*valPtr = (int16) READ_VARO_UINT16(varPos + temp * 2 + offset * 2);  				else if (operation == 28) {  					*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8( -								temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, 0), +								varPos + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, 0),  							kInterVar);  					if (*_vm->_global->_inter_execPtr == 13) {  						_vm->_global->_inter_execPtr++;  						temp2 = parseValExpr(12);  						*operPtr = 20; -						*valPtr = READ_VARO_UINT8(temp * 4 + +						*valPtr = READ_VARO_UINT8(varPos + temp * 4 +  								offset * 4 * _vm->_global->_inter_animDataSize + temp2);  					}  				} @@ -526,17 +592,17 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) {  			case 17:  				*operPtr = 20; -				*valPtr = (int16) READ_VARO_UINT16(_vm->_inter->load16() * 2); +				*valPtr = (int16) READ_VARO_UINT16(varPos + _vm->_inter->load16() * 2);  				break;  			case 18:  				*operPtr = 20; -				*valPtr = (int8) READ_VARO_UINT8(_vm->_inter->load16()); +				*valPtr = (int8) READ_VARO_UINT8(varPos + _vm->_inter->load16());  				break;  			case 19:  				*operPtr = 20; -				*valPtr = READ_LE_UINT32(_vm->_global->_inter_execPtr); +				*valPtr = READ_LE_UINT32(varPos + _vm->_global->_inter_execPtr);  				_vm->_global->_inter_execPtr += 4;  				break; @@ -564,18 +630,18 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) {  			case 24:  				*operPtr = 20; -				*valPtr = (int16) READ_VARO_UINT16(_vm->_inter->load16() * 4); +				*valPtr = (int16) READ_VARO_UINT16(varPos + _vm->_inter->load16() * 4);  				break;  			case 25:  				*operPtr = 22;  				temp = _vm->_inter->load16() * 4; -				*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(temp, 0), kInterVar); +				*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(varPos + temp, 0), kInterVar);  				if (*_vm->_global->_inter_execPtr == 13) {  					_vm->_global->_inter_execPtr++;  					temp += parseValExpr(12);  					*operPtr = 20; -					*valPtr = READ_VARO_UINT8(temp); +					*valPtr = READ_VARO_UINT8(varPos + temp);  				}  				break; diff --git a/engines/gob/video.h b/engines/gob/video.h index 1338885588..e6baf9a67d 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -194,6 +194,15 @@ public:  	virtual ~Video_v2() {}  }; +class Video_v6 : public Video_v2 { +public: +	virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, +			int16 x, int16 y, int16 transp, SurfaceDesc *destDesc); + +	Video_v6(GobEngine *vm); +	virtual ~Video_v6() {} +}; +  class VideoDriver {  public:  	VideoDriver() {} diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp new file mode 100644 index 0000000000..434406265e --- /dev/null +++ b/engines/gob/video_v6.cpp @@ -0,0 +1,69 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/video.h" + +namespace Gob { + +Video_v6::Video_v6(GobEngine *vm) : Video_v2(vm) { +} + +char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, +	    int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) { +	if (!destDesc) +		return 1; + +	_vm->validateVideoMode(destDesc->_vidMode); + +	if (sprBuf[0] != 1) +		return 0; + +	if (sprBuf[1] != 3) +		return 0; + +	sprBuf += 2; + +	srcWidth = READ_LE_UINT16(sprBuf); +	sprBuf += 2; +	srcHeight = READ_LE_UINT16(sprBuf); +	sprBuf += 2; + +	if (sprBuf[0] == 0) { +		SurfaceDesc sourceDesc(0x13, srcWidth, srcHeight, sprBuf + 3); +		Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1, +		    srcHeight - 1, x, y, transp); +		return 1; +	} else { +		warning("Urban Stub: spriteUncompressor()"); +		return 0; +	} + +	return 1; +} + +} // End of namespace Gob | 
