[Scummvm-cvs-logs] SF.net SVN: scummvm: [23939] scummvm/trunk/engines/simon

kirben at users.sourceforge.net kirben at users.sourceforge.net
Tue Sep 19 13:59:31 CEST 2006


Revision: 23939
          http://svn.sourceforge.net/scummvm/?rev=23939&view=rev
Author:   kirben
Date:     2006-09-19 04:59:13 -0700 (Tue, 19 Sep 2006)

Log Message:
-----------
Expand Simon engine

Modified Paths:
--------------
    scummvm/trunk/engines/simon/debug.cpp
    scummvm/trunk/engines/simon/debug.h
    scummvm/trunk/engines/simon/draw.cpp
    scummvm/trunk/engines/simon/game.cpp
    scummvm/trunk/engines/simon/intern.h
    scummvm/trunk/engines/simon/items.cpp
    scummvm/trunk/engines/simon/midiparser_s1d.cpp
    scummvm/trunk/engines/simon/res.cpp
    scummvm/trunk/engines/simon/simon.cpp
    scummvm/trunk/engines/simon/simon.h
    scummvm/trunk/engines/simon/subroutine.cpp
    scummvm/trunk/engines/simon/vga.cpp
    scummvm/trunk/engines/simon/vga.h

Modified: scummvm/trunk/engines/simon/debug.cpp
===================================================================
--- scummvm/trunk/engines/simon/debug.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/debug.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -48,8 +48,10 @@
 		st = s = simon1talkie_opcode_name_table[opcode];
 	} else if (getGameType() == GType_SIMON2) {
 		st = s = simon2dos_opcode_name_table[opcode];
+	} else if (getGameType() == GType_SIMON1) {
+		st = s = simon1dos_opcode_name_table[opcode];
 	} else {
-		st = s = simon1dos_opcode_name_table[opcode];
+		st = s = ww_opcode_name_table[opcode];
 	}
 	if (s == NULL) {
 		//error("INVALID OPCODE %d", opcode);
@@ -178,7 +180,7 @@
 	const char *str, *strn;
 
 	do {
-		if (getGameType() == GType_SIMON1) {
+		if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
 			opcode = READ_BE_UINT16(src);
 			src += 2;
 		} else {
@@ -194,8 +196,10 @@
 			strn = str = feeblefiles_video_opcode_name_table[opcode];
 		} else if (getGameType() == GType_SIMON2) {
 			strn = str = simon2_video_opcode_name_table[opcode];
+		} else if (getGameType() == GType_SIMON1) {
+			strn = str = simon1_video_opcode_name_table[opcode];
 		} else {
-			strn = str = simon1_video_opcode_name_table[opcode];
+			strn = str = ww_video_opcode_name_table[opcode];
 		}
 
 		while (*strn != '|')

Modified: scummvm/trunk/engines/simon/debug.h
===================================================================
--- scummvm/trunk/engines/simon/debug.h	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/debug.h	2006-09-19 11:59:13 UTC (rev 23939)
@@ -26,6 +26,244 @@
 
 namespace Simon {
 
+static const char *const ww_opcode_name_table[256] = {
+	/* 0 */
+	"|NOT",
+	"IJ|AT",
+	"IJ|NOT_AT",
+	NULL,
+	/* 4 */
+	NULL,
+	"IJ|CARRIED",
+	"IJ|NOT_CARRIED",
+	"IIJ|IS_AT",
+	/* 8 */
+	NULL,
+	NULL,
+	NULL,
+	"VJ|IS_ZERO",
+	/* 12 */
+	"VJ|ISNOT_ZERO",
+	"VWJ|IS_EQ",
+	"VWJ|IS_NEQ",
+	"VWJ|IS_LE",
+	/* 16 */
+	"VWJ|IS_GE",
+	"VVJ|IS_EQF",
+	"VVJ|IS_NEQF",
+	"VVJ|IS_LEF",
+	/* 20 */
+	"VVJ|IS_GEF",
+	NULL,
+	NULL,
+	"WJ|CHANCE",
+	/* 24 */
+	NULL,
+	"IJ|IS_ROOM",
+	"IJ|IS_OBJECT",
+	"IWJ|ITEM_STATE_IS",
+	/* 28 */
+	"IBJ|OBJECT_HAS_FLAG",
+	NULL,
+	NULL,
+	"I|SET_NO_PARENT",
+	/* 32 */
+	NULL,
+	"II|SET_PARENT",
+	NULL,
+	NULL,
+	/* 36 */
+	"VV|MOVE",
+	NULL,
+	NULL,
+	NULL,
+	/* 40 */
+	NULL,
+	"V|ZERO",
+	"VW|SET",
+	"VW|ADD",
+	/* 44 */
+	"VW|SUB",
+	"VV|ADDF",
+	"VV|SUBF",
+	"VW|MUL",
+	/* 48 */
+	"VW|DIV",
+	"VV|MULF",
+	"VV|DIVF",
+	"VW|MOD",
+	/* 52 */
+	"VV|MODF",
+	"VW|RANDOM",
+	NULL,
+	"I|SET_A_PARENT",
+	/* 56 */
+	"IB|SET_CHILD2_BIT",
+	"IB|CLEAR_CHILD2_BIT",
+	"II|MAKE_SIBLING",
+	"I|INC_STATE",
+	/* 60 */
+	"I|DEC_STATE",
+	"IW|SET_STATE",
+	"V|SHOW_INT",
+	"T|SHOW_STRING_NL",
+	/* 64 */
+	"T|SHOW_STRING",
+	"WWWWWB|ADD_TEXT_BOX",
+	"BT|SET_SHORT_TEXT",
+	"BT|SET_LONG_TEXT",
+	/* 68 */
+	"x|END",
+	"x|DONE",
+	"V|SHOW_STRING_AR3",
+	"W|START_SUB",
+	/* 72 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	/* 76 */
+	"WW|ADD_TIMEOUT",
+	"J|IS_M1_EMPTY",
+	"J|IS_M3_EMPTY",
+	"ITJ|CHILD_FR2_IS",
+	/* 80 */
+	"IIJ|IS_ITEM_EQ",
+	NULL,
+	"B|DEBUG",
+	"|RESCAN",
+	/* 84 */
+	NULL,
+	"IBB|WHERE_TO",
+	NULL,
+	"W|COMMENT",
+	/* 88 */
+	"|STOP_ANIMATION",
+	"|RESTART_ANIMATION",
+	"IB|GET_PARENT",
+	"IB|GET_NEXT",
+	/* 92 */
+	"IB|GET_CHILDREN",
+	NULL,
+	NULL,
+	NULL,
+	/* 96 */
+	"WB|PICTURE",
+	"W|LOAD_ZONE",
+	"WBWWW|ANIMATE",
+	"W|STOP_ANIMATE",
+	/* 100 */
+	"|KILL_ANIMATE",
+	"BWWWWWW|DEFINE_WINDOW",
+	"B|CHANGE_WINDOW",
+	"|CLS",
+	/* 104 */
+	"B|CLOSE_WINDOW",
+	"B|MENU",
+	"BB|TEXT_MENU",
+	"WWWWWIW|ADD_BOX",
+	/* 108 */
+	"W|DEL_BOX",
+	"W|ENABLE_BOX",
+	"W|DISABLE_BOX",
+	"WWW|MOVE_BOX",
+	/* 112 */
+	NULL,
+	NULL,
+	"IB|DO_ICONS",
+	"IBJ|IS_CLASS",
+	/* 116 */
+	"IB|SET_CLASS",
+	"IB|UNSET_CLASS",
+	NULL,
+	"W|WAIT_SYNC",
+	/* 120 */
+	"W|SYNC",
+	"BI|DEF_OBJ",
+	NULL,
+	NULL,
+	/* 124 */
+	NULL,
+	"IJ|IS_SIBLING_WITH_A",
+	"IBB|DO_CLASS_ICONS",
+	"WW|PLAY_TUNE",
+	/* 128 */
+	"W|WAIT_END_TUNE",
+	"W|IF_END_TUNE",
+	"Bww|SET_ADJ_NOUN",
+	NULL,
+	/* 132 */
+	"|SAVE_GAME",
+	"|LOAD_GAME",
+	"|DUMMYPROC_134",
+	"|QUIT_IF_USER_PRESSES_Y",
+	/* 136 */
+	"IV|COPY_SF",
+	"B|RESTORE_ICONS",
+	"|FREEZE_ZONES",
+	"II|SET_PARENT_SPECIAL",
+	/* 140 */
+	"|CLEAR_TIMERS",
+	"BI|SET_M1_OR_M3",
+	"WJ|IS_HITAREA_0x40_CLEAR",
+	"I|START_ITEM_SUB",
+	/* 144 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	/* 148 */
+	"IB|IF_DOOR_OPEN",
+	NULL,
+	NULL,
+	"BI|SET_ARRAY6_TO",
+	/* 152 */
+	"BB|SET_M1_M3_TO_ARRAY6",
+	"B|SET_BIT",
+	"B|CLEAR_BIT",
+	"BJ|IS_BIT_CLEAR",
+	/* 156 */
+	"BJ|IS_BIT_SET",
+	"IBB|GET_ITEM_PROP",
+	"IBW|SET_ITEM_PROP",
+	NULL,
+	/* 160 */
+	"B|SET_INK",
+	"BWBW|SETUP_TEXT",
+	"BBT|PRINT_STR",
+	"W|PLAY_EFFECT",
+	/* 164 */
+	"|getDollar2",
+	"IWWJ|IS_ADJ_NOUN",
+	"B|SET_BIT2",
+	"B|CLEAR_BIT2",
+	/* 168 */
+	"BJ|IS_BIT2_CLEAR",
+	"BJ|IS_BIT2_SET",
+	NULL,
+	NULL,
+	/* 172 */
+	NULL,
+	NULL,
+	NULL,
+	"|LOCK_ZONES",
+	/* 176 */
+	"|UNLOCK_ZONES",
+	"BBI|SCREEN_TEXT_POBJ",
+	"WWBB|GETPATHPOSN",
+	"IWWJ|IS_ADJ_NOUN",
+	/* 180 */
+	"B|SET_BIT2",
+	"B|CLEAR_BIT2",
+	"BJ|IS_BIT2_CLEAR",
+	"BJ|IS_BIT2_SET",
+	/* 184 */
+	"W|UNLOAD_ZONE",
+	"W|LOAD_SOUND_FILES",
+	"|UNFREEZE_ZONES",
+	"|FADE_TO_BLACK",
+};
+
 static const char *const simon1dos_opcode_name_table[256] = {
 	/* 0 */
 	"|NOT",
@@ -1239,6 +1477,89 @@
 	"B|B3_NOT_ZERO",
 };
 
+const char *const ww_video_opcode_name_table[] = {
+	/* 0 */
+	"x|RET",
+	"ddd|FADEOUT",
+	"d|CALL",
+	"ddddd|NEW_SPRITE",
+	/* 4 */
+	"ddd|FADEIN",
+	"vd|SKIP_IF_NEQ",
+	"d|SKIP_IFN_SIB_WITH_A",
+	"d|SKIP_IF_SIB_WITH_A",
+	/* 8 */
+	"dd|SKIP_IF_PARENT_IS",
+	"dd|SKIP_IF_UNK3_IS",
+	"dddd|DRAW",
+	"d|VC_11",
+	/* 12 */
+	"d|DELAY",
+	"d|SET_SPRITE_OFFSET_X",
+	"d|SET_SPRITE_OFFSET_Y",
+	"d|IDENT_WAKEUP",
+	/* 16 */
+	"d|IDENT_SLEEP",
+	"d|VC_17",
+	"i|JUMP_REL",
+	"|CHAIN_TO",
+	/* 20 */
+	"dd|SET_REPEAT",
+	"i|END_REPEAT",
+	"d|SET_PALETTE",
+	"d|SET_PRIORITY",
+	/* 24 */
+	"diid|SET_SPRITE_XY",
+	"x|HALT_SPRITE",
+	"ddddd|SET_WINDOW",
+	"|RESET",
+	/* 28 */
+	"dddd|PLAY_SOUND",
+	"|STOP_ALL_SOUNDS",
+	"d|SET_FRAME_RATE",
+	"d|SET_WINDOW",
+	/* 32 */
+	"|VC_32",
+	"|MOUSE_ON",
+	"|MOUSE_OFF",
+	"dd|CLEAR_WINDOW",
+	/* 36 */
+	"dd|SAVELOAD_THING",
+	"dd|VC_37",
+	"v|SKIP_IF_VAR_ZERO",
+	"vd|SET_VAR",
+	/* 40 */
+	"vd|ADD_VAR",
+	"vd|SUB_VAR",
+	"vd|DELAY_IF_NOT_EQ",
+	"d|SKIP_IF_BIT_CLEAR",
+	/* 44 */
+	"d|SKIP_IF_BIT_SET",
+	"dd|VC_45",
+	"v|SET_SPRITE_Y",
+	"d|VC_47",
+	/* 48 */
+	"d|VC_48",
+	"d|SET_BIT",
+	"d|CLEAR_BIT",
+	"d|ENABLE_BOX",
+	/* 52 */
+	"d|PLAY_EFFECT",
+	"dd|DUMMY_53",
+	"ddd|DUMMY_54",
+	"ddd|MOVE_BOX",
+	/* 56 */
+	"|FULL_SCREEN",
+	"|BLACK_PALETTE",
+	"|SET_PRIORITIES",
+	"|SKIP_IF_NOT_EGA",
+	/* 60 */
+	"d|STOP_ANIMATE",
+	"d|VC_61",
+	"|FASTFADEOUT",
+	"|FASTFADEIN",
+};
+
 const char *const simon1_video_opcode_name_table[] = {
 	/* 0 */
 	"x|RET",

Modified: scummvm/trunk/engines/simon/draw.cpp
===================================================================
--- scummvm/trunk/engines/simon/draw.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/draw.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -85,14 +85,20 @@
 		_vgaCurSpritePriority = vsp->priority;
 
 		params[0] = readUint16Wrapper(&vsp->image);
-		params[1] = readUint16Wrapper(&vsp->palette);
-		params[2] = readUint16Wrapper(&vsp->x);
-		params[3] = readUint16Wrapper(&vsp->y);
+		if (getGameType() == GType_WW) {
+			params[1] = readUint16Wrapper(&vsp->x);
+			params[2] = readUint16Wrapper(&vsp->y);
+			params[3] = READ_BE_UINT16(&vsp->flags);
+		} else {
+			params[1] = readUint16Wrapper(&vsp->palette);
+			params[2] = readUint16Wrapper(&vsp->x);
+			params[3] = readUint16Wrapper(&vsp->y);
 
-		if (getGameType() == GType_SIMON1) {
-			params[4] = READ_BE_UINT16(&vsp->flags);
-		} else {
-			*(byte *)(&params[4]) = (byte)vsp->flags;
+			if (getGameType() == GType_SIMON1) {
+				params[4] = READ_BE_UINT16(&vsp->flags);
+			} else {
+				*(byte *)(&params[4]) = (byte)vsp->flags;
+			}
 		}
 
 		_vcPtr = (const byte *)params;
@@ -132,10 +138,22 @@
 			printf("id:%5d image:%3d base-color:%3d x:%3d y:%3d flags:%x\n",
 							vsp->id, vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags);
 		params[0] = readUint16Wrapper(&vsp->image);
-		params[1] = readUint16Wrapper(&vsp->palette);
-		params[2] = readUint16Wrapper(&vsp->x);
-		params[3] = readUint16Wrapper(&vsp->y);
-		params[4] = readUint16Wrapper(&vsp->flags);
+		if (getGameType() == GType_WW) {
+			params[1] = readUint16Wrapper(&vsp->x);
+			params[2] = readUint16Wrapper(&vsp->y);
+			params[3] = READ_BE_UINT16(&vsp->flags);
+		} else {
+			params[1] = readUint16Wrapper(&vsp->palette);
+			params[2] = readUint16Wrapper(&vsp->x);
+			params[3] = readUint16Wrapper(&vsp->y);
+
+			if (getGameType() == GType_SIMON1) {
+				params[4] = READ_BE_UINT16(&vsp->flags);
+			} else {
+				*(byte *)(&params[4]) = (byte)vsp->flags;
+			}
+		}
+
 		_vcPtr = (const byte *)params;
 		vc10_draw();
 

Modified: scummvm/trunk/engines/simon/game.cpp
===================================================================
--- scummvm/trunk/engines/simon/game.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/game.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -70,6 +70,7 @@
 	{"feeble", "The Feeble Files"},
 	{"simon1", "Simon the Sorcerer 1"},
 	{"simon2", "Simon the Sorcerer 2"},
+	{"waxworks", "Waxworks"},
 	{NULL, NULL}
 };
 
@@ -88,7 +89,7 @@
 	// First search the list of supported game IDs.
 	const PlainGameDescriptor *g = simonGames;
 	while (g->gameid) {
-		if (0 == scumm_stricmp(gameid, g->gameid))
+		if (!scumm_stricmp(gameid, g->gameid))
 			return *g;
 		g++;
 	}
@@ -586,7 +587,28 @@
 	{ "tbllist",		GAME_TBLFILE,	"0bbfee8e69739111eb36b0d138da8ddf"},
 };
 
+static GameFileDescription WAXWORKS_GameFiles[] = {
+	{ "gamepc",		GAME_BASEFILE,	"7751e9358e894e32ef40ef3b3bae0f2a"},
+	{ "icon.dat",		GAME_ICONFILE,	"ef1b8ad3494cf103dc10a99fe152ef9a"},
+	{ "stripped.txt",	GAME_STRFILE,	"f259e3e07a1cde8d0404a767d815e12c"},
+	{ "tbllist",		GAME_TBLFILE,	"95c44bfc380770a6b6dd0dfcc69e80a0"},
+	{ "xtbllist",		GAME_XTBLFILE,	"6c7b3db345d46349a5226f695c03e20f"},
+};
+
 static GameDescription gameDescriptions[] = {
+	// Waxworks - English Floopy
+	{
+		"waxworks",
+		GType_WW,
+		GID_WAXWORKS,
+		"Floppy",
+		ARRAYSIZE(WAXWORKS_GameFiles),
+		WAXWORKS_GameFiles,
+		GF_OLD_BUNDLE,
+		Common::EN_ANY,
+		Common::kPlatformPC,
+	},
+
 	// Simon the Sorcerer 1 - English Acorn CD Demo
 	{
 		"simon1",

Modified: scummvm/trunk/engines/simon/intern.h
===================================================================
--- scummvm/trunk/engines/simon/intern.h	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/intern.h	2006-09-19 11:59:13 UTC (rev 23939)
@@ -43,7 +43,18 @@
 	int16 objectFlagValue[1];
 };
 
+struct SubUserChain : Child {
+	uint16 subroutine_id;
+	uint16 chChained;
+};
+
+struct SubUserInherit : Child {
+	uint16 subroutine_id;
+	uint16 inMaster;
+};
+
 struct SubUserFlag : Child {
+	uint16 subroutine_id;
 	uint16 userFlags[4];
 };
 
@@ -166,11 +177,16 @@
 	GAME_GMEFILE  = 1 << 2,
 	GAME_STRFILE  = 1 << 3,
 	GAME_TBLFILE  = 1 << 4,
+	GAME_XTBLFILE  = 1 << 5,
 
-	GAME_GFXIDXFILE = 1 << 5
+	GAME_GFXIDXFILE = 1 << 6
 };
 
 enum GameIds {
+	GID_ELVIRA,
+	GID_ELVIRA2,
+	GID_WAXWORKS,
+
 	GID_SIMON1DOS,
 	GID_SIMON1DOS_RU,
 	GID_SIMON1DOS_INF,

Modified: scummvm/trunk/engines/simon/items.cpp
===================================================================
--- scummvm/trunk/engines/simon/items.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/items.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -288,6 +288,50 @@
 	_numOpcodes = ARRAYSIZE(opcode_table);
 
 	switch (getGameType()) {
+	case GType_WW:
+		// Confirmed
+		opcode_table[70] = &SimonEngine::o1_printLongText;
+		opcode_table[83] = &SimonEngine::o1_rescan;
+		opcode_table[98] = &SimonEngine::o1_animate;
+		opcode_table[99] = &SimonEngine::o1_stopAnimate;
+		opcode_table[85] = &SimonEngine::oww_whereTo;
+		opcode_table[105] = &SimonEngine::oww_menu;
+		opcode_table[106] = &SimonEngine::oww_textMenu;
+		opcode_table[127] = &SimonEngine::o1_playTune;
+		opcode_table[148] = &SimonEngine::oww_ifDoorOpen;
+		opcode_table[179] = &SimonEngine::o_isAdjNoun;
+		opcode_table[180] = &SimonEngine::o_b2Set;
+		opcode_table[181] = &SimonEngine::o_b2Clear;
+		opcode_table[182] = &SimonEngine::o_b2Zero;
+		opcode_table[183] = &SimonEngine::o_b2NotZero;
+
+		// Code difference, check if triggered
+		opcode_table[161] = NULL;
+		opcode_table[162] = NULL;
+		opcode_table[163] = NULL;
+		opcode_table[164] = NULL;
+		opcode_table[165] = NULL;
+		opcode_table[166] = NULL;
+		opcode_table[167] = NULL;
+		opcode_table[168] = NULL;
+		opcode_table[169] = NULL;
+		opcode_table[170] = NULL;
+		opcode_table[171] = NULL;
+		opcode_table[172] = NULL;
+		opcode_table[173] = NULL;
+		opcode_table[174] = NULL;
+		opcode_table[175] = NULL;
+		opcode_table[176] = NULL;
+		opcode_table[177] = NULL;
+		opcode_table[178] = NULL;
+		opcode_table[184] = NULL;
+		opcode_table[185] = NULL;
+		opcode_table[186] = NULL;
+		opcode_table[187] = NULL;
+		opcode_table[188] = NULL;
+		opcode_table[189] = NULL;
+		opcode_table[190] = NULL;
+		break;
 	case GType_SIMON1:
 		opcode_table[70] = &SimonEngine::o1_printLongText;
 		opcode_table[83] = &SimonEngine::o1_rescan;
@@ -376,7 +420,7 @@
 }
 
 // -----------------------------------------------------------------------
-// Simon 1 Opcodes
+// Common Opcodes
 // -----------------------------------------------------------------------
 
 void SimonEngine::o_at() {
@@ -1495,6 +1539,76 @@
 }
 
 // -----------------------------------------------------------------------
+// Waxworks 1 Opcodes
+// -----------------------------------------------------------------------
+
+uint16 SimonEngine::getDoorState(Item *item, uint16 d) {
+	uint16 mask = 3;
+	uint16 n;
+
+	SubRoom *subRoom = (SubRoom *)findChildOfType(item, 1);
+	if (subRoom == NULL)
+	    return 0;
+
+	d <<= 1;
+	mask <<= d;
+	n = subRoom->roomExitStates & mask;
+	n >>= d;
+
+	return n;
+}
+
+uint16 SimonEngine::getExitOf(Item *item, uint16 d) {
+	uint16 x;
+	uint16 y = 0;
+
+	SubRoom *subRoom = (SubRoom *)findChildOfType(item, 1);
+	if (subRoom == NULL)
+		return 0;
+	x = d;
+	while (x > y) {
+		if (getDoorState(item, y) == 0)
+			d--;
+		y++;
+	}
+	return subRoom->roomExit[d];
+}
+
+void SimonEngine::oww_whereTo() {
+	// 85: where to
+	Item *i = getNextItemPtr();
+	int16 d = getVarOrByte();
+	int16 f = getVarOrByte();
+
+	if (f == 1)
+		_subjectItem = _itemArrayPtr[getExitOf(i, d)];
+	else
+		_objectItem = _itemArrayPtr[getExitOf(i, d)];
+}
+
+void SimonEngine::oww_menu() {
+	// 105: menu
+	getVarOrByte();
+}
+
+void SimonEngine::oww_textMenu() {
+	// 106: text menu
+
+	/* byte tmp = getVarOrByte();
+	TextMenu[tmp] = getVarOrByte(); */
+
+	getVarOrByte();
+	getVarOrByte();
+}
+
+void SimonEngine::oww_ifDoorOpen() {
+	// 148: if door open
+	Item *item = getNextItemPtr();
+	uint16 d = getVarOrByte();
+	setScriptCondition(getDoorState(item, d) != 0);
+}
+
+// -----------------------------------------------------------------------
 // Simon 1 Opcodes
 // -----------------------------------------------------------------------
 

Modified: scummvm/trunk/engines/simon/midiparser_s1d.cpp
===================================================================
--- scummvm/trunk/engines/simon/midiparser_s1d.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/midiparser_s1d.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -115,7 +115,8 @@
 		// OTherwise fall through to default.
 
 	default:
-		error("MidiParser_S1D: Unexpected byte 0x%02X found!\n", (int) info.event);
+		//warning("MidiParser_S1D: Unexpected byte 0x%02X found!\n", (int) info.command());
+		break;
 	}
 }
 

Modified: scummvm/trunk/engines/simon/res.cpp
===================================================================
--- scummvm/trunk/engines/simon/res.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/res.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -40,6 +40,23 @@
 namespace Simon {
 
 // Script opcodes to load into memory
+static const char *const opcode_arg_table_waxworks[256] = {
+	" ", "I ", "I ", "I ", "I ", "I ", "I ", "II ", "II ", "II ", "II ", "B ", "B ", "BN ", "BN ",
+	"BN ", "BN ", "BB ", "BB ", "BB ", "BB ", "II ", "II ", "N ", "I ", "I ", "I ", "IN ", "IB ",
+	"II ", "I ", "I ", "II ", "II ", "IBB ", "BIB ", "BB ", "B ", "BI ", "IB ", "B ", "B ", "BN ",
+	"BN ", "BN ", "BB ", "BB ", "BN ", "BN ", "BB ", "BB ", "BN ", "BB ", "BN ", "B ", "I ", "IB ",
+	"IB ", "II ", "I ", "I ", "IN ", "B ", "T ", "T ", "NNNNNB ", "BT ", "BT ", "T ", " ", "B ",
+	"N ", "IBN ", "I ", "I ", "I ", "NN ", " ", " ", "IT ", "II ", "I ", "B ", " ", "IB ", "IBB ",
+	"IIB ", "T ", "T ", "T ", "IB ", "IB ", "IB ", "B ", "BB ", "IBB ", "NB ", "N ", "NBNNN ", "N ",
+	" ", "BNNNNNN ", "B ", " ", "B ", "B ", "BB ", "NNNNNIN ", "N ", "N ", "N ", "NNN ", "NBNN ",
+	"IBNN ", "IB ", "IB ", "IB ", "IB ", "N ", "N ", "N ", "BI ", " ", " ", "N ", "I ", "IBB ",
+	"NN ", "N ", "N ", "Ban ", "BB ", " ", " ", " ", " ", "IB ", "B ", " ", "II ", " ", "BI ", "N ",
+	"I ", "IB ", "IB ", "IB ", "IB ", "IB ", "IB ", "IB ", "BI ", "BB ", "B ", "B ", "B ",	"B ",
+	"IBB ", "IBN ", "IB ", "B ", " ", "TB ", "TB ", "I ", "N ", "B ", "INB ", "INB ", "INB ", "INB ",
+	"INB ", "INB ", "INB ", "N ", " ", "INBB ", "B ", "B ", "Ian ", "B ", "B ", "B ", "B ", "T ",
+	"T ", "B ", " ", "I ", " ", " "
+};
+
 static const char *const opcode_arg_table_simon1win[256] = {
 	" ", "I ", "I ", "I ", "I ", "I ", "I ", "II ", "II ", "II ", "II ", "B ", "B ", "BN ", "BN ",
 	"BN ", "BN ", "BB ", "BB ", "BB ", "BB ", "II ", "II ", "N ", "I ", "I ", "I ", "IN ", "IB ",
@@ -252,6 +269,27 @@
 
 	in.close();
 
+	if (getGameType() == GType_WW) {
+		/* Read list of TABLE resources */
+		in.open(getFileName(GAME_XTBLFILE));
+		if (in.isOpen() == false) {
+			error("loadGamePcFile: Can't load table resources file '%s'", getFileName(GAME_XTBLFILE));
+		}
+
+		file_size = in.size();
+
+		_xtblList = (byte *)malloc(file_size);
+		if (_xtblList == NULL)
+			error("loadGamePcFile: Out of memory for strip table list");
+		in.read(_xtblList, file_size);
+		in.close();
+
+		/* Remember the current state */
+		_xsubroutineListOrg = _subroutineList;
+		_xtablesHeapPtrOrg = _tablesHeapPtr;
+		_xtablesHeapCurPosOrg = _tablesHeapCurPos;
+	}
+
 	/* Read list of TABLE resources */
 	in.open(getFileName(GAME_TBLFILE));
 	if (in.isOpen() == false) {
@@ -361,6 +399,17 @@
 				subObject->objectFlagValue[k++] = in->readUint16BE();
 
 		subObject->objectName = (uint16)in->readUint32BE();
+	} else if (type == 8) {
+		SubUserChain *chain = (SubUserChain *)allocateChildBlock(item, 8, sizeof(SubUserChain));
+		chain->chChained = (uint16)fileReadItemID(in);
+	} else if (type == 9) {
+		setUserFlag(item, 0, in->readUint16BE());
+		setUserFlag(item, 1, in->readUint16BE());
+		setUserFlag(item, 2, in->readUint16BE());
+		setUserFlag(item, 3, in->readUint16BE());
+	} else if (type == 255) {
+		SubUserInherit *inherit = (SubUserInherit *)allocateChildBlock(item, 255, sizeof(SubUserInherit));
+		inherit->inMaster = (uint16)fileReadItemID(in);
 	} else {
 		error("readItemChildren: invalid type %d", type);
 	}
@@ -380,16 +429,18 @@
 
 	const char *const *table;
 
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_FF)
 		table = opcode_arg_table_feeblefiles;
-	} else if ((getGameType() == GType_SIMON2) && (getFeatures() & GF_TALKIE))
+	else if (getGameType() == GType_SIMON2 && (getFeatures() & GF_TALKIE))
 		table = opcode_arg_table_simon2win;
 	else if (getGameType() == GType_SIMON2)
 		table = opcode_arg_table_simon2dos;
-	else if (getFeatures() & GF_TALKIE)
+	else if (getGameType() == GType_SIMON1 && (getFeatures() & GF_TALKIE))
 		table = opcode_arg_table_simon1win;
-	else
+	else if (getGameType() == GType_SIMON1)
 		table = opcode_arg_table_simon1dos;
+	else /* if (getGameType() == GType_WW) */
+		table = opcode_arg_table_waxworks;
 
 	i = 0;
 
@@ -690,10 +741,14 @@
 		if (getPlatform() == Common::kPlatformAmiga) {
 			if (getFeatures() & GF_TALKIE)
 				sprintf(filename, "%.3d%d.out", id / 2, type);
-			else 
+			else
 				sprintf(filename, "%.3d%d.pkd", id / 2, type);
 		} else {
-			sprintf(filename, "%.3d%d.VGA", id / 2, type);
+			if (getGameType() == GType_WW) {
+				sprintf(filename, "%.2d%d.VGA", id / 2, type);
+			} else {
+				sprintf(filename, "%.3d%d.VGA", id / 2, type);
+			}
 		}
 
 		in.open(filename);

Modified: scummvm/trunk/engines/simon/simon.cpp
===================================================================
--- scummvm/trunk/engines/simon/simon.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/simon.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -99,14 +99,18 @@
 
 	_iconFilePtr = 0;
 
-	_tblList = 0;
-
 	_codePtr = 0;
 
 	_localStringtable = 0;
 	_stringIdLocalMin = 0;
 	_stringIdLocalMax = 0;
 
+	_xtblList = 0;
+	_xtablesHeapPtrOrg = 0;
+	_xtablesHeapCurPosOrg = 0;
+	_xsubroutineListOrg = 0;
+
+	_tblList = 0;
 	_tablesHeapPtr = 0;
 	_tablesHeapPtrOrg = 0;
 	_tablesheapPtrNew = 0;
@@ -114,9 +118,9 @@
 	_tablesHeapCurPos = 0;
 	_tablesHeapCurPosOrg = 0;
 	_tablesHeapCurPosNew = 0;
+	_subroutineListOrg = 0;
 
 	_subroutineList = 0;
-	_subroutineListOrg = 0;
 	_subroutine = 0;
 
 	_dxSurfacePitch = 0;
@@ -707,9 +711,9 @@
 }
 
 void SimonEngine::allocItemHeap() {
-	_itemHeapSize = 20000;
+	_itemHeapSize = 32000;
 	_itemHeapCurPos = 0;
-	_itemHeapPtr = (byte *)calloc(20000, 1);
+	_itemHeapPtr = (byte *)calloc(32000, 1);
 }
 
 void SimonEngine::allocTablesHeap() {
@@ -754,6 +758,7 @@
 
 Item *SimonEngine::getNextItemPtr() {
 	int a = getNextWord();
+
 	switch (a) {
 	case -1:
 		return _subjectItem;
@@ -764,6 +769,7 @@
 	case -7:
 		return actor();
 	case -9:
+		assert (derefItem(me()->parent) != NULL);
 		return derefItem(me()->parent);
 	default:
 		return derefItem(a);
@@ -1163,7 +1169,11 @@
 void SimonEngine::hitarea_stuff_helper() {
 	time_t cur_time;
 
-	if (getGameType() == GType_SIMON1) {
+	if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) {
+		if (_variableArray[254] || _variableArray[249]) {
+			hitarea_stuff_helper_2();
+		}
+	} else {
 		uint subr_id = (uint16)_variableArray[254];
 		if (subr_id != 0) {
 			Subroutine *sub = getSubroutineByID(subr_id);
@@ -1174,10 +1184,6 @@
 			_variableArray[254] = 0;
 			_runScriptReturn1 = false;
 		}
-	} else {
-		if (_variableArray[254] || _variableArray[249]) {
-			hitarea_stuff_helper_2();
-		}
 	}
 
 	time(&cur_time);
@@ -1265,11 +1271,8 @@
 	vpe->vgaFile2 = loadVGAFile(vga_res * 2 + 1, 2, size);
 	vpe->vgaFile2End = vpe->vgaFile2 + size;
 
-	vpe->sfxFile = NULL;
-	if (getGameType() == GType_FF && getPlatform() == Common::kPlatformWindows) {
-		vpe->sfxFile = loadVGAFile(vga_res * 2, 3, size);
-		vpe->sfxFileEnd = vpe->sfxFile + size;
-	}
+	vpe->sfxFile = loadVGAFile(vga_res * 2, 3, size);
+	vpe->sfxFileEnd = vpe->sfxFile + size;
 }
 
 void SimonEngine::setZoneBuffers() {
@@ -1343,8 +1346,7 @@
 
 void SimonEngine::checkRunningAnims(byte *end) {
 	VgaSprite *vsp;
-	if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
-		(_lockWord & 0x20)) {
+	if (getGameType() != GType_FF && (_lockWord & 0x20)) {
 		return;
 	}
 
@@ -1451,7 +1453,21 @@
 
 	bb = _curVgaFile1;
 
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_WW) {
+		b = bb + READ_BE_UINT16(bb + 10);
+		b += 20;
+
+		count = READ_BE_UINT16(&((VgaFileHeader2_WW *) b)->imageCount);
+		b = bb + READ_BE_UINT16(&((VgaFileHeader2_WW *) b)->imageTable);
+
+		while (count--) {
+			if (READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id)
+				break;
+			b += sizeof(ImageHeader_WW);
+		}
+		assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id);
+
+	} else if (getGameType() == GType_FF) {
 		b = bb + READ_LE_UINT16(&((VgaFileHeader_Feeble *) bb)->hdr2_start);
 		count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageCount);
 		b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable);
@@ -1499,7 +1515,9 @@
 
 	vc_ptr_org = _vcPtr;
 
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_WW) {
+		_vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW *) b)->scriptOffs);
+	} else if (getGameType() == GType_FF) {
 		_vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs);
 	} else {
 		_vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs);
@@ -1566,6 +1584,7 @@
 	_syncCount = 0;
 	_exitCutscene = false;
 	_rightButtonDown = false;
+
 	while (_vgaWaitFor != 0) {
 		if (_rightButtonDown) {
 			if (_vgaWaitFor == 200 && (getGameType() == GType_FF || !getBitFlag(14))) {
@@ -1631,7 +1650,7 @@
 bool SimonEngine::isSpriteLoaded(uint16 id, uint16 zoneNum) {
 	VgaSprite *vsp = _vgaSprites;
 	while (vsp->id) {
-		if (getGameType() == GType_SIMON1) {
+		if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
 			if (vsp->id == id)
 				return true;
 		} else {
@@ -1791,9 +1810,12 @@
 	vsp->y = y;
 	vsp->x = x;
 	vsp->image = 0;
-	vsp->palette = palette;
+	if (getGameType() == GType_WW)
+		vsp->palette = 0;
+	else
+		vsp->palette = palette;
 	vsp->id = vgaSpriteId;
-	if (getGameType() == GType_SIMON1)
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_WW)
 		vsp->zoneNum = zoneNum = vgaSpriteId / 100;
 	else
 		vsp->zoneNum = zoneNum;
@@ -1809,7 +1831,13 @@
 	}
 
 	pp = _curVgaFile1;
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_WW) {
+		p = pp + READ_BE_UINT16(pp + 10);
+		p += 20;
+
+		count = READ_BE_UINT16(&((VgaFileHeader2_WW *) p)->animationCount);
+		p = pp + READ_BE_UINT16(&((VgaFileHeader2_WW *) p)->animationTable);
+	} else if (getGameType() == GType_FF) {
 		p = pp + READ_LE_UINT16(&((VgaFileHeader_Feeble *) pp)->hdr2_start);
 		count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationCount);
 		p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
@@ -1820,7 +1848,16 @@
 	}
 
 	for (;;) {
-		if (getGameType() == GType_FF) {
+		if (getGameType() == GType_WW) {
+			if (READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId) {
+				if (_startVgaScript)
+					dump_vga_script(pp + READ_BE_UINT16(&((AnimationHeader_WW *)p)->scriptOffs), zoneNum, vgaSpriteId);
+
+				addVgaEvent(_vgaBaseDelay, pp + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, zoneNum);
+				break;
+			}
+			p += sizeof(AnimationHeader_WW);
+		} else if (getGameType() == GType_FF) {
 			if (READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId) {
 				if (_startVgaScript)
 					dump_vga_script(pp + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), zoneNum, vgaSpriteId);
@@ -2126,6 +2163,19 @@
 		}
 
 		midi.startTrack (0);
+	} else {
+		midi.stop();
+		midi.setLoop (true); // Must do this BEFORE loading music. (GMF may have its own override.)
+
+		char filename[15];
+		File f;
+		sprintf(filename, "MOD%d.MUS", music);
+		f.open(filename);
+		if (f.isOpen() == false)
+			error("loadMusic: Can't load music from '%s'", filename);
+
+		midi.loadS1D (&f);
+		midi.startTrack (0);
 	}
 }
 

Modified: scummvm/trunk/engines/simon/simon.h
===================================================================
--- scummvm/trunk/engines/simon/simon.h	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/simon.h	2006-09-19 11:59:13 UTC (rev 23939)
@@ -112,7 +112,8 @@
 enum SIMONGameType {
 	GType_FF = 0,
 	GType_SIMON1 = 1,
-	GType_SIMON2 = 2
+	GType_SIMON2 = 2,
+	GType_WW = 3
 };
 
 struct GameFileDescription {
@@ -216,18 +217,23 @@
 
 	byte *_iconFilePtr;
 
-	byte *_tblList;
-
 	const byte *_codePtr;
 
 	byte **_localStringtable;
 	uint _stringIdLocalMin, _stringIdLocalMax;
 
+	byte *_xtblList;
+	byte *_xtablesHeapPtrOrg;
+	uint _xtablesHeapCurPosOrg;
+	Subroutine *_xsubroutineListOrg;
+
+	byte *_tblList;
 	byte *_tablesHeapPtr, *_tablesHeapPtrOrg, *_tablesheapPtrNew;
 	uint _tablesHeapSize, _tablesHeapCurPos, _tablesHeapCurPosOrg;
 	uint _tablesHeapCurPosNew;
+	Subroutine *_subroutineListOrg;
 
-	Subroutine *_subroutineList, *_subroutineListOrg;
+	Subroutine *_subroutineList;
 	uint _subroutine;
 
 	uint _dxSurfacePitch;
@@ -622,7 +628,8 @@
 	void mouseOn();
 
 	void loadTextIntoMem(uint stringId);
-	void loadTablesIntoMem(uint subr_id);
+	bool loadTablesIntoMem(uint subr_id);
+	bool loadXTablesIntoMem(uint subr_id);
 
 	uint loadTextFile(const char *filename, byte *dst);
 	Common::File *openTablesFile(const char *filename);
@@ -784,7 +791,7 @@
 	void vc54_no_op();
 	void vc55_moveBox();
 	void vc56_delay();
-	void vc57_no_op();
+	void vc57_blackPalette();
 	void vc58();
 	void vc59();
 	void vc60_killSprite();
@@ -949,6 +956,15 @@
 	void o_unloadZone();
 	void o_unfreezeZones();
 
+	uint16 getDoorState(Item *item, uint16 d);
+	uint16 getExitOf(Item *item, uint16 d);
+
+	// Opcodes, Waxworks only
+	void oww_whereTo();
+	void oww_menu();
+	void oww_textMenu();
+	void oww_ifDoorOpen();
+
 	// Opcodes, Simon 1 only
 	void o1_printLongText();
 	void o1_rescan();

Modified: scummvm/trunk/engines/simon/subroutine.cpp
===================================================================
--- scummvm/trunk/engines/simon/subroutine.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/subroutine.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -40,11 +40,18 @@
 			return cur;
 	}
 
-	loadTablesIntoMem(subroutine_id);
+	if (loadXTablesIntoMem(subroutine_id)) {
+		for (cur = _subroutineList; cur; cur = cur->next) {
+			if (cur->id == subroutine_id)
+				return cur;
+		}
+	}
 
-	for (cur = _subroutineList; cur; cur = cur->next) {
-		if (cur->id == subroutine_id)
-			return cur;
+	if (loadTablesIntoMem(subroutine_id)) {
+		for (cur = _subroutineList; cur; cur = cur->next) {
+			if (cur->id == subroutine_id)
+				return cur;
+		}
 	}
 
 	if (subroutine_id != 160)
@@ -99,7 +106,7 @@
 	return _gameFile;
 }
 
-void SimonEngine::loadTablesIntoMem(uint subr_id) {
+bool SimonEngine::loadTablesIntoMem(uint subr_id) {
 	byte *p;
 	int i;
 	uint min_num, max_num;
@@ -108,7 +115,7 @@
 
 	p = _tblList;
 	if (p == NULL)
-		return;
+		return 0;
 
 	while (*p) {
 		for (i = 0; *p; p++, i++)
@@ -151,14 +158,73 @@
 
 				if (_tablesHeapCurPos > _tablesHeapSize)
 					error("loadTablesIntoMem: Out of table memory");
-				return;
+				return 1;
 			}
 		}
 	}
 
 	debug(1,"loadTablesIntoMem: didn't find %d", subr_id);
+	return 0;
 }
 
+bool SimonEngine::loadXTablesIntoMem(uint subr_id) {
+	if (getGameType() != GType_WW)
+		return 0;
+
+	byte *p;
+	int i;
+	uint min_num, max_num;
+	char filename[30];
+	File *in;
+
+	p = _xtblList;
+	if (p == NULL)
+		return 0;
+
+	while (*p) {
+		for (i = 0; *p; p++, i++)
+			filename[i] = *p;
+		filename[i] = 0;
+		p++;
+
+		for (;;) {
+			min_num = (p[0] * 256) | p[1];
+			p += 2;
+
+			if (min_num == 0)
+				break;
+
+			max_num = (p[0] * 256) | p[1];
+			p += 2;
+
+			if (subr_id >= min_num && subr_id <= max_num) {
+				_subroutineList = _xsubroutineListOrg;
+				_tablesHeapPtr = _xtablesHeapPtrOrg;
+				_tablesHeapCurPos = _xtablesHeapCurPosOrg;
+				_stringIdLocalMin = 1;
+				_stringIdLocalMax = 0;
+
+				in = openTablesFile(filename);
+				readSubroutineBlock(in);
+				closeTablesFile(in);
+
+				alignTableMem();
+
+				_subroutineListOrg = _subroutineList;
+				_tablesHeapPtrOrg = _tablesHeapPtr;
+				_tablesHeapCurPosOrg = _tablesHeapCurPos;
+				_tablesheapPtrNew = _tablesHeapPtr;
+				_tablesHeapCurPosNew = _tablesHeapCurPos;
+
+				return 1;
+			}
+		}
+	}
+
+	debug(1,"loadXTablesIntoMem: didn't find %d", subr_id);
+	return 0;
+}
+
 void SimonEngine::closeTablesFile(File *in) {
 	if (getFeatures() & GF_OLD_BUNDLE) {
 		in->close();

Modified: scummvm/trunk/engines/simon/vga.cpp
===================================================================
--- scummvm/trunk/engines/simon/vga.cpp	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/vga.cpp	2006-09-19 11:59:13 UTC (rev 23939)
@@ -92,7 +92,7 @@
 		&SimonEngine::vc54_no_op,
 		&SimonEngine::vc55_moveBox,
 		&SimonEngine::vc56_delay,
-		&SimonEngine::vc57_no_op,
+		&SimonEngine::vc57_blackPalette,
 		&SimonEngine::vc58,
 		&SimonEngine::vc59,
 		&SimonEngine::vc60_killSprite,
@@ -137,7 +137,7 @@
 			}
 		}
 
-		if (getGameType() == GType_SIMON1) {
+		if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
 			opcode = READ_BE_UINT16(_vcPtr);
 			_vcPtr += 2;
 		} else {
@@ -195,7 +195,7 @@
 VgaSprite *SimonEngine::findCurSprite() {
 	VgaSprite *vsp = _vgaSprites;
 	while (vsp->id) {
-		if (getGameType() == GType_SIMON1) {
+		if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
 			if (vsp->id == _vgaCurSpriteId)
 				break;
 		} else {
@@ -236,6 +236,17 @@
 }
 
 void SimonEngine::vcSkipNextInstruction() {
+	static const byte opcodeParamLenWW[] = {
+		0, 6, 2, 10, 6, 4, 2, 2,
+		4, 4, 8, 2, 2, 2, 2, 2,
+		2, 2, 2, 0, 4, 2, 2, 2,
+		8, 0, 10, 0, 8, 0, 2, 2,
+		0, 0, 0, 4, 4, 4, 2, 4,
+		4, 4, 4, 2, 2, 4, 2, 2,
+		2, 2, 2, 2, 2, 4, 6, 6,
+		0, 0, 0, 0, 2, 2, 0, 0,
+	};
+
 	static const byte opcodeParamLenSimon1[] = {
 		0, 6, 2, 10, 6, 4, 2, 2,
 		4, 4, 10, 0, 2, 2, 2, 2,
@@ -281,9 +292,12 @@
 	} else if (getGameType() == GType_SIMON2) {
 		opcode = vcReadNextByte();
 		_vcPtr += opcodeParamLenSimon2[opcode];
+	} else if (getGameType() == GType_SIMON1) {
+		opcode = vcReadNextWord();
+		_vcPtr += opcodeParamLenSimon1[opcode];
 	} else {
 		opcode = vcReadNextWord();
-		_vcPtr += opcodeParamLenSimon1[opcode];
+		_vcPtr += opcodeParamLenWW[opcode];
 	}
 
 	if (_continousVgaScript)
@@ -325,7 +339,21 @@
 
 
 	bb = _curVgaFile1;
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_WW) {
+		b = bb + READ_BE_UINT16(bb + 10);
+		b += 20;
+
+		count = READ_BE_UINT16(&((VgaFileHeader2_WW *) b)->imageCount);
+		b = bb + READ_BE_UINT16(&((VgaFileHeader2_WW *) b)->imageTable);
+
+		while (count--) {
+			if (READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == num)
+				break;
+			b += sizeof(ImageHeader_WW);
+		}
+		assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == num);
+
+	} else if (getGameType() == GType_FF) {
 		b = bb + READ_LE_UINT16(&((VgaFileHeader_Feeble *) bb)->hdr2_start);
 		count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageCount);
 		b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable);
@@ -351,7 +379,9 @@
 
 	vcPtrOrg = _vcPtr;
 
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_WW) {
+		_vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW *) b)->scriptOffs);
+	} else if (getGameType() == GType_FF) {
 		_vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs);
 	} else {
 		_vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs);
@@ -376,7 +406,7 @@
 
 	windowNum = vcReadNextWord();		/* 0 */
 
-	if (getGameType() == GType_SIMON1) {
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
 		vgaSpriteId = vcReadNextWord();	/* 2 */
 		zoneNum = vgaSpriteId / 100;
 	} else {
@@ -395,7 +425,10 @@
 	while (vsp->id)
 		vsp++;
 
-	vsp->palette = palette;
+	if (getGameType() == GType_WW)
+		vsp->palette = 0;
+	else
+		vsp->palette = palette;
 	vsp->windowNum = windowNum;
 	vsp->priority = 0;
 	vsp->flags = 0;
@@ -420,7 +453,20 @@
 	}
 
 	pp = _curVgaFile1;
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_WW) {
+		p = pp + READ_BE_UINT16(pp + 10);
+		p += 20;
+
+		count = READ_BE_UINT16(&((VgaFileHeader2_WW *) p)->animationCount);
+		p = pp + READ_BE_UINT16(&((VgaFileHeader2_WW *) p)->animationTable);
+
+		while (count--) {
+			if (READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId)
+				break;
+			p += sizeof(AnimationHeader_WW);
+		}
+		assert(READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId);
+	} else if (getGameType() == GType_FF) {
 		p = pp + READ_LE_UINT16(&((VgaFileHeader_Feeble *) pp)->hdr2_start);
 		count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationCount);
 		p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
@@ -465,7 +511,9 @@
 #endif
 
 	if (_startVgaScript) {
-		if (getGameType() == GType_FF) {
+		if (getGameType() == GType_WW) {
+			dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW*)p)->scriptOffs), res, vgaSpriteId);
+		} else if (getGameType() == GType_FF) {
 			dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), res, vgaSpriteId);
 		} else {
 			dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), res, vgaSpriteId);
@@ -473,7 +521,9 @@
 		}
 	}
 
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_WW) {
+		addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, res);
+	} else if (getGameType() == GType_FF) {
 		addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, res);
 	} else {
 		addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, res);
@@ -771,17 +821,21 @@
 
 	if (getGameType() == GType_FF) {
 		state.palette = (_vcPtr[0] * 16);
+		_vcPtr += 2;
+	} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+		state.palette = (_vcPtr[1] * 16);
+		_vcPtr += 2;
 	} else {
-		state.palette = (_vcPtr[1] * 16);
+		state.palette = 0;
 	}
-	_vcPtr += 2;
+
 	state.x = (int16)vcReadNextWord();
 	state.x -= _scrollX;
 
 	state.y = (int16)vcReadNextWord();
 	state.y -= _scrollY;
 
-	if (getGameType() == GType_SIMON1) {
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
 		state.flags = vcReadNextWord();
 	} else {
 		state.flags = vcReadNextByte();
@@ -842,7 +896,7 @@
 		return;
 	}
 
-	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) {
 		if (state.flags & kDFCompressedFlip) {
 			state.depack_src = vc10_uncompressFlip(state.depack_src, width, height);
 		} else if (state.flags & kDFFlip) {
@@ -870,7 +924,7 @@
 
 	vlut = &_video_windows[_windowNum * 4];
 
-	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) {
 		state->draw_width = state->width * 2;
 	} 
 
@@ -914,7 +968,7 @@
 
 	assert(state->draw_width != 0 && state->draw_height != 0);
 
-	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) {
 		state->draw_width *= 4;
 	}
 
@@ -1152,7 +1206,8 @@
 		} while (++w != state->draw_width);
 
 		/* vc10_helper_5 */
-	} else if (((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) {
+	} else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) &&
+		getGameType() != GType_WW) {
 		const byte *src;
 		byte *dst;
 		uint h, i;
@@ -1413,7 +1468,12 @@
 }
 
 void SimonEngine::vc11_clearPathFinder() {
-	memset(&_pathFindArray, 0, sizeof(_pathFindArray));
+	if (getGameType() == GType_WW) {
+		// FIXME
+		vcReadNextWord();
+	} else {
+		memset(&_pathFindArray, 0, sizeof(_pathFindArray));
+	}
 }
 
 void SimonEngine::vc12_delay() {
@@ -1487,13 +1547,18 @@
 }
 
 void SimonEngine::vc17_setPathfinderItem() {
-	uint16 a = vcReadNextWord();
-	_pathFindArray[a - 1] = (const uint16 *)_vcPtr;
+	if (getGameType() == GType_WW) {
+		// FIXME
+		vcReadNextWord();
+	} else {
+		uint16 a = vcReadNextWord();
+		_pathFindArray[a - 1] = (const uint16 *)_vcPtr;
 
-	int end = (getGameType() == GType_FF) ? 9999 : 999;
-	while (readUint16Wrapper(_vcPtr) != end)
-		_vcPtr += 4;
-	_vcPtr += 2;
+		int end = (getGameType() == GType_FF) ? 9999 : 999;
+		while (readUint16Wrapper(_vcPtr) != end)
+			_vcPtr += 4;
+		_vcPtr += 2;
+	}
 }
 
 void SimonEngine::vc18_jump() {
@@ -1522,7 +1587,7 @@
 void SimonEngine::vc21_endRepeat() {
 	int16 a = vcReadNextWord();
 	const byte *tmp = _vcPtr + a;
-	if (getGameType() == GType_SIMON1)
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_WW)
 		tmp += 4;
 	else
 		tmp += 3;
@@ -1536,29 +1601,48 @@
 }
 
 void SimonEngine::vc22_setSpritePalette() {
-	uint16 a = vcReadNextWord();
-	uint16 b = vcReadNextWord();
-	uint num = a == 0 ? 32 : 16;
-	uint palSize = 96;
-	byte *palptr, *src;
+	byte *offs, *palptr, *src;
+	uint16 a, b, num, palSize;
 
-	if (getGameType() == GType_FF) {
-		a = 0;
+	if (getGameType() != GType_WW)
+		a = vcReadNextWord();
+	b = vcReadNextWord();
+
+	if (getGameType() == GType_WW) {
+		num = 16;
+		palSize = 32;
+		palptr = _displayPalette;
+		offs = _curVgaFile1 + READ_BE_UINT16(_curVgaFile1 + 6);
+	} else if (getGameType() == GType_FF) {
 		num = 256;
 		palSize = 768;
+
+		palptr = _displayPalette;
+		offs = _curVgaFile1 + 6;
+	} else {
+		num = a == 0 ? 32 : 16;
+		palSize = 96;
+
+		palptr = &_displayPalette[(a * 64)];
+		offs = _curVgaFile1 + 6;
 	}
+	src = offs + b * palSize;
 
-	palptr = &_displayPalette[(a * 64)];
-	src = _curVgaFile1 + 6 + b * palSize;
-
 	do {
-		palptr[0] = src[0] * 4;
-		palptr[1] = src[1] * 4;
-		palptr[2] = src[2] * 4;
+		if (getGameType() == GType_WW) {
+			uint16 color = READ_BE_UINT16(src);
+			palptr[2] = ((color & 0x00f) >> 0) * 32;
+			palptr[1] = ((color & 0x0f0) >> 4) * 32;
+			palptr[0] = ((color & 0xf00) >> 8) * 32;
+		} else {
+			palptr[0] = src[0] * 4;
+			palptr[1] = src[1] * 4;
+			palptr[2] = src[2] * 4;
+		}
 		palptr[3] = 0;
 
 		palptr += 4;
-		src += 3;
+		src += (getGameType() == GType_WW) ? 2 : 3;
 	} while (--num);
 
 	_paletteFlag = 2;
@@ -1607,7 +1691,7 @@
 
 	vsp->x += (int16)vcReadNextWord();
 	vsp->y += (int16)vcReadNextWord();
-	if (getGameType() == GType_SIMON1) {
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
 		vsp->flags = vcReadNextWord();
 	} else {
 		vsp->flags = vcReadNextByte();
@@ -1702,8 +1786,12 @@
 }
 
 void SimonEngine::vc32_copyVar() {
-	uint16 a = vcReadVar(vcReadNextWord());
-	vcWriteVar(vcReadNextWord(), a);
+	if (getGameType() == GType_WW) {
+		// FIXME
+	} else {
+		uint16 a = vcReadVar(vcReadNextWord());
+		vcWriteVar(vcReadNextWord(), a);
+	}
 }
 
 void SimonEngine::vc33_setMouseOn() {
@@ -1744,9 +1832,15 @@
 }
 
 void SimonEngine::vc37_addToSpriteY() {
-	VgaSprite *vsp = findCurSprite();
-	vsp->y += vcReadVar(vcReadNextWord());
-	_vgaSpriteChanged++;
+	if (getGameType() == GType_WW) {
+		// FIXME
+		vcReadNextWord();
+		vcReadNextWord();
+	} else {
+		VgaSprite *vsp = findCurSprite();
+		vsp->y += vcReadVar(vcReadNextWord());
+		_vgaSpriteChanged++;
+	}
 }
 
 void SimonEngine::vc38_skipIfVarZero() {
@@ -1838,9 +1932,15 @@
 }
 
 void SimonEngine::vc45_setSpriteX() {
-	VgaSprite *vsp = findCurSprite();
-	vsp->x = vcReadVar(vcReadNextWord());
-	_vgaSpriteChanged++;
+	if (getGameType() == GType_WW) {
+		//FIXME
+		vcReadNextWord();
+		vcReadNextWord();
+	} else {
+		VgaSprite *vsp = findCurSprite();
+		vsp->x = vcReadVar(vcReadNextWord());
+		_vgaSpriteChanged++;
+	}
 }
 
 void SimonEngine::vc46_setSpriteY() {
@@ -1850,15 +1950,23 @@
 }
 
 void SimonEngine::vc47_addToVar() {
-	uint16 var = vcReadNextWord();
-	vcWriteVar(var, vcReadVar(var) + vcReadVar(vcReadNextWord()));
+	if (getGameType() == GType_WW) {
+		//FIXME
+		vcReadNextWord();
+	} else {
+		uint16 var = vcReadNextWord();
+		vcWriteVar(var, vcReadVar(var) + vcReadVar(vcReadNextWord()));
+	}
 }
 
 void SimonEngine::vc48_setPathFinder() {
 	uint16 a = (uint16)_variableArrayPtr[12];
 	const uint16 *p = _pathFindArray[a - 1];
 
-	if (getGameType() == GType_FF) {
+	if (getGameType() == GType_WW) {
+		//FIXME
+		vcReadNextWord();
+	} else if (getGameType() == GType_FF) {
 		VgaSprite *vsp = findCurSprite();
 		int16 x, y, ydiff;
 		int16 x1, y1, x2, y2;
@@ -2036,14 +2144,34 @@
 }
 
 void SimonEngine::vc56_delay() {
-	uint16 num = vcReadVarOrWord() * _frameRate;
+	if (getGameType() == GType_SIMON2) {
+		uint16 num = vcReadVarOrWord() * _frameRate;
 
-	addVgaEvent(num + _vgaBaseDelay, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum);
-	_vcPtr = (byte *)&_vc_get_out_of_code;
+		addVgaEvent(num + _vgaBaseDelay, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum);
+		_vcPtr = (byte *)&_vc_get_out_of_code;
+	} else if (getGameType() == GType_WW) {
+		byte *src = _curVgaFile2 + 32;
+		byte *dst = getBackBuf();
+
+		uint8 palette[1024];
+		for (int i = 0; i < 256; i++) {
+			palette[i * 4 + 0] = *src++ * 4;
+			palette[i * 4 + 1] = *src++ * 4;
+			palette[i * 4 + 2] = *src++ * 4;
+			palette[i * 4 + 3] = 0;
+		}
+
+		_system->setPalette(palette, 0, 256);
+		memcpy(dst, src, _screenHeight * _screenWidth);
+	}
 }
 
-void SimonEngine::vc57_no_op() {
-	/* unused */
+void SimonEngine::vc57_blackPalette() {
+	if (getGameType() == GType_WW) {
+		//uint8 palette[1024];
+		//memset(palette, 0, sizeof(palette));
+		//_system->setPalette(palette, 0, 256);
+	}
 }
 
 void SimonEngine::vc58() {
@@ -2067,10 +2195,7 @@
 }
 
 void SimonEngine::vc59() {
-	if (getGameType() == GType_SIMON1) {
-		if (!_sound->isVoiceActive())
-			vcSkipNextInstruction();
-	} else {
+	if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) {
 		uint16 file = vcReadNextWord();
 		uint16 start = vcReadNextWord();
 		uint16 end = vcReadNextWord() + 1;
@@ -2078,6 +2203,12 @@
 		do {
 			vc_kill_sprite(file, start);
 		} while (++start != end);
+	} else if (getGameType() == GType_SIMON1) {
+		if (!_sound->isVoiceActive())
+			vcSkipNextInstruction();
+	} else {
+		// Skip if not EGA
+		vcSkipNextInstruction();
 	}
 }
 
@@ -2139,10 +2270,15 @@
 }
 
 void SimonEngine::vc61_setMaskImage() {
+	if (getGameType() == GType_WW) {
+		// FIXME
+		vcReadVarOrWord();
+		return;
+	}
+
 	VgaSprite *vsp = findCurSprite();
 
 	vsp->image = vcReadVarOrWord();
-
 	vsp->x += vcReadNextWord();
 	vsp->y += vcReadNextWord();
 	vsp->flags = kDFMasked | kDFUseFrontBuf;
@@ -2156,7 +2292,8 @@
 	if (!_fastFadeOutFlag) {
 		uint i, fadeSize, fadeCount;
 
-		_fastFadeOutFlag = true;
+		if (getGameType() != GType_WW)
+			_fastFadeOutFlag = true;
 
 		_fastFadeCount = 256;
 		if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {

Modified: scummvm/trunk/engines/simon/vga.h
===================================================================
--- scummvm/trunk/engines/simon/vga.h	2006-09-18 22:22:35 UTC (rev 23938)
+++ scummvm/trunk/engines/simon/vga.h	2006-09-19 11:59:13 UTC (rev 23939)
@@ -92,6 +92,34 @@
 };
 
 
+// Waxworks
+struct VgaFileHeader2_WW {
+	uint16 x_1;
+	uint16 imageCount;
+	uint16 x_2;
+	uint16 animationCount;
+	uint16 x_3;
+	uint16 imageTable;
+	uint16 x_4;
+	uint16 animationTable;
+	uint16 x_5;
+};
+
+struct ImageHeader_WW {
+	uint16 id;
+	uint16 x_1;
+	uint16 x_2;
+	uint16 scriptOffs;
+};
+
+struct AnimationHeader_WW {
+	uint16 id;
+	uint16 x_1;
+	uint16 x_2;
+	uint16 scriptOffs;
+};
+
+
 #include "common/pack-end.h"	// END STRUCT PACKING
 
 enum DrawFlags {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list