diff options
Diffstat (limited to 'engines')
| -rw-r--r-- | engines/agos/agos.cpp | 240 | ||||
| -rw-r--r-- | engines/agos/agos.h | 81 | ||||
| -rw-r--r-- | engines/agos/draw.cpp | 4 | ||||
| -rw-r--r-- | engines/agos/gfx.cpp | 2 | ||||
| -rw-r--r-- | engines/agos/icons.cpp | 781 | ||||
| -rw-r--r-- | engines/agos/rooms.cpp | 140 | ||||
| -rw-r--r-- | engines/agos/script_e1.cpp | 2 | ||||
| -rw-r--r-- | engines/agos/script_e2.cpp | 2 | ||||
| -rw-r--r-- | engines/agos/script_ww.cpp | 8 | ||||
| -rw-r--r-- | engines/agos/string.cpp | 330 | ||||
| -rw-r--r-- | engines/agos/subroutine.cpp | 10 | ||||
| -rw-r--r-- | engines/agos/window.cpp | 34 | 
12 files changed, 901 insertions, 733 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 3bb984f199..9fb27cb746 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -635,135 +635,161 @@ static const uint16 initialVideoWindows_Common[20] = {  	 3, 3, 14, 127,  }; -void AGOSEngine::setupGame() { -	if (getGameType() == GType_PP) { -		gss = PTR(puzzlepack_settings); -		_numVideoOpcodes = 85; +void AGOSEngine_PuzzlePack::setupGame() { +	gss = PTR(puzzlepack_settings); +	_numVideoOpcodes = 85;  #ifndef PALMOS_68K -		_vgaMemSize = 7500000; +	_vgaMemSize = 7500000;  #else -		_vgaMemSize = gVars->memory[kMemSimon2Games]; +	_vgaMemSize = gVars->memory[kMemSimon2Games];  #endif -		_itemMemSize = 20000; -		_tableMemSize = 200000; -		_frameRate = 1; -		_vgaBaseDelay = 5; -		_numBitArray1 = 128; -		_numItemStore = 10; -		_numTextBoxes = 40; -		_numVars = 2048; -	} else if (getGameType() == GType_FF) { -		gss = PTR(feeblefiles_settings); -		_numVideoOpcodes = 85; +	_itemMemSize = 20000; +	_tableMemSize = 200000; +	_frameRate = 1; +	_vgaBaseDelay = 5; +	_numBitArray1 = 128; +	_numItemStore = 10; +	_numTextBoxes = 40; +	_numVars = 2048; + +	AGOSEngine::setupGame(); +} + +void AGOSEngine_Feeble::setupGame() { +	gss = PTR(feeblefiles_settings); +	_numVideoOpcodes = 85;  #ifndef PALMOS_68K -		_vgaMemSize = 7500000; +	_vgaMemSize = 7500000;  #else -		_vgaMemSize = gVars->memory[kMemSimon2Games]; +	_vgaMemSize = gVars->memory[kMemSimon2Games];  #endif -		_itemMemSize = 20000; -		_tableMemSize = 200000; -		_frameRate = 1; -		_vgaBaseDelay = 5; -		_numBitArray1 = 16; -		_numBitArray2 = 16; -		_numBitArray3 = 16; -		_numItemStore = 10; -		_numTextBoxes = 40; -		_numVars = 255; -	} else if (getGameType() == GType_SIMON2) { -		gss = PTR(simon2_settings); -		_tableIndexBase = 1580 / 4; -		_textIndexBase = 1500 / 4; -		_numVideoOpcodes = 75; +	_itemMemSize = 20000; +	_tableMemSize = 200000; +	_frameRate = 1; +	_vgaBaseDelay = 5; +	_numBitArray1 = 16; +	_numBitArray2 = 16; +	_numBitArray3 = 16; +	_numItemStore = 10; +	_numTextBoxes = 40; +	_numVars = 255; + +	AGOSEngine::setupGame(); +} + +void AGOSEngine_Simon2::setupGame() { +	gss = PTR(simon2_settings); +	_tableIndexBase = 1580 / 4; +	_textIndexBase = 1500 / 4; +	_numVideoOpcodes = 75;  #ifndef PALMOS_68K -		_vgaMemSize = 2000000; +	_vgaMemSize = 2000000;  #else -		_vgaMemSize = gVars->memory[kMemSimon2Games]; +	_vgaMemSize = gVars->memory[kMemSimon2Games];  #endif -		_itemMemSize = 20000; -		_tableMemSize = 100000; -		// Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2 -		if ((getGameType() == GType_SIMON2) && _native_mt32) -			_musicIndexBase = (1128 + 612) / 4; -		else -			_musicIndexBase = 1128 / 4; -		_soundIndexBase = 1660 / 4; -		_frameRate = 1; -		_vgaBaseDelay = 1; -		_numBitArray1 = 16; -		_numBitArray2 = 16; -		_numItemStore = 10; -		_numTextBoxes = 20; -		_numVars = 255; -	} else if (getGameType() == GType_SIMON1) { -		gss = PTR(simon1_settings); -		_tableIndexBase = 1576 / 4; -		_textIndexBase = 1460 / 4; -		_numVideoOpcodes = 64; +	_itemMemSize = 20000; +	_tableMemSize = 100000; +	// Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2 +	if ((getGameType() == GType_SIMON2) && _native_mt32) +		_musicIndexBase = (1128 + 612) / 4; +	else +		_musicIndexBase = 1128 / 4; +	_soundIndexBase = 1660 / 4; +	_frameRate = 1; +	_vgaBaseDelay = 1; +	_numBitArray1 = 16; +	_numBitArray2 = 16; +	_numItemStore = 10; +	_numTextBoxes = 20; +	_numVars = 255; + +	AGOSEngine::setupGame(); +} + +void AGOSEngine_Simon1::setupGame() { +	gss = PTR(simon1_settings); +	_tableIndexBase = 1576 / 4; +	_textIndexBase = 1460 / 4; +	_numVideoOpcodes = 64;  #ifndef PALMOS_68K -		_vgaMemSize = 1000000; +	_vgaMemSize = 1000000;  #else -		_vgaMemSize = gVars->memory[kMemSimon1Games]; +	_vgaMemSize = gVars->memory[kMemSimon1Games];  #endif -		_itemMemSize = 20000; -		_tableMemSize = 50000; -		_musicIndexBase = 1316 / 4; -		_soundIndexBase = 0; -		_frameRate = 1; -		_vgaBaseDelay = 1; -		_numBitArray1 = 16; -		_numBitArray2 = 16; -		_numItemStore = 10; -		_numTextBoxes = 20; -		_numVars = 255; -	} else if (getGameType() == GType_WW) { -		gss = PTR(simon1_settings); -		_numVideoOpcodes = 64; +	_itemMemSize = 20000; +	_tableMemSize = 50000; +	_musicIndexBase = 1316 / 4; +	_soundIndexBase = 0; +	_frameRate = 1; +	_vgaBaseDelay = 1; +	_numBitArray1 = 16; +	_numBitArray2 = 16; +	_numItemStore = 10; +	_numTextBoxes = 20; +	_numVars = 255; + +	AGOSEngine::setupGame(); +} + +void AGOSEngine_Waxworks::setupGame() { +	gss = PTR(simon1_settings); +	_numVideoOpcodes = 64;  #ifndef PALMOS_68K -		_vgaMemSize = 1000000; +	_vgaMemSize = 1000000;  #else -		_vgaMemSize = gVars->memory[kMemSimon1Games]; +	_vgaMemSize = gVars->memory[kMemSimon1Games];  #endif -		_itemMemSize = 80000; -		_tableMemSize = 50000; -		_frameRate = 4; -		_vgaBaseDelay = 1; -		_numBitArray1 = 16; -		_numBitArray2 = 15; -		_numItemStore = 50; -		_numTextBoxes = 10; -		_numVars = 255; -	} else if (getGameType() == GType_ELVIRA2) { -		gss = PTR(simon1_settings); -		_numVideoOpcodes = 60; +	_itemMemSize = 80000; +	_tableMemSize = 50000; +	_frameRate = 4; +	_vgaBaseDelay = 1; +	_numBitArray1 = 16; +	_numBitArray2 = 15; +	_numItemStore = 50; +	_numTextBoxes = 10; +	_numVars = 255; + +	AGOSEngine::setupGame(); +} + +void AGOSEngine_Elvira2::setupGame() { +	gss = PTR(simon1_settings); +	_numVideoOpcodes = 60;  #ifndef PALMOS_68K -		_vgaMemSize = 1000000; +	_vgaMemSize = 1000000;  #else -		_vgaMemSize = gVars->memory[kMemSimon1Games]; +	_vgaMemSize = gVars->memory[kMemSimon1Games];  #endif -		_itemMemSize = 64000; -		_tableMemSize = 100000; -		_frameRate = 4; -		_vgaBaseDelay = 1; -		_numBitArray1 = 16; -		_numBitArray2 = 15; -		_numItemStore = 50; -		_numVars = 255; -	} else if (getGameType() == GType_ELVIRA1) { -		gss = PTR(simon1_settings); -		_numVideoOpcodes = 57; +	_itemMemSize = 64000; +	_tableMemSize = 100000; +	_frameRate = 4; +	_vgaBaseDelay = 1; +	_numBitArray1 = 16; +	_numBitArray2 = 15; +	_numItemStore = 50; +	_numVars = 255; + +	AGOSEngine::setupGame(); +} + +void AGOSEngine_Elvira1::setupGame() { +	gss = PTR(simon1_settings); +	_numVideoOpcodes = 57;  #ifndef PALMOS_68K -		_vgaMemSize = 1000000; +	_vgaMemSize = 1000000;  #else -		_vgaMemSize = gVars->memory[kMemSimon1Games]; +	_vgaMemSize = gVars->memory[kMemSimon1Games];  #endif -		_itemMemSize = 64000; -		_tableMemSize = 256000; -		_frameRate = 4; -		_vgaBaseDelay = 1; -		_numVars = 512; -	} +	_itemMemSize = 64000; +	_tableMemSize = 256000; +	_frameRate = 4; +	_vgaBaseDelay = 1; +	_numVars = 512; +	AGOSEngine::setupGame(); +} + +void AGOSEngine::setupGame() {  	allocItemHeap();  	allocTablesHeap(); diff --git a/engines/agos/agos.h b/engines/agos/agos.h index d1a57b7b18..2161903b7a 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -154,7 +154,7 @@ public:  	const AGOSGameDescription *_gameDescription;  	bool initGame(void); -	void setupGame(); +	virtual void setupGame();  	int getGameId() const;  	int getGameType() const; @@ -663,17 +663,7 @@ protected:  	// Elvira 1 specific  	Item *getDoorOf(Item *item, uint16 d);  	Item *getExitOf_e1(Item *item, uint16 d); -	void moveDirn_e1(Item *i, uint x); - -	// Elvira 2 specific -	int changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s); -	uint16 getExitState(Item *item, uint16 x, uint16 d); -	void setExitState(Item *i, uint16 n, uint16 d, uint16 s); -	void setSRExit(Item *i, int n, int d, uint16 s); -	void moveDirn_e2(Item *i, uint x); - -	// Waxworks specific -	void moveDirn_ww(Item *i, uint x); +	virtual void moveDirn(Item *i, uint x);  	int canPlace(Item *x, Item *y);  	int contains(Item *a, Item *b); @@ -701,14 +691,10 @@ protected:  	void mouseOff();  	void mouseOn(); -	bool loadTablesIntoMem(uint subr_id); -	bool loadTablesOldIntoMem(uint subr_id); -	bool loadTablesNewIntoMem(uint subr_id); +	virtual bool loadTablesIntoMem(uint subr_id);  	bool loadXTablesIntoMem(uint subr_id);  	void loadTextIntoMem(uint stringId); -	bool loadRoomItems(uint item); -  	uint loadTextFile(const char *filename, byte *dst);  	Common::File *openTablesFile(const char *filename);  	void closeTablesFile(Common::File *in); @@ -751,13 +737,13 @@ protected:  	void initMouse();  	virtual void drawMousePointer(); -	void addArrows(WindowBlock *window); +	virtual void addArrows(WindowBlock *window);  	void removeArrows(WindowBlock *window, uint num); -	void drawIcon(WindowBlock *window, uint icon, uint x, uint y); +	virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);  	bool hasIcon(Item *item);  	uint itemGetIconNumber(Item *item); -	uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); +	virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr);  	virtual void drawIconArray(uint i, Item *item_ptr, int line, int classMask); @@ -792,9 +778,7 @@ protected:  	void printVerbOf(uint hitarea_id);  	void showActionString(const byte *string); -	void printScreenText(uint vga_sprite_id, uint color, const char *string_ptr, int16 x, int16 y, int16 width); -	void sendInteractText(uint16 num, const char *fmt, ...); -	void printInteractText(uint16 num, const char *string); +	virtual void printScreenText(uint vga_sprite_id, uint color, const char *string_ptr, int16 x, int16 y, int16 width);  	void renderStringAmiga(uint vga_sprite_id, uint color, uint width, uint height, const char *txt);  	void renderString(uint vga_sprite_id, uint color, uint width, uint height, const char *txt); @@ -1041,7 +1025,6 @@ protected:  	virtual void drawImage(VC10_state *state); -	void scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY);  	void horizontalScroll(VC10_state *state);  	void verticalScroll(VC10_state *state); @@ -1191,6 +1174,7 @@ public:  	AGOSEngine_Elvira1(OSystem *system);  	//~AGOSEngine_Elvira1(); +	virtual void setupGame();  	virtual void setupOpcodes();  	virtual void setupVideoOpcodes(VgaOpcodeProc *op); @@ -1267,6 +1251,7 @@ public:  	AGOSEngine_Elvira2(OSystem *system);  	//~AGOSEngine_Elvira2(); +	virtual void setupGame();  	virtual void setupOpcodes();  	virtual void setupVideoOpcodes(VgaOpcodeProc *op); @@ -1322,6 +1307,18 @@ protected:  	};  	const OpcodeEntryElvira2 *_opcodesElvira2; + +	virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + +	virtual void addArrows(WindowBlock *window); +	virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); + +	virtual void moveDirn(Item *i, uint x); + +	int changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s); +	uint16 getExitState(Item *item, uint16 x, uint16 d); +	void setExitState(Item *i, uint16 n, uint16 d, uint16 s); +	void setSRExit(Item *i, int n, int d, uint16 s);  };  class AGOSEngine_Waxworks : public AGOSEngine_Elvira2 { @@ -1329,6 +1326,7 @@ public:  	AGOSEngine_Waxworks(OSystem *system);  	//~AGOSEngine_Waxworks(); +	virtual void setupGame();  	virtual void setupOpcodes();  	virtual void setupVideoOpcodes(VgaOpcodeProc *op); @@ -1340,7 +1338,6 @@ public:  	uint16 getBoxSize();  	uint16 checkFit(char *Ptr, int width, int lines); -	void oww_moveDirn();  	void oww_goto();  	void oww_addTextBox();  	void oww_setShortText(); @@ -1366,6 +1363,17 @@ protected:  	};  	const OpcodeEntryWaxworks *_opcodesWaxworks; + +	virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + +	virtual void addArrows(WindowBlock *window); +	virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); + +	virtual bool loadTablesIntoMem(uint subr_id); + +	bool loadRoomItems(uint item); + +	virtual void moveDirn(Item *i, uint x);  };  class AGOSEngine_Simon1 : public AGOSEngine_Waxworks { @@ -1373,6 +1381,7 @@ public:  	AGOSEngine_Simon1(OSystem *system);  	//~AGOSEngine_Simon1(); +	virtual void setupGame();  	virtual void setupOpcodes();  	virtual void setupVideoOpcodes(VgaOpcodeProc *op); @@ -1406,6 +1415,11 @@ protected:  	const OpcodeEntrySimon1 *_opcodesSimon1;  	virtual void drawImage(VC10_state *state); + +	virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + +	virtual void addArrows(WindowBlock *window); +	virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr);  };  class AGOSEngine_Simon2 : public AGOSEngine_Simon1 { @@ -1413,6 +1427,7 @@ public:  	AGOSEngine_Simon2(OSystem *system);  	//~AGOSEngine_Simon2(); +	virtual void setupGame();  	virtual void setupOpcodes();  	virtual void setupVideoOpcodes(VgaOpcodeProc *op); @@ -1438,6 +1453,11 @@ protected:  	};  	const OpcodeEntrySimon2 *_opcodesSimon2; + +	virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + +	virtual void addArrows(WindowBlock *window); +	virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr);  };  class AGOSEngine_Feeble : public AGOSEngine_Simon2 { @@ -1445,6 +1465,7 @@ public:  	AGOSEngine_Feeble(OSystem *system);  	//~AGOSEngine_Feeble(); +	virtual void setupGame();  	virtual void setupOpcodes();  	virtual void setupVideoOpcodes(VgaOpcodeProc *op); @@ -1494,10 +1515,14 @@ protected:  	const OpcodeEntryFeeble *_opcodesFeeble;  	virtual void drawImage(VC10_state *state); +	void scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY);  	void drawMousePart(int image, byte x, byte y);  	virtual void drawMousePointer(); +	virtual void addArrows(WindowBlock *window); +	virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); +  	virtual void resetVerbs();  	virtual void setVerb(HitArea * ha);  	virtual void hitarea_leave(HitArea * ha, bool state = false); @@ -1511,6 +1536,11 @@ protected:  	virtual void print_char_helper_1(const byte *src, uint len); +	virtual void printScreenText(uint vga_sprite_id, uint color, const char *string_ptr, int16 x, int16 y, int16 width); + +	void printInteractText(uint16 num, const char *string); +	void sendInteractText(uint16 num, const char *fmt, ...); +  	void checkLinkBox();   	void hyperLinkOn(uint16 x);   	void hyperLinkOff(); @@ -1538,6 +1568,7 @@ public:  	AGOSEngine_PuzzlePack(OSystem *system);  	//~AGOSEngine_PuzzlePack(); +	virtual void setupGame();  	virtual void setupOpcodes();  	virtual void executeOpcode(int opcode); diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index 48d275bea7..701a6af5f2 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -399,11 +399,11 @@ void AGOSEngine::updateScreen() {  		}  	} -	_system->copyRectToScreen(_backBuf, _screenWidth, 0, 0, _screenWidth, _screenHeight); +	_system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);  	_system->updateScreen();  	if (getGameId() != GID_DIMP) -		memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight); +		memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight);  	if (getGameType() == GType_FF && _scrollFlag) {  		scrollScreen(); diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp index e6b1a01950..d7e9f65b57 100644 --- a/engines/agos/gfx.cpp +++ b/engines/agos/gfx.cpp @@ -777,7 +777,7 @@ void AGOSEngine::verticalScroll(VC10_state *state) {  	}  } -void AGOSEngine::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) { +void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {  	Common::Rect srcRect, dstRect;  	float factor, xscale; diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp index 172d5374fd..1fc73620be 100644 --- a/engines/agos/icons.cpp +++ b/engines/agos/icons.cpp @@ -167,179 +167,115 @@ static void decompressIcon(byte *dst, byte *src, uint width, uint height, byte b  	}  } -void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { +void AGOSEngine_Simon2::drawIcon(WindowBlock *window, uint icon, uint x, uint y) {  	byte *dst;  	byte *src;  	_lockWord |= 0x8000;  	dst = getFrontBuf(); -	if (getGameType() == GType_SIMON2) { -		dst += 110; -		dst += x; -		dst += (y + window->y) * _dxSurfacePitch; +	dst += 110; +	dst += x; +	dst += (y + window->y) * _dxSurfacePitch; -		src = _iconFilePtr; -		src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 0]); -		decompressIcon(dst, src, 20, 10, 224, _dxSurfacePitch); +	src = _iconFilePtr; +	src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 0]); +	decompressIcon(dst, src, 20, 10, 224, _dxSurfacePitch); -		src = _iconFilePtr; -		src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 1]); -		decompressIcon(dst, src, 20, 10, 208, _dxSurfacePitch); -	} else if (getGameType() == GType_SIMON1) { -		dst += (x + window->x) * 8; -		dst += (y * 25 + window->y) * _dxSurfacePitch; - -		if (getPlatform() == Common::kPlatformAmiga) { -			src = _iconFilePtr; -			src += READ_BE_UINT32(&((uint32 *)src)[icon]); -			uint8 color = (getFeatures() & GF_32COLOR) ? 16 : 240; -			decompressIconAmiga(dst, src, 24, 24, color, _dxSurfacePitch); -		} else { -			src = _iconFilePtr; -			src += READ_LE_UINT16(&((uint16 *)src)[icon]); -			decompressIcon(dst, src, 24, 12, 224, _dxSurfacePitch); -		} -	} else if (getGameType() == GType_WW) { -		dst += (x + window->x) * 8; -		dst += (y * 20 + window->y) * _dxSurfacePitch; +	src = _iconFilePtr; +	src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 1]); +	decompressIcon(dst, src, 20, 10, 208, _dxSurfacePitch); -		uint8 color = dst[0] & 0xF0; +	_lockWord &= ~0x8000; +} -		if (getPlatform() == Common::kPlatformAmiga) { -			src = _iconFilePtr; -			src += READ_BE_UINT32(&((uint32 *)src)[icon]); -			decompressIconAmiga(dst, src, 24, 20, color, _dxSurfacePitch); -		} else { -			src = _iconFilePtr; -			src += READ_LE_UINT16(&((uint16 *)src)[icon]); -			decompressIcon(dst, src, 24, 10, color, _dxSurfacePitch); -		} -	} else if (getGameType() == GType_ELVIRA2) { -		dst += (x + window->x) * 8; -		dst += (y * 8 + window->y) * _dxSurfacePitch; +void AGOSEngine_Simon1::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { +	byte *dst; +	byte *src; -		uint color = dst[0] & 0xF0; +	_lockWord |= 0x8000; +	dst = getFrontBuf(); -		if (getPlatform() == Common::kPlatformAmiga) { -			src = _iconFilePtr; -			src += READ_BE_UINT32(&((uint32 *)src)[icon]); -			decompressIconAmiga(dst, src, 24, 24, color, _dxSurfacePitch); -		} else { -			src = _iconFilePtr; -			src += READ_LE_UINT16(&((uint16 *)src)[icon]); -			decompressIcon(dst, src, 24, 12, color, _dxSurfacePitch); -		} -	} else if (getGameType() == GType_ELVIRA1) { -		dst += (x + window->x) * 8; -		dst += (y * 8 + window->y) * _dxSurfacePitch; +	dst += (x + window->x) * 8; +	dst += (y * 25 + window->y) * _dxSurfacePitch; +	if (getPlatform() == Common::kPlatformAmiga) {  		src = _iconFilePtr; -		src += icon * 288; -		decompressIconAmiga(dst, src, 24, 24, 16, _dxSurfacePitch, false); +		src += READ_BE_UINT32(&((uint32 *)src)[icon]); +		uint8 color = (getFeatures() & GF_32COLOR) ? 16 : 240; +		decompressIconAmiga(dst, src, 24, 24, color, _dxSurfacePitch); +	} else { +		src = _iconFilePtr; +		src += READ_LE_UINT16(&((uint16 *)src)[icon]); +		decompressIcon(dst, src, 24, 12, 224, _dxSurfacePitch);  	}  	_lockWord &= ~0x8000;  } -void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) { -	Item *item_ptr_org = itemRef; -	WindowBlock *window; -	uint width, height; -	uint k, i, curWidth; -	bool item_again, showArrows; -	uint x_pos, y_pos; -	const int iconSize = (getGameType() == GType_SIMON2) ? 20 : 1; +void AGOSEngine_Waxworks::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { +	byte *dst; +	byte *src; -	window = _windowArray[num & 7]; +	_lockWord |= 0x8000; +	dst = getFrontBuf(); -	if (getGameType() == GType_SIMON2) { -		width = 100; -		height = 40; +	dst += (x + window->x) * 8; +	dst += (y * 20 + window->y) * _dxSurfacePitch; + +	uint8 color = dst[0] & 0xF0; +	if (getPlatform() == Common::kPlatformAmiga) { +		src = _iconFilePtr; +		src += READ_BE_UINT32(&((uint32 *)src)[icon]); +		decompressIconAmiga(dst, src, 24, 20, color, _dxSurfacePitch);  	} else { -		width = window->width / 3; -		height = window->height / 3; +		src = _iconFilePtr; +		src += READ_LE_UINT16(&((uint16 *)src)[icon]); +		decompressIcon(dst, src, 24, 10, color, _dxSurfacePitch);  	} -	i = 0; - -	if (window == NULL) -		return; +	_lockWord &= ~0x8000; +} -	if (window->iconPtr) -		removeIconArray(num); +void AGOSEngine_Elvira2::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { +	byte *dst; +	byte *src; -	window->iconPtr = (IconBlock *) malloc(sizeof(IconBlock)); -	window->iconPtr->itemRef = itemRef; -	window->iconPtr->upArrow = -1; -	window->iconPtr->downArrow = -1; -	window->iconPtr->line = line; -	window->iconPtr->classMask = classMask; +	_lockWord |= 0x8000; +	dst = getFrontBuf(); -	itemRef = derefItem(itemRef->child); +	dst += (x + window->x) * 8; +	dst += (y * 8 + window->y) * _dxSurfacePitch; -	while (itemRef && line-- != 0) { -		curWidth = 0; -		while (itemRef && width > curWidth) { -			if ((classMask == 0 || itemRef->classFlags & classMask) && hasIcon(itemRef)) -				curWidth += iconSize; -			itemRef = derefItem(itemRef->next); +	uint color = dst[0] & 0xF0; +	if (getPlatform() == Common::kPlatformAmiga) { +		src = _iconFilePtr; +		src += READ_BE_UINT32(&((uint32 *)src)[icon]); +		decompressIconAmiga(dst, src, 24, 24, color, _dxSurfacePitch); +	} else { +		src = _iconFilePtr; +		src += READ_LE_UINT16(&((uint16 *)src)[icon]); +	decompressIcon(dst, src, 24, 12, color, _dxSurfacePitch);  		} -	} -	if (itemRef == NULL) { -		window->iconPtr->line = 0; -		itemRef = derefItem(item_ptr_org->child); -	} +	_lockWord &= ~0x8000; +} -	x_pos = 0; -	y_pos = 0; -	k = 0; -	item_again = false; -	showArrows = false; +void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { +	byte *dst; +	byte *src; -	while (itemRef) { -		if ((classMask == 0 || itemRef->classFlags & classMask) && hasIcon(itemRef)) { -			if (item_again == false) { -				window->iconPtr->iconArray[k].item = itemRef; -				if (getGameType() == GType_SIMON2) { -					drawIcon(window, itemGetIconNumber(itemRef), x_pos, y_pos); -					window->iconPtr->iconArray[k].boxCode = -						setupIconHitArea(window, 0, x_pos, y_pos, itemRef); -				} else if (getGameType() == GType_SIMON1) { -					drawIcon(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos); -					window->iconPtr->iconArray[k].boxCode = -						setupIconHitArea(window, 0, x_pos * 3, y_pos, itemRef); -				} else { -					drawIcon(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos * 3); -					window->iconPtr->iconArray[k].boxCode = -						setupIconHitArea(window, 0, x_pos * 3, y_pos * 3, itemRef); -				} -				k++; -			} else { -				window->iconPtr->iconArray[k].item = NULL; -				showArrows = 1; -			} +	_lockWord |= 0x8000; +	dst = getFrontBuf(); -			x_pos += iconSize; -			if (x_pos >= width) { -				x_pos = 0; -				y_pos += iconSize; -				if (y_pos >= height) -					item_again = true; -			} -		} -		itemRef = derefItem(itemRef->next); -	} +	dst += (x + window->x) * 8; +	dst += (y * 8 + window->y) * _dxSurfacePitch; -	window->iconPtr->iconArray[k].item = NULL; +	src = _iconFilePtr; +	src += icon * 288; +	decompressIconAmiga(dst, src, 24, 24, 16, _dxSurfacePitch, false); -	if (showArrows != 0 || window->iconPtr->line != 0) { -		/* Plot arrows and add their boxes */ -		addArrows(window);		 -		window->iconPtr->upArrow = _scrollUpHitArea; -		window->iconPtr->downArrow = _scrollDownHitArea; -	} +	_lockWord &= ~0x8000;  }  void AGOSEngine_Feeble::drawIconArray(uint num, Item *itemRef, int line, int classMask) { @@ -446,227 +382,400 @@ l1:;		itemRef = derefItem(itemRef->next);  	window->iconPtr->downArrow = _scrollDownHitArea;  } -uint AGOSEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { -	HitArea *ha; +void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) { +	Item *item_ptr_org = itemRef; +	WindowBlock *window; +	uint width, height; +	uint k, i, curWidth; +	bool item_again, showArrows; +	uint x_pos, y_pos; +	const int iconSize = (getGameType() == GType_SIMON2) ? 20 : 1; -	ha = findEmptyHitArea(); +	window = _windowArray[num & 7]; -	if (getGameType() == GType_FF) { -		ha->x = x; -		ha->y = y; -		ha->item_ptr = item_ptr; -		ha->width = 45; -		ha->height = 44; -		ha->flags = kBFBoxInUse | kBFBoxItem; -		ha->id = num; -		ha->priority = 100; -		ha->verb = 208; -	} else if (getGameType() == GType_SIMON2) { -		ha->x = x + 110; -		ha->y = window->y + y; -		ha->item_ptr = item_ptr; -		ha->width = 20; -		ha->height = 20; -		ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; -		ha->id = 0x7FFD; -		ha->priority = 100; -		ha->verb = 208; -	} else if (getGameType() == GType_SIMON1) { -		ha->x = (x + window->x) * 8; -		ha->y = y * 25 + window->y; -		ha->item_ptr = item_ptr; -		ha->width = 24; -		ha->height = 24; -		ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; -		ha->id = 0x7FFD; -		ha->priority = 100; -		ha->verb = 208; -	} else if (getGameType() == GType_WW) { -		ha->x = (x + window->x) * 8; -		ha->y = y * 20 + window->y; -		ha->item_ptr = item_ptr; -		ha->width = 24; -		ha->height = 20; -		ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; -		ha->id = 0x7FFD; -		ha->priority = 100; -		ha->verb = 208; -	} else if (getGameType() == GType_ELVIRA2) { -		ha->x = (x + window->x) * 8; -		ha->y = y * 8 + window->y; -		ha->item_ptr = item_ptr; -		ha->width = 24; -		ha->height = 24; -		ha->id = 0x7FFD; -		ha->priority = 100; - -		if (window->iconPtr->classMask == 2) { -			ha->flags = kBFDragBox | kBFBoxInUse; -			ha->verb = 248 + 0x4000; -		} else { -			ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; -			ha->verb = 208; +	if (getGameType() == GType_SIMON2) { +		width = 100; +		height = 40; +	} else { +		width = window->width / 3; +		height = window->height / 3; +	} + +	i = 0; + +	if (window == NULL) +		return; + +	if (window->iconPtr) +		removeIconArray(num); + +	window->iconPtr = (IconBlock *) malloc(sizeof(IconBlock)); +	window->iconPtr->itemRef = itemRef; +	window->iconPtr->upArrow = -1; +	window->iconPtr->downArrow = -1; +	window->iconPtr->line = line; +	window->iconPtr->classMask = classMask; + +	itemRef = derefItem(itemRef->child); + +	while (itemRef && line-- != 0) { +		curWidth = 0; +		while (itemRef && width > curWidth) { +			if ((classMask == 0 || itemRef->classFlags & classMask) && hasIcon(itemRef)) +				curWidth += iconSize; +			itemRef = derefItem(itemRef->next);  		} +	} + +	if (itemRef == NULL) { +		window->iconPtr->line = 0; +		itemRef = derefItem(item_ptr_org->child); +	} + +	x_pos = 0; +	y_pos = 0; +	k = 0; +	item_again = false; +	showArrows = false; + +	while (itemRef) { +		if ((classMask == 0 || itemRef->classFlags & classMask) && hasIcon(itemRef)) { +			if (item_again == false) { +				window->iconPtr->iconArray[k].item = itemRef; +				if (getGameType() == GType_SIMON2) { +					drawIcon(window, itemGetIconNumber(itemRef), x_pos, y_pos); +					window->iconPtr->iconArray[k].boxCode = +						setupIconHitArea(window, 0, x_pos, y_pos, itemRef); +				} else if (getGameType() == GType_SIMON1) { +					drawIcon(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos); +					window->iconPtr->iconArray[k].boxCode = +						setupIconHitArea(window, 0, x_pos * 3, y_pos, itemRef); +				} else { +					drawIcon(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos * 3); +					window->iconPtr->iconArray[k].boxCode = +						setupIconHitArea(window, 0, x_pos * 3, y_pos * 3, itemRef); +				} +				k++; +			} else { +				window->iconPtr->iconArray[k].item = NULL; +				showArrows = 1; +			} + +			x_pos += iconSize; +			if (x_pos >= width) { +				x_pos = 0; +				y_pos += iconSize; +				if (y_pos >= height) +					item_again = true; +			} +		} +		itemRef = derefItem(itemRef->next); +	} + +	window->iconPtr->iconArray[k].item = NULL; + +	if (showArrows != 0 || window->iconPtr->line != 0) { +		/* Plot arrows and add their boxes */ +		addArrows(window);		 +		window->iconPtr->upArrow = _scrollUpHitArea; +		window->iconPtr->downArrow = _scrollDownHitArea; +	} +} + +uint AGOSEngine_Feeble::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { +	HitArea *ha = findEmptyHitArea(); + +	ha->x = x; +	ha->y = y; +	ha->item_ptr = item_ptr; +	ha->width = 45; +	ha->height = 44; +	ha->flags = kBFBoxInUse | kBFBoxItem; +	ha->id = num; +	ha->priority = 100; +	ha->verb = 208; + +	return ha - _hitAreas; +} + +uint AGOSEngine_Simon2::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { +	HitArea *ha = findEmptyHitArea(); + +	ha->x = x + 110; +	ha->y = window->y + y; +	ha->item_ptr = item_ptr; +	ha->width = 20; +	ha->height = 20; +	ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; +	ha->id = 0x7FFD; +	ha->priority = 100; +	ha->verb = 208; + +	return ha - _hitAreas; +} + +uint AGOSEngine_Simon1::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { +	HitArea *ha = findEmptyHitArea(); + +	ha->x = (x + window->x) * 8; +	ha->y = y * 25 + window->y; +	ha->item_ptr = item_ptr; +	ha->width = 24; +	ha->height = 24; +	ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; +	ha->id = 0x7FFD; +	ha->priority = 100; +	ha->verb = 208; + +	return ha - _hitAreas; +} + +uint AGOSEngine_Waxworks::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { +	HitArea *ha = findEmptyHitArea(); + +	ha->x = (x + window->x) * 8; +	ha->y = y * 20 + window->y; +	ha->item_ptr = item_ptr; +	ha->width = 24; +	ha->height = 20; +	ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; +	ha->id = 0x7FFD; +	ha->priority = 100; +	ha->verb = 208; + +	return ha - _hitAreas; +} + +uint AGOSEngine_Elvira2::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { +	HitArea *ha = findEmptyHitArea(); + +	ha->x = (x + window->x) * 8; +	ha->y = y * 8 + window->y; +	ha->item_ptr = item_ptr; +	ha->width = 24; +	ha->height = 24; +	ha->id = 0x7FFD; +	ha->priority = 100; + +	if (window->iconPtr->classMask == 2) { +		ha->flags = kBFDragBox | kBFBoxInUse; +		ha->verb = 248 + 0x4000;  	} else { -		ha->x = (x + window->x) * 8; -		ha->y = y * 8 + window->y; -		ha->item_ptr = item_ptr; -		ha->width = 24; -		ha->height = 24;  		ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; -		ha->id = 0x7FFD; -		ha->priority = 100; -		ha->verb = 253; +		ha->verb = 208;  	}  	return ha - _hitAreas;  } -void AGOSEngine::addArrows(WindowBlock *window) { +uint AGOSEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { +	HitArea *ha = findEmptyHitArea(); + +	ha->x = (x + window->x) * 8; +	ha->y = y * 8 + window->y; +	ha->item_ptr = item_ptr; +	ha->width = 24; +	ha->height = 24; +	ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; +	ha->id = 0x7FFD; +	ha->priority = 100; +	ha->verb = 253; + +	return ha - _hitAreas; +} + +void AGOSEngine_Feeble::addArrows(WindowBlock *window) {  	HitArea *ha;  	ha = findEmptyHitArea();  	_scrollUpHitArea = ha - _hitAreas; -	if (getGameType() == GType_FF) { -		ha->x = 496; -		ha->y = 279; -		ha->width = 30; -		ha->height = 45; -		ha->flags = kBFBoxInUse | kBFNoTouchName; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -	} else if (getGameType() == GType_SIMON2) { -		ha->x = 81; -		ha->y = 158; -		ha->width = 12; -		ha->height = 26; -		ha->flags = kBFBoxInUse | kBFNoTouchName; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -	} else if (getGameType() == GType_SIMON1) { -		ha->x = 308; -		ha->y = 149; -		ha->width = 12; -		ha->height = 17; -		ha->flags = kBFBoxInUse | kBFNoTouchName; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -	} else if (getGameType() == GType_WW) { -		setBitFlag(22, true); -		ha->x = 255; -		ha->y = 153; -		ha->width = 9; -		ha->height = 11; -		ha->flags = kBFBoxInUse | kBFNoTouchName; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -	} else if (getGameType() == GType_ELVIRA2) { -		setBitFlag(21, true); -		ha->x = 54; -		ha->y = 154; -		ha->width = 12; -		ha->height = 10; -		ha->flags = kBFBoxInUse; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -	} else { -		ha->x = 30 * 8; -		ha->y = 151; -		ha->width = 16; -		ha->height = 19; -		ha->flags = kBFBoxInUse; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -	} + +	ha->x = 496; +	ha->y = 279; +	ha->width = 30; +	ha->height = 45; +	ha->flags = kBFBoxInUse | kBFNoTouchName; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; + +	ha = findEmptyHitArea(); +	_scrollDownHitArea = ha - _hitAreas; + +	ha->x = 496; +	ha->y = 324; +	ha->width = 30; +	ha->height = 44; +	ha->flags = kBFBoxInUse | kBFNoTouchName; +	ha->id = 0x7FFC; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; +} + +void AGOSEngine_Simon2::addArrows(WindowBlock *window) { +	HitArea *ha; + +	ha = findEmptyHitArea(); +	_scrollUpHitArea = ha - _hitAreas; + +	ha->x = 81; +	ha->y = 158; +	ha->width = 12; +	ha->height = 26; +	ha->flags = kBFBoxInUse | kBFNoTouchName; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1;  	ha = findEmptyHitArea();  	_scrollDownHitArea = ha - _hitAreas; -	if (getGameType() == GType_FF) { -		ha->x = 496; -		ha->y = 324; -		ha->width = 30; -		ha->height = 44; -		ha->flags = kBFBoxInUse | kBFNoTouchName; -		ha->id = 0x7FFC; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -	} else if (getGameType() == GType_SIMON2) { -		ha->x = 227; -		ha->y = 162; -		ha->width = 12; -		ha->height = 26; -		ha->flags = kBFBoxInUse | kBFNoTouchName; -		ha->id = 0x7FFC; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -	} else if (getGameType() == GType_SIMON1) { -		ha->x = 308; -		ha->y = 176; -		ha->width = 12; -		ha->height = 17; -		ha->flags = kBFBoxInUse | kBFNoTouchName; -		ha->id = 0x7FFC; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; +	ha->x = 227; +	ha->y = 162; +	ha->width = 12; +	ha->height = 26; +	ha->flags = kBFBoxInUse | kBFNoTouchName; +	ha->id = 0x7FFC; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; +} -		if (getFeatures() & GF_32COLOR) { -			// TODO: Manually draws arrows -		} else { -			stopAnimate(128); -			uint8 palette = (getGameId() == GID_SIMON1CD32) ? 15: 14; -			animate(0, 1, 128, 0, 0, palette); -		} -	} else if (getGameType() == GType_WW) { -		ha->x = 255; -		ha->y = 170; -		ha->width = 9; -		ha->height = 11; -		ha->flags = kBFBoxInUse | kBFNoTouchName; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -		setWindowImageEx(6, 103); -	} else if (getGameType() == GType_ELVIRA2) { -		ha->x = 54; -		ha->y = 178; -		ha->width = 12; -		ha->height = 10; -		ha->flags = kBFBoxInUse; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; -		setWindowImageEx(6, 106); +void AGOSEngine_Simon1::addArrows(WindowBlock *window) { +	HitArea *ha; + +	ha = findEmptyHitArea(); +	_scrollUpHitArea = ha - _hitAreas; + +	ha->x = 308; +	ha->y = 149; +	ha->width = 12; +	ha->height = 17; +	ha->flags = kBFBoxInUse | kBFNoTouchName; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; + +	ha = findEmptyHitArea(); +	_scrollDownHitArea = ha - _hitAreas; + +	ha->x = 308; +	ha->y = 176; +	ha->width = 12; +	ha->height = 17; +	ha->flags = kBFBoxInUse | kBFNoTouchName; +	ha->id = 0x7FFC; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; + +	if (getFeatures() & GF_32COLOR) { +		// TODO: Manually draws arrows  	} else { -		ha->x = 30 * 8; -		ha->y = 170; -		ha->width = 16; -		ha->height = 19; -		ha->flags = kBFBoxInUse; -		ha->id = 0x7FFB; -		ha->priority = 100; -		ha->window = window; -		ha->verb = 1; +		stopAnimate(128); +		uint8 palette = (getGameId() == GID_SIMON1CD32) ? 15: 14; +		animate(0, 1, 128, 0, 0, palette);  	}  } +void AGOSEngine_Waxworks::addArrows(WindowBlock *window) { +	HitArea *ha; + +	ha = findEmptyHitArea(); +	_scrollUpHitArea = ha - _hitAreas; + +	setBitFlag(22, true); +	ha->x = 255; +	ha->y = 153; +	ha->width = 9; +	ha->height = 11; +	ha->flags = kBFBoxInUse | kBFNoTouchName; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; + +	ha = findEmptyHitArea(); +	_scrollDownHitArea = ha - _hitAreas; + +	ha->x = 255; +	ha->y = 170; +	ha->width = 9; +	ha->height = 11; +	ha->flags = kBFBoxInUse | kBFNoTouchName; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; +	setWindowImageEx(6, 103); +} + +void AGOSEngine_Elvira2::addArrows(WindowBlock *window) { +	HitArea *ha; + +	ha = findEmptyHitArea(); +	_scrollUpHitArea = ha - _hitAreas; + +	setBitFlag(21, true); +	ha->x = 54; +	ha->y = 154; +	ha->width = 12; +	ha->height = 10; +	ha->flags = kBFBoxInUse; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; + +	ha = findEmptyHitArea(); +	_scrollDownHitArea = ha - _hitAreas; + +	ha->x = 54; +	ha->y = 178; +	ha->width = 12; +	ha->height = 10; +	ha->flags = kBFBoxInUse; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; +	setWindowImageEx(6, 106); +} + +void AGOSEngine::addArrows(WindowBlock *window) { +	HitArea *ha; + +	ha = findEmptyHitArea(); +	_scrollUpHitArea = ha - _hitAreas; + +	ha->x = 30 * 8; +	ha->y = 151; +	ha->width = 16; +	ha->height = 19; +	ha->flags = kBFBoxInUse; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; + +	ha = findEmptyHitArea(); +	_scrollDownHitArea = ha - _hitAreas; + +	ha->x = 30 * 8; +	ha->y = 170; +	ha->width = 16; +	ha->height = 19; +	ha->flags = kBFBoxInUse; +	ha->id = 0x7FFB; +	ha->priority = 100; +	ha->window = window; +	ha->verb = 1; +} +  void AGOSEngine::removeArrows(WindowBlock *window, uint num) {  	if (getGameType() == GType_SIMON1) {  		if (getFeatures() & GF_32COLOR) { diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index bd66d43722..3996b33839 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -158,7 +158,69 @@ Item *AGOSEngine::getExitOf_e1(Item *item, uint16 d) {  	return derefItem(x->parent);  } -void AGOSEngine::moveDirn_e1(Item *i, uint x) { +void AGOSEngine_Waxworks::moveDirn(Item *i, uint x) { +	Item *d; +	uint16 n; + +	if (i->parent == 0) +		return; + +	n = getExitOf(derefItem(i->parent), x); +	if (derefItem(n) == NULL) { +		loadRoomItems(n); +		n = getExitOf(derefItem(i->parent), x); +	} + +	d = derefItem(n); +	if (d) { +		n = getDoorState(derefItem(i->parent), x); +		if (n == 1) { +			if (!canPlace(i, d)) +				setItemParent(i, d); +		} +	} +} + +void AGOSEngine_Elvira2::moveDirn(Item *i, uint x) { +	SubSuperRoom *sr; +	Item *d, *p; +	uint16 a, n; + +	if (i->parent == 0) +		return; + +	p = derefItem(i->parent); +	if (findChildOfType(p, 4)) { +		n = getExitState(p, _superRoomNumber,x); +		if (n == 1) { +			sr = (SubSuperRoom *)findChildOfType(p, 4); +			switch (x) { +				case 0: a = -(sr->roomX); break; +				case 1: a = 1; break; +				case 2: a = sr->roomX; break; +				case 3: a = 0xFFFF; break; +				case 4: a = -(sr->roomX * sr->roomY); break; +				case 5: a = (sr->roomX * sr->roomY); break; +				default: return; +			} +			_superRoomNumber += a; +		} +		return; +	} + +	n = getExitOf(derefItem(i->parent), x); + +	d = derefItem(n); +	if (d) { +		n = getDoorState(derefItem(i->parent), x); +		if (n == 1) { +			if (!canPlace(i, d)) +				setItemParent(i, d); +		} +	} +} + +void AGOSEngine::moveDirn(Item *i, uint x) {  	Item *d, *p;  	p = derefItem(i->parent); @@ -189,7 +251,7 @@ void AGOSEngine::moveDirn_e1(Item *i, uint x) {  }  // Elvira 2 specific -int AGOSEngine::changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s) { +int AGOSEngine_Elvira2::changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s) {  	int b, bd;  	uint16 mask = 3;  	uint16 bs = s; @@ -250,7 +312,7 @@ int AGOSEngine::changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s) {  	return 1;  } -uint16 AGOSEngine::getExitState(Item *i, uint16 x, uint16 d) { +uint16 AGOSEngine_Elvira2::getExitState(Item *i, uint16 x, uint16 d) {  	SubSuperRoom *sr;  	uint16 mask = 3;  	uint16 n; @@ -266,13 +328,13 @@ uint16 AGOSEngine::getExitState(Item *i, uint16 x, uint16 d) {  	return n;  } -void AGOSEngine::setExitState(Item *i, uint16 n, uint16 d, uint16 s) { +void AGOSEngine_Elvira2::setExitState(Item *i, uint16 n, uint16 d, uint16 s) {  	SubSuperRoom *sr = (SubSuperRoom *)findChildOfType(i, 4);  	if (sr)  		changeExitStates(sr, n, d, s);  } -void AGOSEngine::setSRExit(Item *i, int n, int d, uint16 s) { +void AGOSEngine_Elvira2::setSRExit(Item *i, int n, int d, uint16 s) {  	uint16 mask = 3;  	SubSuperRoom *sr = (SubSuperRoom *)findChildOfType(i, 4); @@ -286,74 +348,8 @@ void AGOSEngine::setSRExit(Item *i, int n, int d, uint16 s) {  	}  } -void AGOSEngine::moveDirn_e2(Item *i, uint x) { -	SubSuperRoom *sr; -	Item *d, *p; -	uint16 a, n; - -	if (i->parent == 0) -		return; - -	p = derefItem(i->parent); -	if (findChildOfType(p, 4)) { -		n = getExitState(p, _superRoomNumber,x); -		if (n == 1) { -			sr = (SubSuperRoom *)findChildOfType(p, 4); -			switch (x) { -				case 0: a = -(sr->roomX); break; -				case 1: a = 1; break; -				case 2: a = sr->roomX; break; -				case 3: a = 0xFFFF; break; -				case 4: a = -(sr->roomX * sr->roomY); break; -				case 5: a = (sr->roomX * sr->roomY); break; -				default: return; -			} -			_superRoomNumber += a; -		} -		return; -	} - -	n = getExitOf(derefItem(i->parent), x); -	if (derefItem(n) == NULL) { -		loadRoomItems(n); -		n=getExitOf(derefItem(i->parent), x); -	} - -	d = derefItem(n); -	if (d) { -		n = getDoorState(derefItem(i->parent), x); -		if (n == 1) { -			if (!canPlace(i, d)) -				setItemParent(i, d); -		} -	} -} -  // Waxworks specific -void AGOSEngine::moveDirn_ww(Item *i, uint x) { -	Item *d; -	uint16 n; - -	if (i->parent == 0) -		return; - -	n = getExitOf(derefItem(i->parent), x); -	if (derefItem(n) == NULL) { -		loadRoomItems(n); -		n = getExitOf(derefItem(i->parent), x); -	} - -	d = derefItem(n); -	if (d) { -		n = getDoorState(derefItem(i->parent), x); -		if (n == 1) { -			if (!canPlace(i, d)) -				setItemParent(i, d); -		} -	} -} - -bool AGOSEngine::loadRoomItems(uint item) { +bool AGOSEngine_Waxworks::loadRoomItems(uint item) {  	byte *p;  	uint i, min_num, max_num;  	char filename[30]; diff --git a/engines/agos/script_e1.cpp b/engines/agos/script_e1.cpp index 4196cd9567..b74c4f3c19 100644 --- a/engines/agos/script_e1.cpp +++ b/engines/agos/script_e1.cpp @@ -525,7 +525,7 @@ void AGOSEngine_Elvira1::oe1_setFF() {  void AGOSEngine_Elvira1::oe1_moveDirn() {  	// 54: move direction  	int16 d = readVariable(getVarOrWord()); -	moveDirn_e1(me(), d); +	moveDirn(me(), d);  }  void AGOSEngine_Elvira1::oe1_score() { diff --git a/engines/agos/script_e2.cpp b/engines/agos/script_e2.cpp index cab8f6ddf5..ebcde7b038 100644 --- a/engines/agos/script_e2.cpp +++ b/engines/agos/script_e2.cpp @@ -279,7 +279,7 @@ void AGOSEngine_Elvira2::executeOpcode(int opcode) {  void AGOSEngine_Elvira2::oe2_moveDirn() {  	// 54: move direction  	int16 d = getVarOrByte(); -	moveDirn_e2(me(), d); +	moveDirn(me(), d);  }  void AGOSEngine_Elvira2::oe2_doClass() { diff --git a/engines/agos/script_ww.cpp b/engines/agos/script_ww.cpp index 9a8e62de92..bd825934c6 100644 --- a/engines/agos/script_ww.cpp +++ b/engines/agos/script_ww.cpp @@ -101,7 +101,7 @@ void AGOSEngine_Waxworks::setupOpcodes() {  		/* 52 */  		OPCODE(o_modf),  		OPCODE(o_random), -		OPCODE(oww_moveDirn), +		OPCODE(oe2_moveDirn),  		OPCODE(oww_goto),  		/* 56 */  		OPCODE(o_oset), @@ -287,12 +287,6 @@ void AGOSEngine_Waxworks::executeOpcode(int opcode) {  // Waxworks Opcodes  // ----------------------------------------------------------------------- -void AGOSEngine_Waxworks::oww_moveDirn() { -	// 54: move direction -	int16 d = getVarOrByte(); -	moveDirn_ww(me(), d); -} -  void AGOSEngine_Waxworks::oww_goto() {  	// 55: set itemA parent  	uint item = getNextItemID(); diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp index f4ceb4239b..6b85f88733 100644 --- a/engines/agos/string.cpp +++ b/engines/agos/string.cpp @@ -289,7 +289,162 @@ bool AGOSEngine::printNameOf(Item *item, uint x, uint y) {  	return true;  } -void AGOSEngine::printInteractText(uint16 num, const char *string) { +void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) { +	char convertedString[320]; +	char *convertedString2 = convertedString; +	int16 height, talkDelay; +	int stringLength = strlen(string); +	int padding, lettersPerRow, lettersPerRowJustified; +	const int textHeight = 10; + +	height = textHeight; +	lettersPerRow = width / 6; +	lettersPerRowJustified = stringLength / (stringLength / lettersPerRow + 1) + 1; + +	talkDelay = (stringLength + 3) / 3; +	if ((getGameType() == GType_SIMON1) && (getFeatures() & GF_TALKIE)) { +		if (_variableArray[141] == 0) +			_variableArray[141] = 9; +		_variableArray[85] = _variableArray[141] * talkDelay; +	} else { +		if (_variableArray[86] == 0) +			talkDelay /= 2; +		if (_variableArray[86] == 2) +			talkDelay *= 2; +		_variableArray[85] = talkDelay * 5; +	} + +	assert(stringLength > 0); + +	while (stringLength > 0) { +		int pos = 0; +		if (stringLength > lettersPerRow) { +			int removeLastWord = 0; +			if (lettersPerRow > lettersPerRowJustified) { +				pos = lettersPerRowJustified; +				while (string[pos] != ' ') +					pos++; +				if (pos > lettersPerRow) +					removeLastWord = 1; +			} +			if (lettersPerRow <= lettersPerRowJustified || removeLastWord) { +				pos = lettersPerRow; +				while (string[pos] != ' ' && pos > 0) +					pos--; +			} +			height += textHeight; +			y -= textHeight; +		} else +			pos = stringLength; +		padding = (lettersPerRow - pos) % 2 ? +			(lettersPerRow - pos) / 2 + 1 : (lettersPerRow - pos) / 2; +		while (padding--) +			*convertedString2++ = ' '; +		stringLength -= pos; +		while (pos--) +			*convertedString2++ = *string++; +		*convertedString2++ = '\n'; +		string++; // skip space +		stringLength--; // skip space +	} +	*(convertedString2 - 1) = '\0'; + +	if (getGameType() == GType_SIMON1) +		stopAnimate(vgaSpriteId + 199); +	else +		stopAnimateSimon2(2, vgaSpriteId); + +	if (getPlatform() == Common::kPlatformAmiga) { +		color = color * 3 + 1; +		renderStringAmiga(vgaSpriteId, color, width, height, convertedString); +	} else { +		color = color * 3 + 192; +		renderString(vgaSpriteId, color, width, height, convertedString); +	} + +	int b = 4; +	if (!getBitFlag(133)) +		b = 3; + +	x /= 8; +	if (y < 2) +		y = 2; + +	if (getGameType() == GType_SIMON1) +		animate(b, 2, vgaSpriteId + 199, x, y, 12); +	else +		animate(b, 2, vgaSpriteId, x, y, 12); +} + +// The Feeble Files specific +void AGOSEngine_Feeble::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) { +	char convertedString[320]; +	char *convertedString2 = convertedString; +	const char *string2 = string; +	int16 height, talkDelay; +	int stringLength = strlen(string); +	int lettersPerRow, lettersPerRowJustified; +	const int textHeight = 15; + +	height = textHeight; +	lettersPerRow = width / 6; +	lettersPerRowJustified = stringLength / (stringLength / lettersPerRow + 1) + 1; + +	talkDelay = (stringLength + 3) / 3; +		if (_variableArray[86] == 0) +			talkDelay /= 2; +		if (_variableArray[86] == 2) +			talkDelay *= 2; +		_variableArray[85] = talkDelay * 5; + +	assert(stringLength > 0); + +	uint16 b, pixels, spaces; + +	while (1) { +		string2 = getPixelLength(string, width, pixels); +		if (*string2 == 0) { +			spaces = (width - pixels) / 12; +			if (spaces != 0) +				spaces--; +			while (spaces) { +	   				*convertedString2++ = ' '; +	   				spaces--; +			} +			strcpy(convertedString2, string); +			break; +		} +		while (*string2 != ' ') { +			byte chr = *string2; +			pixels -= charWidth[chr]; +			string2--; +		} +		spaces = (width - pixels) / 12; +		if (spaces != 0) +			spaces--; +		while (spaces) { +	   			*convertedString2++ = ' '; +	    		spaces--; +		} +		b = string2 - string; +		strncpy(convertedString2, string, b); +		convertedString2 += b; +		*convertedString2++ = '\n'; +		height += textHeight; +		y -= textHeight; +		if (y < 2) +		    y = 2; +		string = string2; +	} + +	stopAnimateSimon2(2, vgaSpriteId); + +	renderString(1, color, width, height, convertedString); + +	animate(4, 2, vgaSpriteId, x, y, 12); +} + +void AGOSEngine_Feeble::printInteractText(uint16 num, const char *string) {  	char convertedString[320];  	char *convertedString2 = convertedString;  	const char *string2 = string; @@ -344,7 +499,7 @@ void AGOSEngine::printInteractText(uint16 num, const char *string) {  	_interactY += height;  } -void AGOSEngine::sendInteractText(uint16 num, const char *fmt, ...) { +void AGOSEngine_Feeble::sendInteractText(uint16 num, const char *fmt, ...) {  	va_list arglist;  	char string[256]; @@ -355,141 +510,7 @@ void AGOSEngine::sendInteractText(uint16 num, const char *fmt, ...) {  	printInteractText(num, string);  } -void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) { -	char convertedString[320]; -	char *convertedString2 = convertedString; -	const char *string2 = string; -	int16 height, talkDelay; -	int stringLength = strlen(string); -	int padding, lettersPerRow, lettersPerRowJustified; -	const int textHeight = (getGameType() == GType_FF) ? 15: 10; - -	height = textHeight; -	lettersPerRow = width / 6; -	lettersPerRowJustified = stringLength / (stringLength / lettersPerRow + 1) + 1; - -	talkDelay = (stringLength + 3) / 3; -	if ((getGameType() == GType_SIMON1) && (getFeatures() & GF_TALKIE)) { -		if (_variableArray[141] == 0) -			_variableArray[141] = 9; -		_variableArray[85] = _variableArray[141] * talkDelay; -	} else { -		if (_variableArray[86] == 0) -			talkDelay /= 2; -		if (_variableArray[86] == 2) -			talkDelay *= 2; -		_variableArray[85] = talkDelay * 5; -	} - -	assert(stringLength > 0); - -	if (getGameType() == GType_FF) { -		uint16 b, pixels, spaces; - -		while (1) { -			string2 = getPixelLength(string, width, pixels); -			if (*string2 == 0) { -				spaces = (width - pixels) / 12; -				if (spaces != 0) -					spaces--; -				while (spaces) { -	    				*convertedString2++ = ' '; -	    				spaces--; -				} -				strcpy(convertedString2, string); -				break; -			} -			while (*string2 != ' ') { -				byte chr = *string2; -				pixels -= charWidth[chr]; -				string2--; -			} -			spaces = (width - pixels) / 12; -			if (spaces != 0) -				spaces--; -			while (spaces) { -	    			*convertedString2++ = ' '; -		    		spaces--; -			} -			b = string2 - string; -			strncpy(convertedString2, string, b); -			convertedString2 += b; -			*convertedString2++ = '\n'; -			height += textHeight; -			y -= textHeight; -			if (y < 2) -			    y = 2; -			string = string2; -		} -	} else { -		while (stringLength > 0) { -			int pos = 0; -			if (stringLength > lettersPerRow) { -				int removeLastWord = 0; -				if (lettersPerRow > lettersPerRowJustified) { -					pos = lettersPerRowJustified; -					while (string[pos] != ' ') -						pos++; -					if (pos > lettersPerRow) -						removeLastWord = 1; -				} -				if (lettersPerRow <= lettersPerRowJustified || removeLastWord) { -					pos = lettersPerRow; -					while (string[pos] != ' ' && pos > 0) -						pos--; -				} -				height += textHeight; -				y -= textHeight; -			} else -				pos = stringLength; -			padding = (lettersPerRow - pos) % 2 ? -				(lettersPerRow - pos) / 2 + 1 : (lettersPerRow - pos) / 2; -			while (padding--) -				*convertedString2++ = ' '; -			stringLength -= pos; -			while (pos--) -				*convertedString2++ = *string++; -			*convertedString2++ = '\n'; -			string++; // skip space -			stringLength--; // skip space -		} -		*(convertedString2 - 1) = '\0'; -	} - -	if (getGameType() == GType_SIMON1) -		stopAnimate(vgaSpriteId + 199); -	else -		stopAnimateSimon2(2, vgaSpriteId); - -	if (getGameType() == GType_FF) { -		renderString(1, color, width, height, convertedString); -	} else { -		if (getPlatform() == Common::kPlatformAmiga) { -			color = color * 3 + 1; -			renderStringAmiga(vgaSpriteId, color, width, height, convertedString); -		} else { -			color = color * 3 + 192; -			renderString(vgaSpriteId, color, width, height, convertedString); -		} -	} - -	int b = 4; -	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { -		if (!getBitFlag(133)) -			b = 3; - -		x /= 8; -		if (y < 2) -			y = 2; -	} - -	if (getGameType() == GType_SIMON1) -		animate(b, 2, vgaSpriteId + 199, x, y, 12); -	else -		animate(b, 2, vgaSpriteId, x, y, 12); -} - -// String code for boxes in Waxworks +// Waxworks specific  uint16 AGOSEngine_Waxworks::getBoxSize() {  	int x;  	switch (_boxLineCount) { @@ -747,39 +768,4 @@ void AGOSEngine_Waxworks::printBox() {  	changeWindow(0);  } -// String code for statistics in Elvira 1/2 -void AGOSEngine::writeChar(WindowBlock *window, int x, int y, int offs, int val) { -	int chr; - -	// Clear background of first digit -	window->textColumnOffset = offs; -	window->text_color = 0; -	windowDrawChar(window, x * 8, y, 129); - -	if (val != -1) { -		// Print first digit -		chr = val / 10 + 48; -		window->text_color = 15; -		windowDrawChar(window, x * 8, y, chr); -	} - -	offs += 6; -	if (offs >= 7) { -		offs -= 8; -		x++; -	} - -	// Clear background of second digit -	window->textColumnOffset = offs; -	window->text_color = 0; -	windowDrawChar(window, x * 8, y, 129); - -	if (val != -1) { -		// Print second digit -		chr = val % 10 + 48; -		window->text_color = 15; -		windowDrawChar(window, x * 8, y, chr); -	} -} -  } // End of namespace AGOS diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp index a876c5402a..17039d1974 100644 --- a/engines/agos/subroutine.cpp +++ b/engines/agos/subroutine.cpp @@ -287,14 +287,6 @@ File *AGOSEngine::openTablesFile_gme(const char *filename) {  }  bool AGOSEngine::loadTablesIntoMem(uint subr_id) { -	if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) -		return loadTablesOldIntoMem(subr_id); -	else -		return loadTablesNewIntoMem(subr_id); -} - - -bool AGOSEngine::loadTablesOldIntoMem(uint subr_id) {  	byte *p;  	uint16 min_num, max_num, file_num;  	File *in; @@ -343,7 +335,7 @@ bool AGOSEngine::loadTablesOldIntoMem(uint subr_id) {  	return 0;  } -bool AGOSEngine::loadTablesNewIntoMem(uint subr_id) { +bool AGOSEngine_Waxworks::loadTablesIntoMem(uint subr_id) {  	byte *p;  	int i;  	uint min_num, max_num; diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp index 768005479e..909ab97c33 100644 --- a/engines/agos/window.cpp +++ b/engines/agos/window.cpp @@ -243,4 +243,38 @@ void AGOSEngine::waitWindow(WindowBlock *window) {  	undefineBox(0x7FFF);  } +void AGOSEngine::writeChar(WindowBlock *window, int x, int y, int offs, int val) { +	int chr; + +	// Clear background of first digit +	window->textColumnOffset = offs; +	window->text_color = 0; +	windowDrawChar(window, x * 8, y, 129); + +	if (val != -1) { +		// Print first digit +		chr = val / 10 + 48; +		window->text_color = 15; +		windowDrawChar(window, x * 8, y, chr); +	} + +	offs += 6; +	if (offs >= 7) { +		offs -= 8; +		x++; +	} + +	// Clear background of second digit +	window->textColumnOffset = offs; +	window->text_color = 0; +	windowDrawChar(window, x * 8, y, 129); + +	if (val != -1) { +		// Print second digit +		chr = val % 10 + 48; +		window->text_color = 15; +		windowDrawChar(window, x * 8, y, chr); +	} +} +  } // End of namespace AGOS  | 
