diff options
93 files changed, 2082 insertions, 1442 deletions
@@ -6,6 +6,7 @@ For a more comprehensive changelog for the latest experimental SVN code, see:     - Added support for a custom SJIS font for FM-TOWNS and PC98 games.   KYRA: +   - Added support for the Amiga version of The Legend of Kyrandia.     - Adapted KYRA to support the custom SJIS font.  1.0.0 (2009-??-??) @@ -769,7 +769,9 @@ site, please see the section on reporting bugs.        original game.    The Legend of Kyrandia: -    - Amiga versions aren't supported +    - No music or sound effects in the Amiga and Macintosh floppy versions. +    - Macintosh CD is using included DOS music and sound effects. +    - PC-9821 version lacks support for sound effects.    Humongous Entertainment games:      - Only the original load and save interface can be used. diff --git a/backends/platform/sdl/graphics.cpp b/backends/platform/sdl/graphics.cpp index efcade834d..3bfe8f5c98 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/platform/sdl/graphics.cpp @@ -563,7 +563,7 @@ bool OSystem_SDL::loadGFXMode() {  	// Create the surface that contains the scaled graphics in 16 bit mode  	// -	if(_videoMode.fullscreen) { +	if (_videoMode.fullscreen) {  		fixupResolutionForAspectRatio(_videoMode.desiredAspectRatio, _videoMode.hardwareWidth, _videoMode.hardwareHeight);  	} diff --git a/backends/platform/symbian/BuildPackageUpload_AllVersions.pl b/backends/platform/symbian/BuildPackageUpload_AllVersions.pl index ba8afe5084..fbfdaeeeef 100644 --- a/backends/platform/symbian/BuildPackageUpload_AllVersions.pl +++ b/backends/platform/symbian/BuildPackageUpload_AllVersions.pl @@ -59,6 +59,7 @@ $ftp_url = "FTP://$FTP_User\@$FTP_Host/$FTP_Dir/";  # these macros are always defined:  $ExtraMacros =  "MACRO		NONSTANDARD_PORT\n"; +$ExtraMacros .=  "MACRO		ENABLE_VKEYBD\n";  $ExtraMacros .= "MACRO		DISABLE_FANCY_THEMES\n";  $ExtraMacros .= "MACRO		DISABLE_SCALERS\n";  $ExtraMacros .= "MACRO		DISABLE_HQ_SCALERS\n"; diff --git a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg index a6f1b03327..fe82cb7b4e 100644 --- a/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg +++ b/backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg @@ -63,6 +63,8 @@  "..\..\..\..\dists\engine-data\igor.tbl"-"c:\data\scummvm\igor.tbl"  "..\..\..\..\dists\engine-data\lure.dat"-"c:\data\scummvm\lure.dat"  "..\..\..\..\dists\engine-data\drascula.dat"-"c:\data\scummvm\drascula.dat" +"..\..\..\..\dists\engine-data\m4.dat"-"c:\data\scummvm\m4.dat" +"..\..\..\vkeybd\packs\vkeybd_default.zip"-"c:\data\scummvm\vkeybd_default.zip"  ; Config/log files: 'empty' will automagically be removed on uninstall  ""-"c:\data\scummvm\scummvm.ini",FILENULL diff --git a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg index 2289cd435e..5a8d317fbc 100644 --- a/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg +++ b/backends/platform/symbian/UIQ3/scummvm-CVS-SymbianUIQ3.pkg @@ -60,7 +60,8 @@  "..\..\..\..\dists\engine-data\igor.tbl"-"c:\shared\scummvm\igor.tbl"  "..\..\..\..\dists\engine-data\lure.dat"-"c:\shared\scummvm\lure.dat"  "..\..\..\..\dists\engine-data\drascula.dat"-"c:\shared\scummvm\drascula.dat" - +"..\..\..\..\dists\engine-data\m4.dat"-"c:\shared\scummvm\m4.dat" +"..\..\..\vkeybd\packs\vkeybd_default.zip"-"c:\shared\scummvm\vkeybd_default.zip"  ; Config/log files: 'empty' will automagically be removed on uninstall  ""-"c:\shared\scummvm\scummvm.ini",FILENULL  ""-"c:\shared\scummvm\scummvm.stdout.txt",FILENULL diff --git a/backends/platform/symbian/mmp/scummvm_base.mmp.in b/backends/platform/symbian/mmp/scummvm_base.mmp.in index 4f6ca6ec8f..57f4fe6008 100644 --- a/backends/platform/symbian/mmp/scummvm_base.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_base.mmp.in @@ -117,4 +117,9 @@ SOURCE     backends\keymapper\action.cpp  SOURCE     backends\keymapper\keymap.cpp  SOURCE     backends\keymapper\keymapper.cpp  SOURCE     backends\keymapper\remap-dialog.cpp - +// Source files for virtual keyboard +SOURCE     backends\vkeybd\image-map.cpp +SOURCE     backends\vkeybd\polygon.cpp +SOURCE     backends\vkeybd\virtual-keyboard-gui.cpp +SOURCE     backends\vkeybd\virtual-keyboard-parser.cpp +SOURCE     backends\vkeybd\virtual-keyboard.cpp diff --git a/backends/platform/symbian/src/SymbianActions.cpp b/backends/platform/symbian/src/SymbianActions.cpp index 995b03f200..5f5551422e 100644 --- a/backends/platform/symbian/src/SymbianActions.cpp +++ b/backends/platform/symbian/src/SymbianActions.cpp @@ -163,7 +163,9 @@ void SymbianActions::initInstanceGame() {  	bool is_drascula = (strncmp(gameid.c_str(), "drascula",8) == 0);  	bool is_tucker = (gameid == "tucker");  	bool is_groovie = (gameid == "groovie"); +	bool is_tinsel = (gameid == "tinsel");  	bool is_cruise = (gameid == "cruise"); +	bool is_made = (gameid == "made");  	Actions::initInstanceGame(); @@ -194,6 +196,8 @@ void SymbianActions::initInstanceGame() {  			_key_action[ACTION_SAVE].setKey(Common::ASCII_ESCAPE, Common::KEYCODE_ESCAPE);  		} else if (is_parallaction) {  			_key_action[ACTION_SAVE].setKey('s', Common::KEYCODE_s); +		} else if (is_tinsel) { +			_key_action[ACTION_SAVE].setKey(Common::ASCII_F1, SDLK_F1);  		} else {  			_key_action[ACTION_SAVE].setKey(Common::ASCII_F5, Common::KEYCODE_F5); // F5 key  		} @@ -202,9 +206,9 @@ void SymbianActions::initInstanceGame() {  	_action_enabled[ACTION_QUIT] = true;  	// Skip text -	if (!is_cine && !is_parallaction && !is_groovie) +	if (!is_cine && !is_parallaction && !is_groovie && !is_cruise && !is_made)  		_action_enabled[ACTION_SKIP_TEXT] = true; -	if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || +	if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || is_tinsel ||  			is_saga || is_kyra || is_touche || is_lure || is_feeble || is_drascula || is_tucker)  		_key_action[ACTION_SKIP_TEXT].setKey(Common::KEYCODE_ESCAPE, Common::KEYCODE_ESCAPE); // Escape key  	else { @@ -70,8 +70,8 @@ add_engine scumm "SCUMM" yes "scumm_7_8 he"  add_engine scumm_7_8 "v7 & v8 games" yes  add_engine he "HE71+ games" yes  add_engine agi "AGI" yes -add_engine agos "AGOS" yes "pn" -add_engine pn "Personal Nightmare" no +add_engine agos "AGOS" yes "agos2" +add_engine agos2 "AGOS 2 games" yes  add_engine cine "Cinematique evo 1" yes  add_engine cruise "Cinematique evo 2" yes  add_engine drascula "Drascula: The Vampire Strikes Back" yes diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex c945b7863b..da57e2ce2a 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat diff --git a/dists/msvc8/ScummVM_Global.vsprops b/dists/msvc8/ScummVM_Global.vsprops index be8e9df17f..dc45440e62 100644 --- a/dists/msvc8/ScummVM_Global.vsprops +++ b/dists/msvc8/ScummVM_Global.vsprops @@ -10,7 +10,7 @@  		Name="VCCLCompilerTool"  		DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996"  		AdditionalIncludeDirectories="../..;../../engines" -		PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE;ENABLE_RGB_COLOR;ENABLE_KEYMAPPER" +		PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE;ENABLE_RGB_COLOR;ENABLE_KEYMAPPER"  		ExceptionHandling="0"  		RuntimeTypeInfo="false"  		WarningLevel="4" diff --git a/dists/msvc8/agos.vcproj b/dists/msvc8/agos.vcproj index 5d6fe215b2..9dab1b3110 100644 --- a/dists/msvc8/agos.vcproj +++ b/dists/msvc8/agos.vcproj @@ -35,6 +35,7 @@  		<File RelativePath="..\..\engines\agos\gfx.cpp" />  		<File RelativePath="..\..\engines\agos\icons.cpp" />  		<File RelativePath="..\..\engines\agos\input.cpp" /> +		<File RelativePath="..\..\engines\agos\input_pn.cpp" />  		<File RelativePath="..\..\engines\agos\intern.h" />  		<File RelativePath="..\..\engines\agos\items.cpp" />  		<File RelativePath="..\..\engines\agos\menus.cpp" /> @@ -60,8 +61,10 @@  		<File RelativePath="..\..\engines\agos\sound.cpp" />  		<File RelativePath="..\..\engines\agos\sound.h" />  		<File RelativePath="..\..\engines\agos\string.cpp" /> +		<File RelativePath="..\..\engines\agos\string_pn.cpp" />  		<File RelativePath="..\..\engines\agos\subroutine.cpp" />  		<File RelativePath="..\..\engines\agos\verb.cpp" /> +		<File RelativePath="..\..\engines\agos\verb_pn.cpp" />  		<File RelativePath="..\..\engines\agos\vga.cpp" />  		<File RelativePath="..\..\engines\agos\vga.h" />  		<File RelativePath="..\..\engines\agos\vga_e2.cpp" /> diff --git a/dists/msvc9/ScummVM_Global.vsprops b/dists/msvc9/ScummVM_Global.vsprops index 7ba00aac7b..afcfab102b 100644 --- a/dists/msvc9/ScummVM_Global.vsprops +++ b/dists/msvc9/ScummVM_Global.vsprops @@ -10,7 +10,7 @@  		Name="VCCLCompilerTool"  		DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996"  		AdditionalIncludeDirectories="../..;../../engines" -		PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE" +		PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_AGOS2;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE"  		ExceptionHandling="0"  		RuntimeTypeInfo="false"  		WarningLevel="4" diff --git a/dists/msvc9/agos.vcproj b/dists/msvc9/agos.vcproj index b352dff3e1..bcd2d98aec 100644 --- a/dists/msvc9/agos.vcproj +++ b/dists/msvc9/agos.vcproj @@ -36,6 +36,7 @@  		<File RelativePath="..\..\engines\agos\gfx.cpp" />  		<File RelativePath="..\..\engines\agos\icons.cpp" />  		<File RelativePath="..\..\engines\agos\input.cpp" /> +		<File RelativePath="..\..\engines\agos\input_pn.cpp" />  		<File RelativePath="..\..\engines\agos\intern.h" />  		<File RelativePath="..\..\engines\agos\items.cpp" />  		<File RelativePath="..\..\engines\agos\menus.cpp" /> @@ -61,8 +62,10 @@  		<File RelativePath="..\..\engines\agos\sound.cpp" />  		<File RelativePath="..\..\engines\agos\sound.h" />  		<File RelativePath="..\..\engines\agos\string.cpp" /> +		<File RelativePath="..\..\engines\agos\string_pn.cpp" />  		<File RelativePath="..\..\engines\agos\subroutine.cpp" />  		<File RelativePath="..\..\engines\agos\verb.cpp" /> +		<File RelativePath="..\..\engines\agos\verb_pn.cpp" />  		<File RelativePath="..\..\engines\agos\vga.cpp" />  		<File RelativePath="..\..\engines\agos\vga.h" />  		<File RelativePath="..\..\engines\agos\vga_e2.cpp" /> diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 0e53698b59..07b5c12247 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -59,6 +59,7 @@ static const GameSpecificSettings puzzlepack_settings = {  	"MUSIC",                               // speech_filename  }; +#ifdef ENABLE_AGOS2  AGOSEngine_PuzzlePack::AGOSEngine_PuzzlePack(OSystem *system)  	: AGOSEngine_Feeble(system) { @@ -72,6 +73,7 @@ AGOSEngine_PuzzlePack::AGOSEngine_PuzzlePack(OSystem *system)  	_startSecondCount = 0;  	_tSecondCount = 0;  } +#endif  AGOSEngine_Simon2::AGOSEngine_Simon2(OSystem *system)  	: AGOSEngine_Simon1(system) { @@ -696,6 +698,7 @@ static const uint16 initialVideoWindows_PN[20] = {  	 3, 2, 14, 129,  }; +#ifdef ENABLE_AGOS2  void AGOSEngine_PuzzlePack::setupGame() {  	gss = &puzzlepack_settings;  	_numVideoOpcodes = 85; @@ -712,6 +715,7 @@ void AGOSEngine_PuzzlePack::setupGame() {  	AGOSEngine::setupGame();  } +#endif  void AGOSEngine_Simon2::setupGame() {  	gss = &simon2_settings; @@ -828,7 +832,6 @@ void AGOSEngine_Elvira1::setupGame() {  	AGOSEngine::setupGame();  } -#ifdef ENABLE_PN  void AGOSEngine_PN::setupGame() {  	gss = &simon1_settings;  	_numVideoOpcodes = 57; @@ -840,7 +843,6 @@ void AGOSEngine_PN::setupGame() {  	AGOSEngine::setupGame();  } -#endif  void AGOSEngine::setupGame() {  	allocItemHeap(); diff --git a/engines/agos/agos.h b/engines/agos/agos.h index ac1f33428b..291ebb71f6 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -34,14 +34,13 @@  #include "common/stack.h"  #include "common/util.h" +#ifdef ENABLE_AGOS2  #include "agos/animation.h" +#endif  #include "agos/midi.h"  #include "agos/sound.h"  #include "agos/vga.h" -// TODO: Replace with more portable code -#include <setjmp.h> -  namespace AGOS {  uint fileReadItemID(Common::SeekableReadStream *in); @@ -892,6 +891,7 @@ public:  	void vc19_loop();  	void vc20_setRepeat();  	void vc21_endRepeat(); +	virtual void vc22_setPalette();  	void vc23_setPriority();  	void vc24_setSpriteXY();  	void vc25_halt_sprite(); @@ -904,7 +904,7 @@ public:  	void vc33_setMouseOn();  	void vc34_setMouseOff();  	void vc35_clearWindow(); -	void vc36_setWindowImage(); +	virtual void vc36_setWindowImage();  	void vc38_ifVarNotZero();  	void vc39_setVar();  	void vc40_scrollRight(); @@ -924,7 +924,6 @@ public:  	// Video Script Opcodes, Elvira 1  	void vc17_waitEnd(); -	void vc22_setPaletteOld();  	void vc32_saveScreen();  	void vc37_pokePalette(); @@ -962,10 +961,9 @@ public:  	void vc45_setSpriteX();  	void vc46_setSpriteY();  	void vc47_addToVar(); -	void vc48_setPathFinder(); +	virtual void vc48_setPathFinder();  	void vc59_ifSpeech();  	void vc61_setMaskImage(); -	void vc22_setPaletteNew();  	// Video Script Opcodes, Simon 2  	void vc56_delayLong(); @@ -1264,7 +1262,6 @@ protected:  	virtual char *genSaveName(int slot);  }; -#ifdef ENABLE_PN  class AGOSEngine_PN : public AGOSEngine {  	virtual Common::Error go(); @@ -1366,9 +1363,6 @@ protected:  	int _tagOfActiveDoline;	///< tag of the active doline "instance"  	int _dolineReturnVal; -	jmp_buf _loadfail; - -  	byte *_dataBase, *_textBase;  	uint32 _dataBaseSize, _textBaseSize; @@ -1515,7 +1509,6 @@ protected:  	const OpcodeEntryPN *_opcodesPN;  }; -#endif  class AGOSEngine_Elvira1 : public AGOSEngine {  public: @@ -1771,6 +1764,8 @@ public:  	virtual void executeOpcode(int opcode); +	virtual void vc22_setPalette(); +  	// Opcodes, Simon 1  	void os1_animate();  	void os1_pauseGame(); @@ -1875,6 +1870,7 @@ protected:  	virtual char *genSaveName(int slot);  }; +#ifdef ENABLE_AGOS2  class AGOSEngine_Feeble : public AGOSEngine_Simon2 {  public:  	AGOSEngine_Feeble(OSystem *system); @@ -1886,6 +1882,9 @@ public:  	virtual void executeOpcode(int opcode); +	virtual void vc36_setWindowImage(); +	virtual void vc48_setPathFinder(); +  	void off_chance();  	void off_jumpOut();  	void off_addTextBox(); @@ -2092,6 +2091,7 @@ protected:  	virtual char *genSaveName(int slot);  }; +#endif  } // End of namespace AGOS diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp index 36399a7b2f..dd52f42abc 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -25,8 +25,11 @@ +#ifdef ENABLE_AGOS2 +  #include "common/endian.h"  #include "common/events.h" +#include "common/file.h"  #include "common/system.h"  #include "graphics/cursorman.h" @@ -541,3 +544,5 @@ MoviePlayer *makeMoviePlayer(AGOSEngine_Feeble *vm, const char *name) {  }  } // End of namespace AGOS + +#endif // ENABLE_AGOS2 diff --git a/engines/agos/animation.h b/engines/agos/animation.h index 4ebcb3d4b3..f0a975f1d4 100644 --- a/engines/agos/animation.h +++ b/engines/agos/animation.h @@ -23,12 +23,11 @@   *   */ +#ifdef ENABLE_AGOS2 +  #ifndef AGOS_ANIMATION_H  #define AGOS_ANIMATION_H -#include "common/file.h" -#include "common/stream.h" -  #include "graphics/video/dxa_decoder.h"  #include "graphics/video/smk_decoder.h"  #include "sound/mixer.h" @@ -115,3 +114,5 @@ MoviePlayer *makeMoviePlayer(AGOSEngine_Feeble *vm, const char *name);  } // End of namespace AGOS  #endif + +#endif // ENABLE_AGOS2 diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp index 5b0a694312..7d93f26f7b 100644 --- a/engines/agos/charset.cpp +++ b/engines/agos/charset.cpp @@ -34,6 +34,7 @@  namespace AGOS { +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::doOutput(const byte *src, uint len) {  	if (_textWindow == NULL)  		return; @@ -64,6 +65,7 @@ void AGOSEngine_Feeble::doOutput(const byte *src, uint len) {  		}  	}  } +#endif  void AGOSEngine::doOutput(const byte *src, uint len) {  	uint idx; @@ -484,13 +486,11 @@ void AGOSEngine::openTextWindow() {  		_textWindow = openWindow(8, 144, 24, 6, 1, 0, 15);  } -#ifdef ENABLE_PN  void AGOSEngine_PN::windowPutChar(WindowBlock *window, byte c, byte b) {  	if (_mousePrintFG || _wiped)  		return;  	AGOSEngine::windowPutChar(window, c, b);  } -#endif  void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) {  	byte width = 6; @@ -573,6 +573,7 @@ void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) {  	}  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) {  	if (_noOracleScroll == 0) {  		if (window->height < window->textRow + 30) { @@ -603,6 +604,7 @@ void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) {  	window->textColumnOffset = 0;  	window->textLength = 0;  } +#endif  void AGOSEngine::windowNewLine(WindowBlock *window) {  	window->textColumn = 0; diff --git a/engines/agos/cursor.cpp b/engines/agos/cursor.cpp index c279fbd335..b741811a68 100644 --- a/engines/agos/cursor.cpp +++ b/engines/agos/cursor.cpp @@ -348,6 +348,7 @@ static const byte _mouseOffs[29 * 32] = {  	0,0,10,7,10,6,10,5,10,4,10,3,10,4,10,5,10,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  }; +#ifdef ENABLE_AGOS2  void AGOSEngine_PuzzlePack::handleMouseMoved() {  	uint x; @@ -379,6 +380,7 @@ void AGOSEngine_PuzzlePack::handleMouseMoved() {  	drawMousePointer();  } +#endif  void AGOSEngine_Simon1::handleMouseMoved() {  	uint x; @@ -474,7 +476,6 @@ get_out:  	_litBoxFlag = 0;  } -#ifdef ENABLE_PN  void AGOSEngine_PN::handleMouseMoved() {  	if (_mouseHideCount) {  		CursorMan.showMouse(false); @@ -539,7 +540,6 @@ void AGOSEngine_PN::handleMouseMoved() {  	_needHitAreaRecalc = 0;  	_litBoxFlag = 0;  } -#endif  void AGOSEngine::handleMouseMoved() {  	uint x; @@ -638,6 +638,7 @@ void AGOSEngine::mouseOn() {  	_videoLockOut &= ~1;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_PuzzlePack::initMouse() {  	if (getGameId() == GID_DIMP) {  		AGOSEngine_Simon1::initMouse(); @@ -652,48 +653,12 @@ void AGOSEngine_FeebleDemo::initMouse() {  	// TODO: Add larger cursor  	AGOSEngine_Simon1::initMouse();  } - -static const byte mouseCursorPalette[] = { -	0x00, 0x00, 0x00, 0x00, // Black -	0xFF, 0xFF, 0xFF, 0x00, // White -}; -  void AGOSEngine_Feeble::initMouse() {  	_maxCursorWidth = 40;  	_maxCursorHeight = 40;  	_mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1);  } -void AGOSEngine_Simon1::initMouse() { -	AGOSEngine::initMouse(); - -	const uint16 *src = _common_mouseInfo; -	for (int i = 0; i < 16; i++) { -		for (int j = 0; j < 16; j++) { -			if (src[0] & (1 << (15 - (j % 16)))) { -				if (src[1] & (1 << (15 - (j % 16)))) { -					_mouseData[16 * i + j] = 1; -				} else { -					_mouseData[16 * i + j] = 0; -				} -			} -		} -		src += 2; -	} - -	CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); -} - -void AGOSEngine::initMouse() { -	_maxCursorWidth = 16; -	_maxCursorHeight = 16; -	_mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1); - -	memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight); - -	CursorMan.replaceCursorPalette(mouseCursorPalette, 0, ARRAYSIZE(mouseCursorPalette) / 4); -} -  void AGOSEngine_PuzzlePack::loadMouseImage() {  	loadZone(_variableArray[500]);  	VgaPointersEntry *vpe = &_vgaBufferPointers[_variableArray[500]]; @@ -793,6 +758,42 @@ void AGOSEngine_Feeble::drawMousePointer() {  		CursorMan.replaceCursor(_mouseData, _maxCursorWidth, _maxCursorHeight, hotspotX, hotspotY, 0);  	}  } +#endif + +void AGOSEngine_Simon1::initMouse() { +	AGOSEngine::initMouse(); + +	const uint16 *src = _common_mouseInfo; +	for (int i = 0; i < 16; i++) { +		for (int j = 0; j < 16; j++) { +			if (src[0] & (1 << (15 - (j % 16)))) { +				if (src[1] & (1 << (15 - (j % 16)))) { +					_mouseData[16 * i + j] = 1; +				} else { +					_mouseData[16 * i + j] = 0; +				} +			} +		} +		src += 2; +	} + +	CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); +} + +static const byte mouseCursorPalette[] = { +	0x00, 0x00, 0x00, 0x00, // Black +	0xFF, 0xFF, 0xFF, 0x00, // White +}; + +void AGOSEngine::initMouse() { +	_maxCursorWidth = 16; +	_maxCursorHeight = 16; +	_mouseData = (byte *)calloc(_maxCursorWidth * _maxCursorHeight, 1); + +	memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight); + +	CursorMan.replaceCursorPalette(mouseCursorPalette, 0, ARRAYSIZE(mouseCursorPalette) / 4); +}  void AGOSEngine::drawMousePointer() {  	if (getGameType() == GType_SIMON2) { diff --git a/engines/agos/debug.cpp b/engines/agos/debug.cpp index 8bdb35d3ae..519dfc344c 100644 --- a/engines/agos/debug.cpp +++ b/engines/agos/debug.cpp @@ -26,6 +26,8 @@  // AGOS debug functions +#include "common/file.h" +  #include "agos/debug.h"  #include "agos/agos.h"  #include "agos/intern.h" @@ -323,6 +325,7 @@ void AGOSEngine::dumpAllVgaScriptFiles() {  	}  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::dumpVgaFile(const byte *vga) {  	const byte *pp;  	const byte *p; @@ -352,6 +355,7 @@ void AGOSEngine_Feeble::dumpVgaFile(const byte *vga) {  		p += sizeof(ImageHeader_Feeble);  	}  } +#endif  void AGOSEngine_Simon1::dumpVgaFile(const byte *vga) {  	const byte *pp; diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp index 7877e19646..6f128a5a1b 100644 --- a/engines/agos/detection.cpp +++ b/engines/agos/detection.cpp @@ -72,11 +72,13 @@ static const PlainGameDescriptor simonGames[] = {  	{"waxworks", "Waxworks"},  	{"simon1", "Simon the Sorcerer 1"},  	{"simon2", "Simon the Sorcerer 2"}, +#ifdef ENABLE_AGOS2  	{"feeble", "The Feeble Files"},  	{"dimp", "Demon in my Pocket"},  	{"jumble", "Jumble"},  	{"puzzle", "NoPatience"},  	{"swampy", "Swampy Adventures"}, +#endif  	{0, 0}  }; @@ -138,11 +140,9 @@ bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame  	bool res = true;  	switch (gd->gameType) { -#ifdef ENABLE_PN  	case AGOS::GType_PN:  		*engine = new AGOS::AGOSEngine_PN(syst);  		break; -#endif  	case AGOS::GType_ELVIRA1:  		*engine = new AGOS::AGOSEngine_Elvira1(syst);  		break; @@ -158,6 +158,7 @@ bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame  	case AGOS::GType_SIMON2:  		*engine = new AGOS::AGOSEngine_Simon2(syst);  		break; +#ifdef ENABLE_AGOS2  	case AGOS::GType_FF:  		if (gd->features & GF_DEMO)  			*engine = new AGOS::AGOSEngine_FeebleDemo(syst); @@ -167,6 +168,7 @@ bool AgosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame  	case AGOS::GType_PP:  		*engine = new AGOS::AGOSEngine_PuzzlePack(syst);  		break; +#endif  	default:  		res = false;  		error("AGOS engine: unknown gameType"); diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h index 533f35d304..678d10f5fa 100644 --- a/engines/agos/detection_tables.h +++ b/engines/agos/detection_tables.h @@ -2335,6 +2335,7 @@ static const AGOSGameDescription gameDescriptions[] = {  		GF_TALKIE  	}, +#ifdef ENABLE_AGOS2  	// The Feeble Files - English DOS Demo  	{  		{ @@ -2807,6 +2808,7 @@ static const AGOSGameDescription gameDescriptions[] = {  		GID_SWAMPY,  		GF_OLD_BUNDLE | GF_TALKIE  	}, +#endif  	{ AD_TABLE_END_MARKER, 0, 0, 0 }  }; diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index 368da5db83..35023885cc 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -46,6 +46,7 @@ byte *AGOSEngine::getScaleBuf() {  	return (byte *)_scaleBuf->pixels;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::animateSpritesByY() {  	VgaSprite *vsp;  	VgaPointersEntry *vpe; @@ -147,6 +148,7 @@ void AGOSEngine_Feeble::animateSprites() {  	_displayScreen = true;  } +#endif  void AGOSEngine::animateSprites() {  	VgaSprite *vsp; diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index cbb09e1ec7..2ba5d56243 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -552,11 +552,13 @@ void AGOSEngine::delay(uint amount) {  	} while (cur < start + amount && !shouldQuit());  } +#ifdef ENABLE_AGOS2  void AGOSEngine_PuzzlePack::timerProc() {  	_lastTickCount = _system->getMillis();  	AGOSEngine_Feeble::timerProc(); -	dimpIdle(); +	if (getGameId() == GID_DIMP) +		dimpIdle();  }  void AGOSEngine_Feeble::timerProc() { @@ -609,8 +611,8 @@ void AGOSEngine_Feeble::timerProc() {  	_videoLockOut &= ~2;  } +#endif -#ifdef ENABLE_PN  void AGOSEngine_PN::timerProc() {  	if (_videoLockOut & 0x80E9 || _videoLockOut & 2)  		return; @@ -649,7 +651,6 @@ void AGOSEngine_PN::timerProc() {  	_videoLockOut &= ~2;  } -#endif  void AGOSEngine::timerProc() {  	if (_videoLockOut & 0x80E9 || _videoLockOut & 2) @@ -677,6 +678,7 @@ void AGOSEngine::timerProc() {  	_videoLockOut &= ~2;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_PuzzlePack::dimpIdle() {  	int z, n; @@ -758,5 +760,6 @@ void AGOSEngine_PuzzlePack::dimpIdle() {  		}  	}  } +#endif  } // End of namespace AGOS diff --git a/engines/agos/feeble.cpp b/engines/agos/feeble.cpp index 89b6f6da27..7dbeacd62f 100644 --- a/engines/agos/feeble.cpp +++ b/engines/agos/feeble.cpp @@ -23,6 +23,10 @@   *   */ + + +#ifdef ENABLE_AGOS2 +  #include "common/config-manager.h"  #include "agos/intern.h" @@ -383,3 +387,5 @@ void AGOSEngine_FeebleDemo::waitForSpace() {  }  } // End of namespace AGOS + +#endif // ENABLE_AGOS2 diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp index 1b5a820260..e2c634007c 100644 --- a/engines/agos/gfx.cpp +++ b/engines/agos/gfx.cpp @@ -226,6 +226,7 @@ bool AGOSEngine::drawImage_clip(VC10_state *state) {  	return (state->draw_width != 0 && state->draw_height != 0);  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {  	Common::Rect srcRect, dstRect;  	float factor, xscale; @@ -461,6 +462,7 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) {  		} while (--state->draw_height);  	}  } +#endif  void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) {  	if (getGameType() == GType_SIMON1 && (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10)) { @@ -1260,7 +1262,6 @@ void AGOSEngine::setImage(uint16 vgaSpriteId, bool vgaScript) {  	_vcPtr = vc_ptr_org;  } -#ifdef ENABLE_PN  void AGOSEngine_PN::setWindowImageEx(uint16 mode, uint16 vga_res) {  	if (!_initMouse) {  		_initMouse = 1; @@ -1268,7 +1269,6 @@ void AGOSEngine_PN::setWindowImageEx(uint16 mode, uint16 vga_res) {  	}  	setWindowImage(mode, vga_res);  } -#endif  void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vgaSpriteId) {  	_window3Flag = 0; diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp index d06e4ec6fc..b28f5ea14f 100644 --- a/engines/agos/icons.cpp +++ b/engines/agos/icons.cpp @@ -374,6 +374,7 @@ void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) {  	_videoLockOut &= ~0x8000;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::drawIconArray(uint num, Item *itemRef, int line, int classMask) {  	Item *item_ptr_org = itemRef;  	WindowBlock *window; @@ -477,6 +478,7 @@ l1:;		itemRef = derefItem(itemRef->next);  	window->iconPtr->upArrow = _scrollUpHitArea;  	window->iconPtr->downArrow = _scrollDownHitArea;  } +#endif  void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) {  	Item *item_ptr_org = itemRef; @@ -581,6 +583,7 @@ void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask)  	}  } +#ifdef ENABLE_AGOS2  uint AGOSEngine_Feeble::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *itemPtr) {  	HitArea *ha = findEmptyHitArea(); @@ -596,6 +599,7 @@ uint AGOSEngine_Feeble::setupIconHitArea(WindowBlock *window, uint num, uint x,  	return ha - _hitAreas;  } +#endif  uint AGOSEngine_Simon2::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *itemPtr) {  	HitArea *ha = findEmptyHitArea(); @@ -683,6 +687,7 @@ uint AGOSEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y,  	return ha - _hitAreas;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::addArrows(WindowBlock *window, uint8 num) {  	HitArea *ha; @@ -712,6 +717,7 @@ void AGOSEngine_Feeble::addArrows(WindowBlock *window, uint8 num) {  	ha->window = window;  	ha->verb = 1;  } +#endif  void AGOSEngine_Simon2::addArrows(WindowBlock *window, uint8 num) {  	HitArea *ha; @@ -1040,7 +1046,6 @@ static const byte hitBarData[12 * 7] = {  	0x3C, 0x89, 0xC3, 0x00, 0x88, 0x88, 0x18, 0x03, 0x86, 0x23, 0x0C, 0x00  }; -#ifdef ENABLE_PN  // Personal Nightmare specific  void AGOSEngine_PN::drawIconHitBar() {  	Graphics::Surface *screen = _system->lockScreen(); @@ -1120,6 +1125,5 @@ void AGOSEngine_PN::printIcon(HitArea *ha, uint8 i, uint8 r) {  		}  	}  } -#endif  } // End of namespace AGOS diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp index 5c37fe620a..35ed045675 100644 --- a/engines/agos/input.cpp +++ b/engines/agos/input.cpp @@ -624,143 +624,4 @@ bool AGOSEngine::processSpecialKeys() {  	return verbCode;  } -#ifdef ENABLE_PN -// Personal Nightmare specific -void AGOSEngine_PN::clearInputLine() { -	_inputting = false; -	_inputReady = false; -	clearWindow(_windowArray[2]); -} - -void AGOSEngine_PN::handleKeyboard() { -	if (!_inputReady) -		return; - -	if (_hitCalled != 0) { -		mouseHit(); -	} - -	int16 chr = -1; -	if (_mouseString) { -		const char *strPtr = _mouseString; -		while (*strPtr != 0 && *strPtr != 13) -			addChar(*strPtr++); -		_mouseString = 0; - -		chr = *strPtr; -		if (chr == 13) { -			addChar(13); -		} -	} -	if (_mouseString1 && chr != 13) { -		const char *strPtr = _mouseString1; -		while (*strPtr != 13) -			addChar(*strPtr++); -		_mouseString1 = 0; - -		chr = *strPtr; -		if (chr == 13) { -			addChar(13); -		} -	} -	if (chr == -1) { -		if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE || _keyPressed.keycode == Common::KEYCODE_RETURN) { -			chr = _keyPressed.keycode; -			addChar(chr); -		} else if (!(_videoLockOut & 0x10)) { -			chr = _keyPressed.ascii; -			if (chr >= 32) -				addChar(chr); -		} -	} - -	if (chr == 13) { -		_mouseString = 0; -		_mouseString1 = 0; -		_mousePrintFG = 0; -		_inputReady = false; -	} - -	_keyPressed.reset(); -} - -void AGOSEngine_PN::interact(char *buffer, uint8 size) { -	if (!_inputting) { -		memset(_keyboardBuffer, 0, sizeof(_keyboardBuffer)); -		_intputCounter = 0; -		_inputMax = size; -		_inputWindow = _windowArray[_curWindow]; -		windowPutChar(_inputWindow, 128); -		windowPutChar(_inputWindow, 8); -		_inputting = true; -		_inputReady = true; -	} - -	while (!shouldQuit() && _inputReady) { -		if (!_noScanFlag && _scanFlag) { -			buffer[0] = 1; -			buffer[1] = 0; -			_scanFlag = 0; -			break; -		} -		delay(1); -	} - -	if (!_inputReady) { -		memcpy(buffer, _keyboardBuffer, size); -		_inputting = false; -	} -} - -void AGOSEngine_PN::addChar(uint8 chr) { -	if (chr == 13) { -		_keyboardBuffer[_intputCounter++] = chr; -		windowPutChar(_inputWindow, 13); -	} else if (chr == 8 && _intputCounter) { -		clearCursor(_inputWindow); -		windowPutChar(_inputWindow, 8); -		windowPutChar(_inputWindow, 128); -		windowPutChar(_inputWindow, 8); - -		_keyboardBuffer[--_intputCounter] = 0; -	} else if (chr >= 32 && _intputCounter < _inputMax) { -		_keyboardBuffer[_intputCounter++] = chr; - -		clearCursor(_inputWindow); -		windowPutChar(_inputWindow, chr); -		windowPutChar(_inputWindow, 128); -		windowPutChar(_inputWindow, 8); -	} -} - -void AGOSEngine_PN::clearCursor(WindowBlock *window) { -	byte oldTextColor = window->textColor; - -	window->textColor = window->fillColor; -	windowPutChar(window, 128); -	window->textColor = oldTextColor; - -	windowPutChar(window, 8); -} - -bool AGOSEngine_PN::processSpecialKeys() { -	if (shouldQuit()) -		_exitCutscene = true; - -	switch (_keyPressed.keycode) { -	case Common::KEYCODE_ESCAPE: -		_exitCutscene = true; -		break; -	case Common::KEYCODE_PAUSE: -		pause(); -		break; -	default: -		break; -	} - -	_keyPressed.reset(); -	return false; -} -#endif -  } // End of namespace AGOS diff --git a/engines/agos/input_pn.cpp b/engines/agos/input_pn.cpp new file mode 100644 index 0000000000..9c35fbb3a2 --- /dev/null +++ b/engines/agos/input_pn.cpp @@ -0,0 +1,169 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + + +#include "agos/agos.h" +#include "agos/intern.h" + +namespace AGOS { + +void AGOSEngine_PN::clearInputLine() { +	_inputting = false; +	_inputReady = false; +	clearWindow(_windowArray[2]); +} + +void AGOSEngine_PN::handleKeyboard() { +	if (!_inputReady) +		return; + +	if (_hitCalled != 0) { +		mouseHit(); +	} + +	int16 chr = -1; +	if (_mouseString) { +		const char *strPtr = _mouseString; +		while (*strPtr != 0 && *strPtr != 13) +			addChar(*strPtr++); +		_mouseString = 0; + +		chr = *strPtr; +		if (chr == 13) { +			addChar(13); +		} +	} +	if (_mouseString1 && chr != 13) { +		const char *strPtr = _mouseString1; +		while (*strPtr != 13) +			addChar(*strPtr++); +		_mouseString1 = 0; + +		chr = *strPtr; +		if (chr == 13) { +			addChar(13); +		} +	} +	if (chr == -1) { +		if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE || _keyPressed.keycode == Common::KEYCODE_RETURN) { +			chr = _keyPressed.keycode; +			addChar(chr); +		} else if (!(_videoLockOut & 0x10)) { +			chr = _keyPressed.ascii; +			if (chr >= 32) +				addChar(chr); +		} +	} + +	if (chr == 13) { +		_mouseString = 0; +		_mouseString1 = 0; +		_mousePrintFG = 0; +		_inputReady = false; +	} + +	_keyPressed.reset(); +} + +void AGOSEngine_PN::interact(char *buffer, uint8 size) { +	if (!_inputting) { +		memset(_keyboardBuffer, 0, sizeof(_keyboardBuffer)); +		_intputCounter = 0; +		_inputMax = size; +		_inputWindow = _windowArray[_curWindow]; +		windowPutChar(_inputWindow, 128); +		windowPutChar(_inputWindow, 8); +		_inputting = true; +		_inputReady = true; +	} + +	while (!shouldQuit() && _inputReady) { +		if (!_noScanFlag && _scanFlag) { +			buffer[0] = 1; +			buffer[1] = 0; +			_scanFlag = 0; +			break; +		} +		delay(1); +	} + +	if (!_inputReady) { +		memcpy(buffer, _keyboardBuffer, size); +		_inputting = false; +	} +} + +void AGOSEngine_PN::addChar(uint8 chr) { +	if (chr == 13) { +		_keyboardBuffer[_intputCounter++] = chr; +		windowPutChar(_inputWindow, 13); +	} else if (chr == 8 && _intputCounter) { +		clearCursor(_inputWindow); +		windowPutChar(_inputWindow, 8); +		windowPutChar(_inputWindow, 128); +		windowPutChar(_inputWindow, 8); + +		_keyboardBuffer[--_intputCounter] = 0; +	} else if (chr >= 32 && _intputCounter < _inputMax) { +		_keyboardBuffer[_intputCounter++] = chr; + +		clearCursor(_inputWindow); +		windowPutChar(_inputWindow, chr); +		windowPutChar(_inputWindow, 128); +		windowPutChar(_inputWindow, 8); +	} +} + +void AGOSEngine_PN::clearCursor(WindowBlock *window) { +	byte oldTextColor = window->textColor; + +	window->textColor = window->fillColor; +	windowPutChar(window, 128); +	window->textColor = oldTextColor; + +	windowPutChar(window, 8); +} + +bool AGOSEngine_PN::processSpecialKeys() { +	if (shouldQuit()) +		_exitCutscene = true; + +	switch (_keyPressed.keycode) { +	case Common::KEYCODE_ESCAPE: +		_exitCutscene = true; +		break; +	case Common::KEYCODE_PAUSE: +		pause(); +		break; +	default: +		break; +	} + +	_keyPressed.reset(); +	return false; +} + +} // End of namespace AGOS diff --git a/engines/agos/module.mk b/engines/agos/module.mk index a7042fa2ad..e60b85a3ef 100644 --- a/engines/agos/module.mk +++ b/engines/agos/module.mk @@ -2,7 +2,6 @@ MODULE := engines/agos  MODULE_OBJS := \  	agos.o \ -	animation.o \  	charset.o \  	charset-fontdata.o \  	contain.o \ @@ -12,15 +11,14 @@ MODULE_OBJS := \  	detection.o \  	draw.o \  	event.o \ -	feeble.o \  	gfx.o \  	icons.o \  	input.o \ +	input_pn.o \  	items.o \  	menus.o \  	midi.o \  	midiparser_s1d.o \ -	oracle.o \  	pn.o \  	res.o \  	res_ami.o \ @@ -28,28 +26,37 @@ MODULE_OBJS := \  	rooms.o \  	saveload.o \  	script.o \ +	script_pn.o \  	script_e1.o \  	script_e2.o \ -	script_pn.o \  	script_ww.o \  	script_s1.o \  	script_s2.o \ -	script_ff.o \ -	script_pp.o \  	sound.o \  	string.o \ +	string_pn.o \  	subroutine.o \  	verb.o \ +	verb_pn.o \  	vga.o \ -	vga_e2.o \  	vga_pn.o \ +	vga_e2.o \  	vga_ww.o \  	vga_s1.o \  	vga_s2.o \ -	vga_ff.o \  	window.o \  	zones.o +ifdef ENABLE_AGOS2 +MODULE_OBJS += \ +	animation.o \ +	feeble.o \ +	oracle.o \ +	script_ff.o \ +	script_pp.o \ +	vga_ff.o +endif +  # This module can be built as a plugin  ifeq ($(ENABLE_AGOS), DYNAMIC_PLUGIN)  PLUGIN := 1 diff --git a/engines/agos/oracle.cpp b/engines/agos/oracle.cpp index e7192ea2ec..b0ecc679c0 100644 --- a/engines/agos/oracle.cpp +++ b/engines/agos/oracle.cpp @@ -25,6 +25,8 @@ +#ifdef ENABLE_AGOS2 +  #include "common/savefile.h"  #include "common/system.h" @@ -520,3 +522,5 @@ void AGOSEngine_Feeble::windowBackSpace(WindowBlock *window) {  }  } // End of namespace AGOS + +#endif // ENABLE_AGOS2 diff --git a/engines/agos/pn.cpp b/engines/agos/pn.cpp index e8135f56cd..94768f9ffb 100644 --- a/engines/agos/pn.cpp +++ b/engines/agos/pn.cpp @@ -23,8 +23,6 @@   *   */ -#ifdef ENABLE_PN -  #include "common/config-manager.h"  #include "agos/intern.h" @@ -297,5 +295,3 @@ void AGOSEngine_PN::setqptrs() {  }  } // End of namespace AGOS - -#endif diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp index 4278ed11e6..cb48e5e50b 100644 --- a/engines/agos/res.cpp +++ b/engines/agos/res.cpp @@ -39,25 +39,27 @@ using Common::File;  namespace AGOS { +#ifdef ENABLE_AGOS2  uint16 AGOSEngine_Feeble::to16Wrapper(uint value) {  	return TO_LE_16(value);  } -uint16 AGOSEngine::to16Wrapper(uint value) { -	return TO_BE_16(value); -} -  uint16 AGOSEngine_Feeble::readUint16Wrapper(const void *src) {  	return READ_LE_UINT16(src);  } -uint16 AGOSEngine::readUint16Wrapper(const void *src) { -	return READ_BE_UINT16(src); -} -  uint32 AGOSEngine_Feeble::readUint32Wrapper(const void *src) {  	return READ_LE_UINT32(src);  } +#endif + +uint16 AGOSEngine::to16Wrapper(uint value) { +	return TO_BE_16(value); +} + +uint16 AGOSEngine::readUint16Wrapper(const void *src) { +	return READ_BE_UINT16(src); +}  uint32 AGOSEngine::readUint32Wrapper(const void *src) {  	return READ_BE_UINT32(src); @@ -150,7 +152,6 @@ int AGOSEngine::allocGamePcVars(Common::SeekableReadStream *in) {  	return itemArrayInited;  } -#ifdef ENABLE_PN  void AGOSEngine_PN::loadGamePcFile() {  	Common::File in; @@ -190,7 +191,6 @@ void AGOSEngine_PN::loadGamePcFile() {  			error("Unknown compression format");  	}  } -#endif  void AGOSEngine::loadGamePcFile() {  	Common::File in; diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index e3052e7d2f..d5146ae408 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -25,6 +25,8 @@ +#include "common/file.h" +  #include "agos/agos.h"  #include "agos/intern.h" diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index 77b503b2e3..8a54151f91 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -23,6 +23,7 @@   *   */ +#include "common/file.h"  #include "common/savefile.h"  #include "common/system.h" @@ -72,6 +73,7 @@ int AGOSEngine::countSaveGames() {  	return i;  } +#ifdef ENABLE_AGOS2  char *AGOSEngine_PuzzlePack::genSaveName(int slot) {  	static char buf[20]; @@ -88,6 +90,7 @@ char *AGOSEngine_Feeble::genSaveName(int slot) {  	sprintf(buf, "feeble.%.3d", slot);  	return buf;  } +#endif  char *AGOSEngine_Simon2::genSaveName(int slot) {  	static char buf[20]; @@ -1548,7 +1551,6 @@ bool AGOSEngine_Elvira2::saveGame(uint slot, const char *caption) {  	return result;  } -#ifdef ENABLE_PN  // Personal Nightmare specific  bool AGOSEngine_PN::badload(int8 errorNum) {  	if (errorNum == -2) @@ -1672,6 +1674,5 @@ void AGOSEngine_PN::dbtosysf() {  		ct++;  	}  } -#endif  } // End of namespace AGOS diff --git a/engines/agos/script_ff.cpp b/engines/agos/script_ff.cpp index f20086b268..c1cc8ca9a0 100644 --- a/engines/agos/script_ff.cpp +++ b/engines/agos/script_ff.cpp @@ -25,6 +25,8 @@ +#ifdef ENABLE_AGOS2 +  #include "common/system.h"  #include "agos/animation.h" @@ -675,3 +677,5 @@ void AGOSEngine_Feeble::off_b3NotZero() {  }  } // End of namespace AGOS + +#endif // ENABLE_AGOS2 diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp index 2885781a9f..f4b2aefcc6 100644 --- a/engines/agos/script_pn.cpp +++ b/engines/agos/script_pn.cpp @@ -23,8 +23,6 @@   *   */ -#ifdef ENABLE_PN -  #include "agos/agos.h"  #include "agos/vga.h" @@ -1119,5 +1117,3 @@ void AGOSEngine_PN::popstack(int type) {  }  } // End of namespace AGOS - -#endif diff --git a/engines/agos/script_pp.cpp b/engines/agos/script_pp.cpp index 7c83165274..3fbfd43afd 100644 --- a/engines/agos/script_pp.cpp +++ b/engines/agos/script_pp.cpp @@ -25,6 +25,8 @@ +#ifdef ENABLE_AGOS2 +  #include "common/system.h"  #include "agos/agos.h" @@ -457,3 +459,5 @@ void AGOSEngine_PuzzlePack::opp_restartClock() {  }  } // End of namespace AGOS + +#endif // ENABLE_AGOS2 diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp index 3773b1fa10..1d8bb0b976 100644 --- a/engines/agos/string.cpp +++ b/engines/agos/string.cpp @@ -25,6 +25,8 @@ +#include "common/file.h" +  #include "agos/agos.h"  #include "agos/intern.h" @@ -560,6 +562,7 @@ void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *strin  	}  } +#ifdef ENABLE_AGOS2  // The Feeble Files specific  void AGOSEngine_Feeble::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) {  	char convertedString[320]; @@ -693,6 +696,7 @@ void AGOSEngine_Feeble::sendInteractText(uint16 num, const char *fmt, ...) {  	printInteractText(num, string);  } +#endif  // Waxworks specific  uint16 AGOSEngine_Waxworks::getBoxSize() { @@ -951,648 +955,4 @@ void AGOSEngine_Waxworks::printBox() {  	changeWindow(0);  } -#ifdef ENABLE_PN -// Personal Nightmare specific -uint32 AGOSEngine_PN::ftext(uint32 base, int n) { -	uint32 b = base; -	int ct = n; -	while (ct) { -		while(_textBase[b++]) -			; -		ct--; -	} -	return b; -} - -char *AGOSEngine_PN::unctok(char *c, int n) { -	int x; -	uint8 *tokbase; -	tokbase = _textBase + getlong(30); -	x = n; -	while (x-=(*tokbase++ > 127)) -		; -	while (*tokbase < 128) -		*c++=*tokbase++; -	*c++ = *tokbase & 127; -	*c = 0; -	return c; -} - -void AGOSEngine_PN::uncomstr(char *c, uint32 x) { -	if (x > _textBaseSize) -		error("UNCOMSTR: TBASE over-run"); -	while (_textBase[x]) { -		if (_textBase[x] < 244) { -			c = unctok(c, _textBase[x]); -		} else { -			c = unctok(c, (_textBase[x] - 244) * 254 + _textBase[x + 1] - 1); -			x++; -		} -		x++; -	} -	*c++ = 13; -	*c = 0; -} - -static const char *objectNames[30] = { -	"\0", -	"Take \0", -	"Inventory\r", -	"Open \0", -	"Close \0", -	"Lock \0", -	"Unlock \0", -	"Examine \0", -	"Look in \0", -	"Exits \r", -	"Look\r", -	"Wait\r", -	"Pause\r", -	"\0", -	"Save\r", -	"Restore\r", -	"\0", -	"N\r", -	"NE\r", -	"E\r", -	"SE\r", -	"S\r", -	"SW\r", -	"W\r", -	"NW\r", -	"INVENTORY\r", -	"ROOM DESCRIPTION\r", -	"x\r", -	"MORE\r", -	"CLOSE\r" -}; - -void AGOSEngine_PN::getObjectName(char *v, uint16 x) { -	if (x & 0x8000) { -		x &= ~0x8000; -		if (x > getptr(51)) -			error("getObjectName: Object %d out of range", x); -		uncomstr(v, ftext(getlong(27), x * _dataBase[47])); -	} else { -		assert(x < 30); -		strcpy(v, objectNames[x]); -	} -} - -void AGOSEngine_PN::pcl(const char *s) { -	strcat(_sb, s); -	if (strchr(s, '\n') == 0) { -		for (char *str = _sb; *str; str++) -			windowPutChar(_windowArray[_curWindow], *str); -		strcpy(_sb, ""); -	} -} - -void AGOSEngine_PN::pcf(uint8 ch) { -	int ct = 0; -	if (ch == '[') -		ch = '\n'; -	if (ch == 0) -		return;	/* Trap any C EOS chrs */ -	if (ch == 255) { -		_bp = 0; -		_xofs = 0; -		return;		/* pcf(255) initialises the routine */ -	}			/* pcf(254) flushes its working _buffer */ -	if (ch != 254) { -		if ((ch != 32) || (_bp + _xofs != 50)) -			_buffer[_bp++] = ch; -	} -	if ((ch != 254) && (!isspace(ch)) && (_bp < 60)) -		return; -	/* We know have a case of needing to print the text */ -	if (_bp + _xofs > 50) { -		pcl("\n"); -		if (_buffer[0] == ' ') -			ct = 1;	/* Skip initial space */ -		/* Note '  ' will give a single start of line space */ -		_xofs = 0; -	} -	_buffer[_bp] = 0; -	pcl(_buffer + ct); -	_xofs += _bp; -	_bp = 0; -	if (ch == '\n') -		_xofs = 0;	/* At Newline! */ -} - -void AGOSEngine_PN::patok(int n) { -	int x; -	uint8 *tokbase; -	tokbase = _textBase + getlong(30); -	x = n; -	while (x -= (*tokbase++ > 127)) -		; -	while (*tokbase < 128) -		pcf(*tokbase++); -	pcf((uint8)(*tokbase & 127)); -} - -void AGOSEngine_PN::pmesd(int n) { -	ptext(ftext(getlong(24), n)); -} - -void AGOSEngine_PN::plocd(int n, int m) { -	if (n > getptr(53)) -		error("Location out of range"); -	ptext(ftext(getlong(21), n * _dataBase[48] + m)); -} - -void AGOSEngine_PN::pobjd(int n, int m) { -	if (n > getptr(51)) -		error("Object out of range"); -	ptext(ftext(getlong(27), n * _dataBase[47] + m)); -} - -void AGOSEngine_PN::ptext(uint32 tptr) { -	if (tptr > _textBaseSize) -		error("ptext: attempt to print beyond end of TBASE"); - -	while (_textBase[tptr]) { -		if (_textBase[tptr] < 244) { -			patok(_textBase[tptr++]); -		} else { -			patok((_textBase[tptr] - 244) * 254 + _textBase[tptr + 1] - 1); -			tptr += 2; -		} -	} -} - -const uint8 characters[11][80] = { -// PETERMASON -	{ -		118, 225, -		 91, 118, -		 94, 124, -		236, 161, -		241, 166, -		168,   4, -		138,  46, -		139,  46, -		249,  50, -		 38,  56, -		 80,  59, -		149,  69, -		 37,  77, -		 93,  93, -		 86,  95, -		  0, -		  0, -		 58, 130, -		 62, 178, -		 83,  95, -		  0, -		121,  58, -		122,  59, -		126,  60, -		124,  61, -		240,  62, -		123,  63, -		0 -	}, -// JBLANDFORD -	{ -		0, -		0, -		0, -		0 -	}, -// SBLANDFORD -	{ -		120, 223, -		 94, 126, -		112, 134, -		 45, 152, -		241, 166, -		168,   3, -		150,  26, -		220,  29, -		138,  42, -		139,  47, -		249,  50, -		 38,  56, -		230,  64, -		 37,  77, -		 93,  94, -		 86,  96, -		  0, -		  0, -		 58, 129, -		 59, 112, -		 83,  96, -		 81, 106, -		 62, 169, -		  0, -		121,  54, -		122,  55, -		119,  56, -		118,  57, -		  0 -	}, -// MRJONES -	{ -		121, 218, -		 91, 118, -		253, 121, -		154, 138, -		235, 173, -		236, 161, -		241, 165, -		168,   0, -		150,  21, -		 36,  33, -		138,  42, -		249,  50, -		 80,  60, -		  4,  60, -		 37,  78, -		 68,  33, -		 93,  92, -		101, 109, -		  0, -		 36,  35, -		 68,  90, -		  0, -		 58, 128, -		 59, 111, -		 62, 182, -		  0, -		122,  13, -		126,  14, -		124,  15, -		240,  16, -		120,  17, -		119,  18, -		118,  19, -		 52,  20, -		125,  21, -		127,  22, -		123,  23, -		117,  24, -		  0 -	}, -// MRSJONES -	{ -		122, 219, -		 91, 119, -		253, 123, -		112, 136, -		154, 137, -		 95, 142, -		 45, 152, -		109, 155, -		235, 160, -		168,   1, -		151,  13, -		145,  15, -		150,  22, -		220,  28, -		 36,  33, -		138,  43, -		 13,  51, -		 80,  59, -		230,  64, -		149,  69, -		 86, 100, -		  0, -		 36,  36, -		  0, -		 58, 127, -		 62, 179, -		 83, 100, -		 81, 102, -		  0, -		121,  25, -		126,  26, -		124,  27, -		120,  28, -		119,  29, -		118,  30, -		 52,  31, -		125,  32, -		127,  33, -		123,  34, -		117,  35, -		0 -	}, -// MRROBERTS -	{ -		123, 229, -		 91, 117, -		253, 120, -		 94, 125, -		112, 134, -		109, 156, -		235, 172, -		236, 162, -		241, 165, -		168,   3, -		 36,  33, -		249,  50, -		 38,  56, -		 80,  58, -		 37,  75, -		 34,  81, -		 68,  33, -		101, 109, -		  0, -		 36,  40, -		 68,  88, -		  0, -		 59, 111, -		 62, 181, -		  0, -		  0 -	}, -// POSTMISTRESS -	{ -		124, 221, -		 91, 119, -		253, 122, -		112, 136, -		 95, 142, -		130, 149, -		109, 155, -		235, 176, -		220,  29, -		 36,  33, -		138,  43, -		 13,  51, -		 80,  57, -		149,  68, -		 37,  73, -		 34,  33, -		 68,  33, -		 86, 100, -		  0, -		 36,  39, -		 34,  80, -		 68,  86, -		  0, -		 58, 130, -		 62, 181, -		 83, 100, -		 81, 103, -		  0, -		121,  41, -		122,  42, -		126,  43, -		240,  44, -		120,  45, -		119,  46, -		118,  47, -		 52,  48, -		123,  49, -		 83,  50, -		117,  51, -		  0 -	}, -// MWILLIAMS -	{ -		125, 227, -		 94, 124, -		 95, 141, -		241, 166, -		168,   4, -		150,  26, -		 38,  54, -		  4,  60, -		230,  65, -		149,  68, -		 37,  76, -		101, 109, -		  0, -		230,  63, -		  0, -		 59, 112, -		 62, 183, -		  0, -		240,  71, -		120,  72, -		118,  73, -		 52,  74, -		117,  75, -		  0 -	}, -// TONY -	{ -		126, 220, -		 95, 143, -		130, 149, -		 45, 153, -		109, 154, -		235, 158, -		241, 166, -		168,   2, -		145,  15, -		150,  24, -		220,  20, -		 36,  20, -		  4,  60, -		 37,  79, -		 86,  97, -		  0, -		150,  23, -		220,  27, -		 36,  34, -		  0, -		 83,  97, -		  0, -		121,  36, -		122,  37, -		124,  38, -		240,  39, -		 52,  40, -		  0 -	}, -// PIG -	{ -		127, 228, -		112, 133, -		 45, 153, -		235, 157, -		236, 163, -		241, 165, -		 36,  33, -		 80,  58, -		 34,  81, -		 68,  33, -		 86,  98, -		  0, -		 36,  37, -		 68,  90, -		  0, -		 62, 184, -		 83,  98, -		  0, -		121,  76, -		122,  77, -		126,  78, -		124,  79, -		240,  80, -		120,  81, -		118,  82, -		 52,  83, -		125,  84, -		123,  85, -		 83,  86, -		117,  87, -		  0 -	}, -// JUDY -	{ -			  0, -			  0, -			  0, -			240, 52, -			117, 53, -			  0 -	} -}; - -void AGOSEngine_PN::getResponse(uint16 charNum, uint16 objNum, uint16 &msgNum1, uint16 &msgNum2) { -	const uint8 *ptr; -	uint16 num; - -	msgNum1 = 0; -	msgNum2 = 0; - -	if (charNum == 83) -		charNum += 45; - -	if (charNum < 118 || charNum > 128) { -		return; -	} - -	ptr = characters[charNum - 118]; - -	while ((num = *ptr++) != 0) { -		if (num == objNum) { -			msgNum1 = *ptr++; -			msgNum1 += 400; - -			while ((num = *ptr++) != 0) -				ptr++; -			break; -		} -		ptr++; -	} - -	while ((num = *ptr++) != 0) { -		if (num == objNum) { -			msgNum2 = *ptr++; -			msgNum2 += 400; - -			if (msgNum1 == 569) -				msgNum1 += 400; -			if (msgNum2 == 0) -				msgNum2 = msgNum1; -			return; -		} -		ptr++; -	} - -	if (objNum >= 200) -		msgNum1 = 0; - -	objNum -= 200; -	while ((num = *ptr++) != 0) { -		if (num == objNum) { -			msgNum1 = *ptr++; -			msgNum1 += 400; - -			if (msgNum1 == 569) -				msgNum1 += 400; -			if (msgNum2 == 0) -				msgNum2 = msgNum1; -			return; -		} -		ptr++; -	} - -	objNum += 200; -	while ((num = *ptr++) != 0) { -		if (num == objNum) { -			msgNum1 = *ptr++; -			msgNum1 += 200; - -			if (msgNum1 == 569) -				msgNum1 += 400; -			if (msgNum2 == 0) -				msgNum2 = msgNum1; -			return; -		} -		ptr++; -	} - -	if (msgNum1 == 569) -		msgNum1 += 400; -	if (msgNum2 == 0) -		msgNum2 = msgNum1; -} - -char *AGOSEngine_PN::getMessage(char *msg, uint16 num) { -	char *origPtr, *strPtr1 = msg; -	uint8 count; - -	getObjectName(strPtr1, num); -	if (!(num & 0x8000)) { -		return msg; -	} - -	if (strPtr1[0] == 0x41 || strPtr1[0] == 0x61) { -		if (strPtr1[1] != 0x20) -			strPtr1 += 2; -	} else if (strPtr1[0] == 0x54 || strPtr1[0] == 0x74) { -		if (strPtr1[1] == 0x68 && -		    strPtr1[2] == 0x65 && -		    strPtr1[3] == 0x20) -			strPtr1 += 4; -	} - -	origPtr = strPtr1; -	while (*strPtr1 != 13) -		strPtr1++; - -	strPtr1[0] = 32; -	strPtr1[1] = 13; -	strPtr1[2] = 0; - -	if (_videoLockOut & 0x10) { -		strPtr1 = origPtr; -		count = 6; -		while (*strPtr1) { -			if (*strPtr1 == 32) { -				count = 6; -			} else { -				count--; -				if (count == 0) { -					char *tmpPtr = strPtr1; -					char *strPtr2 = strPtr1; - -					while (*strPtr2 != 0 && *strPtr2 != 32) -						strPtr2++; - -					while (*strPtr2) { -						*strPtr1++ = *strPtr2++; -					} -					*strPtr1++ = *strPtr2++; - -					strPtr1 = tmpPtr; -					count = 6; -				} -			} -			strPtr1++; -		} -	} - -	return origPtr; -} -#endif -  } // End of namespace AGOS diff --git a/engines/agos/string_pn.cpp b/engines/agos/string_pn.cpp new file mode 100644 index 0000000000..0872e9d589 --- /dev/null +++ b/engines/agos/string_pn.cpp @@ -0,0 +1,674 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + + +#include "agos/agos.h" +#include "agos/intern.h" + +namespace AGOS { + +uint32 AGOSEngine_PN::ftext(uint32 base, int n) { +	uint32 b = base; +	int ct = n; +	while (ct) { +		while(_textBase[b++]) +			; +		ct--; +	} +	return b; +} + +char *AGOSEngine_PN::unctok(char *c, int n) { +	int x; +	uint8 *tokbase; +	tokbase = _textBase + getlong(30); +	x = n; +	while (x-=(*tokbase++ > 127)) +		; +	while (*tokbase < 128) +		*c++=*tokbase++; +	*c++ = *tokbase & 127; +	*c = 0; +	return c; +} + +void AGOSEngine_PN::uncomstr(char *c, uint32 x) { +	if (x > _textBaseSize) +		error("UNCOMSTR: TBASE over-run"); +	while (_textBase[x]) { +		if (_textBase[x] < 244) { +			c = unctok(c, _textBase[x]); +		} else { +			c = unctok(c, (_textBase[x] - 244) * 254 + _textBase[x + 1] - 1); +			x++; +		} +		x++; +	} +	*c++ = 13; +	*c = 0; +} + +static const char *objectNames[30] = { +	"\0", +	"Take \0", +	"Inventory\r", +	"Open \0", +	"Close \0", +	"Lock \0", +	"Unlock \0", +	"Examine \0", +	"Look in \0", +	"Exits \r", +	"Look\r", +	"Wait\r", +	"Pause\r", +	"\0", +	"Save\r", +	"Restore\r", +	"\0", +	"N\r", +	"NE\r", +	"E\r", +	"SE\r", +	"S\r", +	"SW\r", +	"W\r", +	"NW\r", +	"INVENTORY\r", +	"ROOM DESCRIPTION\r", +	"x\r", +	"MORE\r", +	"CLOSE\r" +}; + +void AGOSEngine_PN::getObjectName(char *v, uint16 x) { +	if (x & 0x8000) { +		x &= ~0x8000; +		if (x > getptr(51)) +			error("getObjectName: Object %d out of range", x); +		uncomstr(v, ftext(getlong(27), x * _dataBase[47])); +	} else { +		assert(x < 30); +		strcpy(v, objectNames[x]); +	} +} + +void AGOSEngine_PN::pcl(const char *s) { +	strcat(_sb, s); +	if (strchr(s, '\n') == 0) { +		for (char *str = _sb; *str; str++) +			windowPutChar(_windowArray[_curWindow], *str); +		strcpy(_sb, ""); +	} +} + +void AGOSEngine_PN::pcf(uint8 ch) { +	int ct = 0; +	if (ch == '[') +		ch = '\n'; +	if (ch == 0) +		return;	/* Trap any C EOS chrs */ +	if (ch == 255) { +		_bp = 0; +		_xofs = 0; +		return;		/* pcf(255) initialises the routine */ +	}			/* pcf(254) flushes its working _buffer */ +	if (ch != 254) { +		if ((ch != 32) || (_bp + _xofs != 50)) +			_buffer[_bp++] = ch; +	} +	if ((ch != 254) && (!isspace(ch)) && (_bp < 60)) +		return; +	/* We know have a case of needing to print the text */ +	if (_bp + _xofs > 50) { +		pcl("\n"); +		if (_buffer[0] == ' ') +			ct = 1;	/* Skip initial space */ +		/* Note '  ' will give a single start of line space */ +		_xofs = 0; +	} +	_buffer[_bp] = 0; +	pcl(_buffer + ct); +	_xofs += _bp; +	_bp = 0; +	if (ch == '\n') +		_xofs = 0;	/* At Newline! */ +} + +void AGOSEngine_PN::patok(int n) { +	int x; +	uint8 *tokbase; +	tokbase = _textBase + getlong(30); +	x = n; +	while (x -= (*tokbase++ > 127)) +		; +	while (*tokbase < 128) +		pcf(*tokbase++); +	pcf((uint8)(*tokbase & 127)); +} + +void AGOSEngine_PN::pmesd(int n) { +	ptext(ftext(getlong(24), n)); +} + +void AGOSEngine_PN::plocd(int n, int m) { +	if (n > getptr(53)) +		error("Location out of range"); +	ptext(ftext(getlong(21), n * _dataBase[48] + m)); +} + +void AGOSEngine_PN::pobjd(int n, int m) { +	if (n > getptr(51)) +		error("Object out of range"); +	ptext(ftext(getlong(27), n * _dataBase[47] + m)); +} + +void AGOSEngine_PN::ptext(uint32 tptr) { +	if (tptr > _textBaseSize) +		error("ptext: attempt to print beyond end of TBASE"); + +	while (_textBase[tptr]) { +		if (_textBase[tptr] < 244) { +			patok(_textBase[tptr++]); +		} else { +			patok((_textBase[tptr] - 244) * 254 + _textBase[tptr + 1] - 1); +			tptr += 2; +		} +	} +} + +const uint8 characters[11][80] = { +// PETERMASON +	{ +		118, 225, +		 91, 118, +		 94, 124, +		236, 161, +		241, 166, +		168,   4, +		138,  46, +		139,  46, +		249,  50, +		 38,  56, +		 80,  59, +		149,  69, +		 37,  77, +		 93,  93, +		 86,  95, +		  0, +		  0, +		 58, 130, +		 62, 178, +		 83,  95, +		  0, +		121,  58, +		122,  59, +		126,  60, +		124,  61, +		240,  62, +		123,  63, +		0 +	}, +// JBLANDFORD +	{ +		0, +		0, +		0, +		0 +	}, +// SBLANDFORD +	{ +		120, 223, +		 94, 126, +		112, 134, +		 45, 152, +		241, 166, +		168,   3, +		150,  26, +		220,  29, +		138,  42, +		139,  47, +		249,  50, +		 38,  56, +		230,  64, +		 37,  77, +		 93,  94, +		 86,  96, +		  0, +		  0, +		 58, 129, +		 59, 112, +		 83,  96, +		 81, 106, +		 62, 169, +		  0, +		121,  54, +		122,  55, +		119,  56, +		118,  57, +		  0 +	}, +// MRJONES +	{ +		121, 218, +		 91, 118, +		253, 121, +		154, 138, +		235, 173, +		236, 161, +		241, 165, +		168,   0, +		150,  21, +		 36,  33, +		138,  42, +		249,  50, +		 80,  60, +		  4,  60, +		 37,  78, +		 68,  33, +		 93,  92, +		101, 109, +		  0, +		 36,  35, +		 68,  90, +		  0, +		 58, 128, +		 59, 111, +		 62, 182, +		  0, +		122,  13, +		126,  14, +		124,  15, +		240,  16, +		120,  17, +		119,  18, +		118,  19, +		 52,  20, +		125,  21, +		127,  22, +		123,  23, +		117,  24, +		  0 +	}, +// MRSJONES +	{ +		122, 219, +		 91, 119, +		253, 123, +		112, 136, +		154, 137, +		 95, 142, +		 45, 152, +		109, 155, +		235, 160, +		168,   1, +		151,  13, +		145,  15, +		150,  22, +		220,  28, +		 36,  33, +		138,  43, +		 13,  51, +		 80,  59, +		230,  64, +		149,  69, +		 86, 100, +		  0, +		 36,  36, +		  0, +		 58, 127, +		 62, 179, +		 83, 100, +		 81, 102, +		  0, +		121,  25, +		126,  26, +		124,  27, +		120,  28, +		119,  29, +		118,  30, +		 52,  31, +		125,  32, +		127,  33, +		123,  34, +		117,  35, +		0 +	}, +// MRROBERTS +	{ +		123, 229, +		 91, 117, +		253, 120, +		 94, 125, +		112, 134, +		109, 156, +		235, 172, +		236, 162, +		241, 165, +		168,   3, +		 36,  33, +		249,  50, +		 38,  56, +		 80,  58, +		 37,  75, +		 34,  81, +		 68,  33, +		101, 109, +		  0, +		 36,  40, +		 68,  88, +		  0, +		 59, 111, +		 62, 181, +		  0, +		  0 +	}, +// POSTMISTRESS +	{ +		124, 221, +		 91, 119, +		253, 122, +		112, 136, +		 95, 142, +		130, 149, +		109, 155, +		235, 176, +		220,  29, +		 36,  33, +		138,  43, +		 13,  51, +		 80,  57, +		149,  68, +		 37,  73, +		 34,  33, +		 68,  33, +		 86, 100, +		  0, +		 36,  39, +		 34,  80, +		 68,  86, +		  0, +		 58, 130, +		 62, 181, +		 83, 100, +		 81, 103, +		  0, +		121,  41, +		122,  42, +		126,  43, +		240,  44, +		120,  45, +		119,  46, +		118,  47, +		 52,  48, +		123,  49, +		 83,  50, +		117,  51, +		  0 +	}, +// MWILLIAMS +	{ +		125, 227, +		 94, 124, +		 95, 141, +		241, 166, +		168,   4, +		150,  26, +		 38,  54, +		  4,  60, +		230,  65, +		149,  68, +		 37,  76, +		101, 109, +		  0, +		230,  63, +		  0, +		 59, 112, +		 62, 183, +		  0, +		240,  71, +		120,  72, +		118,  73, +		 52,  74, +		117,  75, +		  0 +	}, +// TONY +	{ +		126, 220, +		 95, 143, +		130, 149, +		 45, 153, +		109, 154, +		235, 158, +		241, 166, +		168,   2, +		145,  15, +		150,  24, +		220,  20, +		 36,  20, +		  4,  60, +		 37,  79, +		 86,  97, +		  0, +		150,  23, +		220,  27, +		 36,  34, +		  0, +		 83,  97, +		  0, +		121,  36, +		122,  37, +		124,  38, +		240,  39, +		 52,  40, +		  0 +	}, +// PIG +	{ +		127, 228, +		112, 133, +		 45, 153, +		235, 157, +		236, 163, +		241, 165, +		 36,  33, +		 80,  58, +		 34,  81, +		 68,  33, +		 86,  98, +		  0, +		 36,  37, +		 68,  90, +		  0, +		 62, 184, +		 83,  98, +		  0, +		121,  76, +		122,  77, +		126,  78, +		124,  79, +		240,  80, +		120,  81, +		118,  82, +		 52,  83, +		125,  84, +		123,  85, +		 83,  86, +		117,  87, +		  0 +	}, +// JUDY +	{ +			  0, +			  0, +			  0, +			240, 52, +			117, 53, +			  0 +	} +}; + +void AGOSEngine_PN::getResponse(uint16 charNum, uint16 objNum, uint16 &msgNum1, uint16 &msgNum2) { +	const uint8 *ptr; +	uint16 num; + +	msgNum1 = 0; +	msgNum2 = 0; + +	if (charNum == 83) +		charNum += 45; + +	if (charNum < 118 || charNum > 128) { +		return; +	} + +	ptr = characters[charNum - 118]; + +	while ((num = *ptr++) != 0) { +		if (num == objNum) { +			msgNum1 = *ptr++; +			msgNum1 += 400; + +			while ((num = *ptr++) != 0) +				ptr++; +			break; +		} +		ptr++; +	} + +	while ((num = *ptr++) != 0) { +		if (num == objNum) { +			msgNum2 = *ptr++; +			msgNum2 += 400; + +			if (msgNum1 == 569) +				msgNum1 += 400; +			if (msgNum2 == 0) +				msgNum2 = msgNum1; +			return; +		} +		ptr++; +	} + +	if (objNum >= 200) +		msgNum1 = 0; + +	objNum -= 200; +	while ((num = *ptr++) != 0) { +		if (num == objNum) { +			msgNum1 = *ptr++; +			msgNum1 += 400; + +			if (msgNum1 == 569) +				msgNum1 += 400; +			if (msgNum2 == 0) +				msgNum2 = msgNum1; +			return; +		} +		ptr++; +	} + +	objNum += 200; +	while ((num = *ptr++) != 0) { +		if (num == objNum) { +			msgNum1 = *ptr++; +			msgNum1 += 200; + +			if (msgNum1 == 569) +				msgNum1 += 400; +			if (msgNum2 == 0) +				msgNum2 = msgNum1; +			return; +		} +		ptr++; +	} + +	if (msgNum1 == 569) +		msgNum1 += 400; +	if (msgNum2 == 0) +		msgNum2 = msgNum1; +} + +char *AGOSEngine_PN::getMessage(char *msg, uint16 num) { +	char *origPtr, *strPtr1 = msg; +	uint8 count; + +	getObjectName(strPtr1, num); +	if (!(num & 0x8000)) { +		return msg; +	} + +	if (strPtr1[0] == 0x41 || strPtr1[0] == 0x61) { +		if (strPtr1[1] != 0x20) +			strPtr1 += 2; +	} else if (strPtr1[0] == 0x54 || strPtr1[0] == 0x74) { +		if (strPtr1[1] == 0x68 && +		    strPtr1[2] == 0x65 && +		    strPtr1[3] == 0x20) +			strPtr1 += 4; +	} + +	origPtr = strPtr1; +	while (*strPtr1 != 13) +		strPtr1++; + +	strPtr1[0] = 32; +	strPtr1[1] = 13; +	strPtr1[2] = 0; + +	if (_videoLockOut & 0x10) { +		strPtr1 = origPtr; +		count = 6; +		while (*strPtr1) { +			if (*strPtr1 == 32) { +				count = 6; +			} else { +				count--; +				if (count == 0) { +					char *tmpPtr = strPtr1; +					char *strPtr2 = strPtr1; + +					while (*strPtr2 != 0 && *strPtr2 != 32) +						strPtr2++; + +					while (*strPtr2) { +						*strPtr1++ = *strPtr2++; +					} +					*strPtr1++ = *strPtr2++; + +					strPtr1 = tmpPtr; +					count = 6; +				} +			} +			strPtr1++; +		} +	} + +	return origPtr; +} + +} // End of namespace AGOS diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp index 70ad3404f5..a4aa81a171 100644 --- a/engines/agos/subroutine.cpp +++ b/engines/agos/subroutine.cpp @@ -25,6 +25,8 @@ +#include "common/file.h" +  #include "agos/agos.h"  #include "agos/intern.h" diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp index 8376ebb28e..bdf23d5815 100644 --- a/engines/agos/verb.cpp +++ b/engines/agos/verb.cpp @@ -203,6 +203,7 @@ static const char *const czech_verb_prep_names[] = {  	"", "", "", "komu ?"  }; +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::clearName() {  	stopAnimateSimon2(2, 6);  	_lastNameOn = NULL; @@ -210,6 +211,7 @@ void AGOSEngine_Feeble::clearName() {  	_mouseAnim = 1;  	return;  } +#endif  void AGOSEngine_Simon2::clearName() {  	if (getBitFlag(79)) { @@ -530,6 +532,7 @@ void AGOSEngine::defineBox(int id, int x, int y, int width, int height, int flag  	_needHitAreaRecalc++;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_PuzzlePack::resetVerbs() {  	_verbHitArea = 300;  } @@ -559,6 +562,7 @@ void AGOSEngine_Feeble::resetVerbs() {  		setVerb(NULL);  	}  } +#endif  void AGOSEngine::resetVerbs() {  	if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) @@ -590,6 +594,7 @@ void AGOSEngine::resetVerbs() {  	}  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::setVerb(HitArea *ha) {  	int cursor = _mouseCursor;  	if (_noRightClick) @@ -616,6 +621,7 @@ void AGOSEngine_Feeble::setVerb(HitArea *ha) {  	_needHitAreaRecalc++;  	_verbHitArea = cursor + 300;  } +#endif  void AGOSEngine::setVerb(HitArea *ha) {  	HitArea *tmp = _currentVerbBox; @@ -654,9 +660,11 @@ void AGOSEngine::setVerb(HitArea *ha) {  	_currentVerbBox = ha;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::hitarea_leave(HitArea *ha, bool state) {  	invertBox(ha, state);  } +#endif  void AGOSEngine::hitarea_leave(HitArea *ha, bool state) {  	if (getGameType() == GType_SIMON2) { @@ -917,6 +925,7 @@ void AGOSEngine::displayName(HitArea *ha) {  		_lastNameOn = ha;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::invertBox(HitArea *ha, bool state) {  	if (getBitFlag(205) || getBitFlag(206)) {  		if (state != 0) { @@ -959,6 +968,7 @@ void AGOSEngine_Feeble::invertBox(HitArea *ha, bool state) {  		}  	}  } +#endif  void AGOSEngine::invertBox(HitArea *ha, byte a, byte b, byte c, byte d) {  	byte *src, color; @@ -1027,257 +1037,4 @@ void AGOSEngine::invertBox(HitArea *ha, byte a, byte b, byte c, byte d) {  	_videoLockOut &= ~0x8000;  } -#ifdef ENABLE_PN -// Personal Nightmare specific -void AGOSEngine_PN::boxController(uint x, uint y, uint mode) { -	HitArea *best_ha; -	HitArea *ha = _hitAreaList; - -	best_ha = NULL; - -	do { -		if (!(ha->flags & kOBFBoxDisabled)) { -			if (x >= ha->x && y >= ha->y && x - ha->x < ha->width && y - ha->y < ha->height && -				best_ha == NULL) { -				best_ha = ha; -			} else { -				if (ha->flags & kOBFBoxSelected) { -					hitarea_leave(ha , true); -					ha->flags &= ~kOBFBoxSelected; -				} -			} -		} else { -			ha->flags &= ~kOBFBoxSelected; -		} -	} while (ha++, ha->id != 0xFFFF); - -	if (mode != 0) { -		_lastHitArea = best_ha; -	} - -	if (best_ha == NULL) { -		return; -	} - -	if (best_ha->flags & kOBFInvertTouch && !(best_ha->flags & kOBFBoxSelected)) { -		hitarea_leave(best_ha, false); -		best_ha->flags |= kOBFBoxSelected; -	} -} - -void AGOSEngine_PN::mouseHit() { -	if (_hitCalled == 5) { -		execMouseHit(NULL); -	} else { -		boxController(_mouse.x, _mouse.y, 1); -		if (_hitCalled == 4 || _lastHitArea != 0) { -			execMouseHit(_lastHitArea); -		} -	} -	_hitCalled = 0; -	_oneClick = 0; -} - -void AGOSEngine_PN::execMouseHit(HitArea *ha) { -	if (_hitCalled == 1) { -		if (ha->flags & kOBFUseMessageList) -			hitBox11(ha); -		else if (ha->flags & kOBFMoreBox) -			hitBox9(ha); -		else if (ha->flags & kOBFExit) -			hitBox7(ha); -		else if (ha->flags & kOBFUseEmptyLine) -			hitBox2(ha); -		else -			hitBox1(ha); -	} else if (_hitCalled == 2) { -		if (ha->flags & (kOBFObject | kOBFInventoryBox | kOBFRoomBox)) -			hitBox3(ha); -		else if (ha->flags & kOBFUseMessageList) -			hitBox11(ha); -		else if (ha->flags & kOBFMoreBox) -			hitBox9(ha); -		else if (ha->flags & kOBFExit) -			hitBox7(ha); -		else if (ha->flags & kOBFUseEmptyLine) -			hitBox2(ha); -		else -			hitBox1(ha); -	} else if (_hitCalled == 3) { -		if ((ha->flags & kOBFDraggable) && !_dragFlag) { -			_dragFlag = true; -			_dragStore = ha; -			_needHitAreaRecalc++; -		} -	} else if (_hitCalled == 4) { -		_dragFlag = false; -		_hitCalled = 0; -		_oneClick = 0; -		_dragCount = 0; -		_needHitAreaRecalc++; -		if (ha != 0) { -			if (ha->flags & kOBFInventoryBox) -				hitBox5(ha); -			else if (ha->flags & kOBFRoomBox) -				hitBox6(ha); -			else if (_videoLockOut & 10) -				hitBox8(ha); -		} -	} else { -		_hitCalled = 0; -		if (_mouseString == 0) { -			_mouseString = (const char *)"\r"; -		} -	} -} - -void AGOSEngine_PN::hitBox1(HitArea *ha) { -	if (_mouseString) -		return; - -	_mouseString = getMessage(_objectName1, ha->msg1); -	if (_intputCounter) { -		char *msgPtr = getMessage(_objectName1, ha->msg1); -		while (*msgPtr != 13) -			msgPtr++; -		*msgPtr = 0; -	} else if (!(ha->flags & kOBFNoShowName)) { -		_mousePrintFG++; -		_mouseString1 = _mouseString; -		_mouseString = (const char*)"showname \0"; - -	} -} - -void AGOSEngine_PN::hitBox2(HitArea *ha) { -	if (!_intputCounter) -		hitBox1(ha); -} - -void AGOSEngine_PN::hitBox3(HitArea *ha) { -	if (!_intputCounter) -		hitBox4(ha); -} - -void AGOSEngine_PN::hitBox4(HitArea *ha) { -	if (_mouseString) -		return; - -	uint16 num = ha->msg1 & ~0x8000; -	if ((_videoLockOut & 0x10) && !(ha->flags & (kOBFInventoryBox | kOBFRoomBox)) && -		!testContainer(num)) { -		return; -	} - -	_mouseString = getMessage(_objectName2, ha->msg2); -	_mouseString1 = getMessage(_objectName1, ha->msg1); -	_mousePrintFG++; -} - -void AGOSEngine_PN::hitBox5(HitArea *ha) { -	if (_intputCounter || _mouseString) -		return; - -	if (_dragStore && (_dragStore->flags & kOBFInventoryBox)) -		return; - -	_mousePrintFG++; -	_mouseString = (const char *)"take \0"; -	_mouseString1 = getMessage(_objectName1, _dragStore->msg1); - -	if (_dragStore->flags & kOBFRoomBox) -		_mouseString1 = (const char *)"all\r"; -} - -void AGOSEngine_PN::hitBox6(HitArea *ha) { -	if (_intputCounter || _mouseString) -		return; - -	if (_dragStore->flags & kOBFRoomBox) -		return; - -	_mousePrintFG++; -	_mouseString = (const char *)"drop \0"; -	_mouseString1 = getMessage(_objectName1, _dragStore->msg1); - -	if (_dragStore->flags & kOBFInventoryBox) -		_mouseString1 = (const char *)"all\r"; -} - -void AGOSEngine_PN::hitBox7(HitArea *ha) { -	if (_intputCounter) { -		if (!(ha->flags & kOBFUseEmptyLine)) { -			hitBox1(ha); -		} -		return; -	} - -	if (_mouseString) -		return; - -	_mousePrintFG++; -	_mouseString1 = getMessage(_objectName1, ha->msg1); - -	uint16 num = ha->msg1 & ~0x8000; -	uint16 state = getptr(_quickptr[0] + num * _quickshort[0] + 2); -	if (state == 3) { -		_mouseString = (const char *)"unlock \0"; -	} else if (state == 2) { -		_mouseString = (const char *)"open \0"; -	} else { -		_mouseString = (const char *)"go through \0"; -	} -} - -void AGOSEngine_PN::hitBox8(HitArea *ha) { -	char *msgPtr, *tmpPtr; - -	if (_intputCounter || _mouseString) -		return; - -	if (_dragStore == ha) -		return; - -	uint16 num = ha->msg1 & ~0x8000; -	if (!testSeen(num)) -		return; - -	msgPtr = getMessage(_objectName1, ha->msg1); -	sprintf(_inMessage, " in %s", msgPtr); -	_mouseString1 = _inMessage; - -	msgPtr = getMessage(_objectName1, _dragStore->msg1); -	*(tmpPtr = strchr(msgPtr, 13)) = 0; -	sprintf(_placeMessage, "put %s", msgPtr); -	_mouseString = _placeMessage; -} - -void AGOSEngine_PN::hitBox9(HitArea *ha) { -	if (_objectCountS == _objects) { -		_objectCountS = -1; -	} -	iconPage(); -} - -static const char *messageList[9] = { -	"North\r", -	"East\r", -	"South\r", -	"West\r", -	"Up\r", -	"Down\r", -	"Push grey button\r", -	"Push red button\r", -	"Go under car\r" -}; - -void AGOSEngine_PN::hitBox11(HitArea *ha) { -	if (_intputCounter || _mouseString) -		return; - -	_mouseString = messageList[ha->msg1]; -	_mousePrintFG++; -} -#endif -  } // End of namespace AGOS diff --git a/engines/agos/verb_pn.cpp b/engines/agos/verb_pn.cpp new file mode 100644 index 0000000000..129e1dec0e --- /dev/null +++ b/engines/agos/verb_pn.cpp @@ -0,0 +1,284 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +// Verb and hitarea handling + + +#include "agos/agos.h" +#include "agos/intern.h" + +namespace AGOS { + +void AGOSEngine_PN::boxController(uint x, uint y, uint mode) { +	HitArea *best_ha; +	HitArea *ha = _hitAreaList; + +	best_ha = NULL; + +	do { +		if (!(ha->flags & kOBFBoxDisabled)) { +			if (x >= ha->x && y >= ha->y && x - ha->x < ha->width && y - ha->y < ha->height && +				best_ha == NULL) { +				best_ha = ha; +			} else { +				if (ha->flags & kOBFBoxSelected) { +					hitarea_leave(ha , true); +					ha->flags &= ~kOBFBoxSelected; +				} +			} +		} else { +			ha->flags &= ~kOBFBoxSelected; +		} +	} while (ha++, ha->id != 0xFFFF); + +	if (mode != 0) { +		_lastHitArea = best_ha; +	} + +	if (best_ha == NULL) { +		return; +	} + +	if (best_ha->flags & kOBFInvertTouch && !(best_ha->flags & kOBFBoxSelected)) { +		hitarea_leave(best_ha, false); +		best_ha->flags |= kOBFBoxSelected; +	} +} + +void AGOSEngine_PN::mouseHit() { +	if (_hitCalled == 5) { +		execMouseHit(NULL); +	} else { +		boxController(_mouse.x, _mouse.y, 1); +		if (_hitCalled == 4 || _lastHitArea != 0) { +			execMouseHit(_lastHitArea); +		} +	} +	_hitCalled = 0; +	_oneClick = 0; +} + +void AGOSEngine_PN::execMouseHit(HitArea *ha) { +	if (_hitCalled == 1) { +		if (ha->flags & kOBFUseMessageList) +			hitBox11(ha); +		else if (ha->flags & kOBFMoreBox) +			hitBox9(ha); +		else if (ha->flags & kOBFExit) +			hitBox7(ha); +		else if (ha->flags & kOBFUseEmptyLine) +			hitBox2(ha); +		else +			hitBox1(ha); +	} else if (_hitCalled == 2) { +		if (ha->flags & (kOBFObject | kOBFInventoryBox | kOBFRoomBox)) +			hitBox3(ha); +		else if (ha->flags & kOBFUseMessageList) +			hitBox11(ha); +		else if (ha->flags & kOBFMoreBox) +			hitBox9(ha); +		else if (ha->flags & kOBFExit) +			hitBox7(ha); +		else if (ha->flags & kOBFUseEmptyLine) +			hitBox2(ha); +		else +			hitBox1(ha); +	} else if (_hitCalled == 3) { +		if ((ha->flags & kOBFDraggable) && !_dragFlag) { +			_dragFlag = true; +			_dragStore = ha; +			_needHitAreaRecalc++; +		} +	} else if (_hitCalled == 4) { +		_dragFlag = false; +		_hitCalled = 0; +		_oneClick = 0; +		_dragCount = 0; +		_needHitAreaRecalc++; +		if (ha != 0) { +			if (ha->flags & kOBFInventoryBox) +				hitBox5(ha); +			else if (ha->flags & kOBFRoomBox) +				hitBox6(ha); +			else if (_videoLockOut & 10) +				hitBox8(ha); +		} +	} else { +		_hitCalled = 0; +		if (_mouseString == 0) { +			_mouseString = (const char *)"\r"; +		} +	} +} + +void AGOSEngine_PN::hitBox1(HitArea *ha) { +	if (_mouseString) +		return; + +	_mouseString = getMessage(_objectName1, ha->msg1); +	if (_intputCounter) { +		char *msgPtr = getMessage(_objectName1, ha->msg1); +		while (*msgPtr != 13) +			msgPtr++; +		*msgPtr = 0; +	} else if (!(ha->flags & kOBFNoShowName)) { +		_mousePrintFG++; +		_mouseString1 = _mouseString; +		_mouseString = (const char*)"showname \0"; + +	} +} + +void AGOSEngine_PN::hitBox2(HitArea *ha) { +	if (!_intputCounter) +		hitBox1(ha); +} + +void AGOSEngine_PN::hitBox3(HitArea *ha) { +	if (!_intputCounter) +		hitBox4(ha); +} + +void AGOSEngine_PN::hitBox4(HitArea *ha) { +	if (_mouseString) +		return; + +	uint16 num = ha->msg1 & ~0x8000; +	if ((_videoLockOut & 0x10) && !(ha->flags & (kOBFInventoryBox | kOBFRoomBox)) && +		!testContainer(num)) { +		return; +	} + +	_mouseString = getMessage(_objectName2, ha->msg2); +	_mouseString1 = getMessage(_objectName1, ha->msg1); +	_mousePrintFG++; +} + +void AGOSEngine_PN::hitBox5(HitArea *ha) { +	if (_intputCounter || _mouseString) +		return; + +	if (_dragStore && (_dragStore->flags & kOBFInventoryBox)) +		return; + +	_mousePrintFG++; +	_mouseString = (const char *)"take \0"; +	_mouseString1 = getMessage(_objectName1, _dragStore->msg1); + +	if (_dragStore->flags & kOBFRoomBox) +		_mouseString1 = (const char *)"all\r"; +} + +void AGOSEngine_PN::hitBox6(HitArea *ha) { +	if (_intputCounter || _mouseString) +		return; + +	if (_dragStore->flags & kOBFRoomBox) +		return; + +	_mousePrintFG++; +	_mouseString = (const char *)"drop \0"; +	_mouseString1 = getMessage(_objectName1, _dragStore->msg1); + +	if (_dragStore->flags & kOBFInventoryBox) +		_mouseString1 = (const char *)"all\r"; +} + +void AGOSEngine_PN::hitBox7(HitArea *ha) { +	if (_intputCounter) { +		if (!(ha->flags & kOBFUseEmptyLine)) { +			hitBox1(ha); +		} +		return; +	} + +	if (_mouseString) +		return; + +	_mousePrintFG++; +	_mouseString1 = getMessage(_objectName1, ha->msg1); + +	uint16 num = ha->msg1 & ~0x8000; +	uint16 state = getptr(_quickptr[0] + num * _quickshort[0] + 2); +	if (state == 3) { +		_mouseString = (const char *)"unlock \0"; +	} else if (state == 2) { +		_mouseString = (const char *)"open \0"; +	} else { +		_mouseString = (const char *)"go through \0"; +	} +} + +void AGOSEngine_PN::hitBox8(HitArea *ha) { +	char *msgPtr, *tmpPtr; + +	if (_intputCounter || _mouseString) +		return; + +	if (_dragStore == ha) +		return; + +	uint16 num = ha->msg1 & ~0x8000; +	if (!testSeen(num)) +		return; + +	msgPtr = getMessage(_objectName1, ha->msg1); +	sprintf(_inMessage, " in %s", msgPtr); +	_mouseString1 = _inMessage; + +	msgPtr = getMessage(_objectName1, _dragStore->msg1); +	*(tmpPtr = strchr(msgPtr, 13)) = 0; +	sprintf(_placeMessage, "put %s", msgPtr); +	_mouseString = _placeMessage; +} + +void AGOSEngine_PN::hitBox9(HitArea *ha) { +	if (_objectCountS == _objects) { +		_objectCountS = -1; +	} +	iconPage(); +} + +static const char *messageList[9] = { +	"North\r", +	"East\r", +	"South\r", +	"West\r", +	"Up\r", +	"Down\r", +	"Push grey button\r", +	"Push red button\r", +	"Go under car\r" +}; + +void AGOSEngine_PN::hitBox11(HitArea *ha) { +	if (_intputCounter || _mouseString) +		return; + +	_mouseString = messageList[ha->msg1]; +	_mousePrintFG++; +} + +} // End of namespace AGOS diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index 7855d0e805..1344be6b3a 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -106,7 +106,7 @@ void AGOSEngine_Elvira1::setupVideoOpcodes(VgaOpcodeProc *op) {  	op[20] = &AGOSEngine::vc19_loop;  	op[21] = &AGOSEngine::vc20_setRepeat;  	op[22] = &AGOSEngine::vc21_endRepeat; -	op[23] = &AGOSEngine::vc22_setPaletteOld; +	op[23] = &AGOSEngine::vc22_setPalette;  	op[24] = &AGOSEngine::vc23_setPriority;  	op[25] = &AGOSEngine::vc24_setSpriteXY;  	op[26] = &AGOSEngine::vc25_halt_sprite; @@ -918,7 +918,7 @@ static const uint8 iconPalette[64] = {  	0x77, 0x55, 0x00,  }; -void AGOSEngine::vc22_setPaletteOld() { +void AGOSEngine::vc22_setPalette() {  	byte *offs, *palptr, *src;  	uint16 b, num; @@ -1302,12 +1302,7 @@ void AGOSEngine::vc36_setWindowImage() {  	_displayScreen = false;  	uint16 vga_res = vcReadNextWord();  	uint16 windowNum = vcReadNextWord(); - -	if (getGameType() == GType_FF || getGameType() == GType_PP) { -		fillBackGroundFromFront(); -	} else { -		setWindowImage(windowNum, vga_res); -	} +	setWindowImage(windowNum, vga_res);  }  void AGOSEngine::vc37_pokePalette() { diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp index de3cb55963..1bbc7f4849 100644 --- a/engines/agos/vga_e2.cpp +++ b/engines/agos/vga_e2.cpp @@ -40,7 +40,7 @@ void AGOSEngine_Elvira2::setupVideoOpcodes(VgaOpcodeProc *op) {  	op[17] = &AGOSEngine::vc17_waitEnd;  	op[19] = &AGOSEngine::vc19_loop; -	op[22] = &AGOSEngine::vc22_setPaletteOld; +	op[22] = &AGOSEngine::vc22_setPalette;  	op[28] = &AGOSEngine::vc28_playSFX;  	op[32] = &AGOSEngine::vc32_saveScreen;  	op[37] = &AGOSEngine::vc37_pokePalette; diff --git a/engines/agos/vga_ff.cpp b/engines/agos/vga_ff.cpp index 14451a3dbe..a92be159e7 100644 --- a/engines/agos/vga_ff.cpp +++ b/engines/agos/vga_ff.cpp @@ -25,6 +25,8 @@ +#ifdef ENABLE_AGOS2 +  #include "agos/agos.h"  #include "agos/intern.h" @@ -68,6 +70,57 @@ int AGOSEngine::getScale(int16 y, int16 x) {  	}  } +void AGOSEngine_Feeble::vc36_setWindowImage() { +	_displayScreen = false; +	vcReadNextWord(); +	vcReadNextWord(); +	fillBackGroundFromFront(); +} + +void AGOSEngine_Feeble::vc48_setPathFinder() { +	uint16 a = (uint16)_variableArrayPtr[12]; +	const uint16 *p = _pathFindArray[a - 1]; + +	VgaSprite *vsp = findCurSprite(); +	int16 x, y, ydiff; +	int16 x1, y1, x2, y2; +	uint pos = 0; + +	x = vsp->x; +	while (x >= (int16)readUint16Wrapper(p + 2)) { +		p += 2; +		pos++; +	} + +	x1 = readUint16Wrapper(p); +	y1 = readUint16Wrapper(p + 1); +	x2 = readUint16Wrapper(p + 2); +	y2 = readUint16Wrapper(p + 3); + +	if (x2 != 9999) { +		ydiff = y2 - y1; +		if (ydiff < 0) { +			ydiff = -ydiff; +			x = vsp->x & 7; +			ydiff *= x; +			ydiff /= 8; +			ydiff = -ydiff; +		} else { +			x = vsp->x & 7; +			ydiff *= x; +			ydiff /= 8; +		} +		y1 += ydiff; +	} + +	y = vsp->y; +	vsp->y = y1; +	checkScrollY(y1 - y, y1); + +	_variableArrayPtr[11] = x1; +	_variableArrayPtr[13] = pos; +} +  void AGOSEngine::vc75_setScale() {  	_baseY = vcReadNextWord();  	_scale = vcReadNextWord() / 1000000.0f; @@ -435,3 +488,5 @@ void AGOSEngine_PuzzlePack::startAnOverlayAnim() {  }  } // End of namespace AGOS + +#endif // ENABLE_AGOS2 diff --git a/engines/agos/vga_pn.cpp b/engines/agos/vga_pn.cpp index 12846b08f1..d249259ba6 100644 --- a/engines/agos/vga_pn.cpp +++ b/engines/agos/vga_pn.cpp @@ -23,8 +23,6 @@   *   */ -#ifdef ENABLE_PN -  #include "agos/agos.h"  #include "agos/intern.h"  #include "agos/vga.h" @@ -57,7 +55,7 @@ void AGOSEngine_PN::setupVideoOpcodes(VgaOpcodeProc *op) {  	op[20] = &AGOSEngine::vc19_loop;  	op[21] = &AGOSEngine::vc20_setRepeat;  	op[22] = &AGOSEngine::vc21_endRepeat; -	op[23] = &AGOSEngine::vc22_setPaletteOld; +	op[23] = &AGOSEngine::vc22_setPalette;  	op[24] = &AGOSEngine::vc23_setPriority;  	op[25] = &AGOSEngine::vc24_setSpriteXY;  	op[26] = &AGOSEngine::vc25_halt_sprite; @@ -219,5 +217,3 @@ void AGOSEngine_PN::clearVideoWindow(uint16 num, uint16 color) {  }  } // End of namespace AGOS - -#endif diff --git a/engines/agos/vga_s1.cpp b/engines/agos/vga_s1.cpp index b1ae26437e..bb13d211fe 100644 --- a/engines/agos/vga_s1.cpp +++ b/engines/agos/vga_s1.cpp @@ -36,7 +36,7 @@ void AGOSEngine_Simon1::setupVideoOpcodes(VgaOpcodeProc *op) {  	op[11] = &AGOSEngine::vc11_clearPathFinder;  	op[17] = &AGOSEngine::vc17_setPathfinderItem; -	op[22] = &AGOSEngine::vc22_setPaletteNew; +	op[22] = &AGOSEngine::vc22_setPalette;  	op[32] = &AGOSEngine::vc32_copyVar;  	op[37] = &AGOSEngine::vc37_addToSpriteY;  	op[48] = &AGOSEngine::vc48_setPathFinder; @@ -96,7 +96,7 @@ static const uint8 customPalette[96] = {  	0xFF, 0xFF, 0x77,  }; -void AGOSEngine::vc22_setPaletteNew() { +void AGOSEngine_Simon1::vc22_setPalette() {  	byte *offs, *palptr = 0, *src;  	uint16 a = 0, b, num, palSize = 0; @@ -186,73 +186,32 @@ void AGOSEngine::vc48_setPathFinder() {  	uint16 a = (uint16)_variableArrayPtr[12];  	const uint16 *p = _pathFindArray[a - 1]; -	if (getGameType() == GType_FF || getGameType() == GType_PP) { -		VgaSprite *vsp = findCurSprite(); -		int16 x, y, ydiff; -		int16 x1, y1, x2, y2; -		uint pos = 0; - -		x = vsp->x; -		while (x >= (int16)readUint16Wrapper(p + 2)) { -			p += 2; -			pos++; -		} - -		x1 = readUint16Wrapper(p); -		y1 = readUint16Wrapper(p + 1); -		x2 = readUint16Wrapper(p + 2); -		y2 = readUint16Wrapper(p + 3); - -		if (x2 != 9999) { -			ydiff = y2 - y1; -			if (ydiff < 0) { -				ydiff = -ydiff; -				x = vsp->x & 7; -				ydiff *= x; -				ydiff /= 8; -				ydiff = -ydiff; -			} else { -				x = vsp->x & 7; -				ydiff *= x; -				ydiff /= 8; -			} -			y1 += ydiff; -		} - -		y = vsp->y; -		vsp->y = y1; -		checkScrollY(y1 - y, y1); - -		_variableArrayPtr[11] = x1; -		_variableArrayPtr[13] = pos; -	} else { -		uint b = (uint16)_variableArray[13]; -		p += b * 2 + 1; -		int c = _variableArray[14]; +	uint b = (uint16)_variableArray[13]; +	p += b * 2 + 1; +	int c = _variableArray[14]; -		int step; -		int y1, y2; -		int16 *vp; +	int step; +	int y1, y2; +	int16 *vp; -		step = 2; -		if (c < 0) { -			c = -c; -			step = -2; -		} +	step = 2; +	if (c < 0) { +		c = -c; +		step = -2; +	} -		vp = &_variableArray[20]; +	vp = &_variableArray[20]; -		do { -			y2 = readUint16Wrapper(p); -			p += step; -			y1 = readUint16Wrapper(p) - y2; +	do { +		y2 = readUint16Wrapper(p); +		p += step; +		y1 = readUint16Wrapper(p) - y2; -			vp[0] = y1 / 2; -			vp[1] = y1 - (y1 / 2); +		vp[0] = y1 / 2; +		vp[1] = y1 - (y1 / 2); -			vp += 2; -		} while (--c); -	} +		vp += 2; +	} while (--c);  }  void AGOSEngine::vc59_ifSpeech() { diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp index a578568a03..8bf4102067 100644 --- a/engines/agos/window.cpp +++ b/engines/agos/window.cpp @@ -122,6 +122,7 @@ void AGOSEngine::clearWindow(WindowBlock *window) {  	window->scrollY = 0;  } +#ifdef ENABLE_AGOS2  void AGOSEngine_Feeble::colorWindow(WindowBlock *window) {  	byte *dst;  	uint16 h, w; @@ -140,6 +141,7 @@ void AGOSEngine_Feeble::colorWindow(WindowBlock *window) {  	_videoLockOut &= ~0x8000;  } +#endif  void AGOSEngine::colorWindow(WindowBlock *window) {  	uint16 y, h; diff --git a/engines/engines.mk b/engines/engines.mk index 8d7d8de9ff..b73f45b8e6 100644 --- a/engines/engines.mk +++ b/engines/engines.mk @@ -21,8 +21,8 @@ ifdef ENABLE_AGOS  DEFINES += -DENABLE_AGOS=$(ENABLE_AGOS)  MODULES += engines/agos -ifdef ENABLE_PN -DEFINES += -DENABLE_PN +ifdef ENABLE_AGOS2 +DEFINES += -DENABLE_AGOS2  endif  endif diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp index 9ef20ba8a3..e9c71f511d 100644 --- a/engines/kyra/gui_lok.cpp +++ b/engines/kyra/gui_lok.cpp @@ -208,9 +208,29 @@ void GUI_LoK::createScreenThumbnail(Graphics::Surface &dst) {  	uint8 *screen = new uint8[Screen::SCREEN_W*Screen::SCREEN_H];  	if (screen) {  		_screen->queryPageFromDisk("SEENPAGE.TMP", 0, screen); -  		uint8 screenPal[768]; -		_screen->getRealPalette(2, screenPal); + +		if (_vm->gameFlags().platform == Common::kPlatformAmiga) { +			_screen->getRealPalette(0, &screenPal[ 0]); +			_screen->getRealPalette(1, &screenPal[96]); + +			// Set the interface palette text color to white +			screenPal[96 + 16 * 3 + 0] = 0xFF; +			screenPal[96 + 16 * 3 + 1] = 0xFF; +			screenPal[96 + 16 * 3 + 2] = 0xFF; + +			if (_screen->isInterfacePaletteEnabled()) { +				for (int y = 0; y < 64; ++y) { +					for (int x = 0; x < 320; ++x) { +						screen[(y + 136) * Screen::SCREEN_W + x] += 32; +					} +				} +			} + +		} else { +			_screen->getRealPalette(2, screenPal); +		} +  		::createThumbnail(&dst, screen, Screen::SCREEN_W, Screen::SCREEN_H, screenPal);  	}  	delete[] screen; @@ -371,8 +391,11 @@ void GUI_LoK::setGUILabels() {  		walkspeedGarbageOffset = 0;  	} else if (_vm->gameFlags().platform == Common::kPlatformAmiga) {  		// English Amiga version -		offsetOptions = 8; +		offset = 23; +		offsetOn = 23; +		offsetOptions = 32;  		walkspeedGarbageOffset = 2; +		offsetMainMenu = 23;  	}  	assert(offset + 27 < _vm->_guiStringsSize); @@ -653,12 +676,12 @@ int GUI_LoK::loadGameMenu(Button *button) {  }  void GUI_LoK::redrawTextfield() { -	_screen->fillRect(38, 91, 287, 102, 250); +	_screen->fillRect(38, 91, 287, 102, _vm->gameFlags().platform == Common::kPlatformAmiga ? 18 : 250);  	_text->printText(_savegameName, 38, 92, 253, 0, 0);  	_screen->_charWidth = -2;  	int width = _screen->getTextWidth(_savegameName); -	_screen->fillRect(39 + width, 93, 45 + width, 100, 254); +	_screen->fillRect(39 + width, 93, 45 + width, 100, _vm->gameFlags().platform == Common::kPlatformAmiga ? 31 : 254);  	_screen->_charWidth = 0;  	_screen->updateScreen(); diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h index e22cc0d997..e7cc92c5e1 100644 --- a/engines/kyra/kyra_lok.h +++ b/engines/kyra/kyra_lok.h @@ -192,6 +192,7 @@ protected:  	// -> credits  	void seq_playCredits(); +	void seq_playCreditsAmiga();  public:  	// delay diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index f102e92802..e3d28163a8 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -160,7 +160,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy  	_flyingObjects = 0;  	_monsters = 0;  	_lastMouseRegion = 0; -	_objectLastDirection = _monsterCountUnk = _monsterShiftAlt = 0; +	_objectLastDirection = _monsterStepCounter = _monsterStepMode = 0;  	_monsterCurBlock = 0;  	_seqWindowX1 = _seqWindowY1 = _seqWindowX2 = _seqWindowY2 = _seqTrigger = 0;  	_spsWindowX = _spsWindowY = _spsWindowW = _spsWindowH = 0; diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index f4ac597b5c..06950779b1 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -1296,8 +1296,8 @@ private:  	uint8 _monsterAnimType[3];  	uint16 _monsterCurBlock;  	int _objectLastDirection; -	int _monsterCountUnk; -	int _monsterShiftAlt; +	int _monsterStepCounter; +	int _monsterStepMode;  	const uint16 *_monsterModifiers;  	int _monsterModifiersSize; diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp index 3c92b8f2d4..13f08715fd 100644 --- a/engines/kyra/saveload_lok.cpp +++ b/engines/kyra/saveload_lok.cpp @@ -182,10 +182,27 @@ Common::Error KyraEngine_LoK::loadGameState(int slot) {  	}  	setHandItem(_itemInHand); -	_animator->setBrandonAnimSeqSize(3, 48); + +	// Will-O-Wisp uses a different shape size than Brandon's usual +	// shape, thus we need to setup the correct size depending on +	// his state over here. This fixes graphics glitches when loading +	// saves, where Brandon is transformed into the Will-O-Wisp. +	if (_brandonStatusBit & 2) +		_animator->setBrandonAnimSeqSize(5, 48); +	else +		_animator->setBrandonAnimSeqSize(3, 48); +  	redrawInventory(0); -	_brandonPosX = brandonX; -	_brandonPosY = brandonY; +	 +	_brandonPosX = _brandonPosY = -1; +	 +	// Unlike the original we did restore Brandon's position in the scene screen on load. +	// This appereantly caused graphics gliches in some scenes. For example bug #2835715 +	// ("KYRA: GFX glitch in Amiga version at the bridge") is caused by this feature. +	// Thus we disable that for now. +	//_brandonPosX = brandonX; +	//_brandonPosY = brandonY; +  	enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1);  	_animator->animRefreshNPC(0); diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 97ecbcfb28..bc1ccbb801 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -79,6 +79,7 @@ bool Screen::init() {  	_useOverlays = false;  	_useSJIS = false;  	_use16ColorMode = _vm->gameFlags().use16ColorMode; +	_isAmiga = (_vm->gameFlags().platform == Common::kPlatformAmiga);  	if (_vm->gameFlags().useHiResOverlay) {  		_useOverlays = true; @@ -110,8 +111,8 @@ bool Screen::init() {  	memset(_shapePages, 0, sizeof(_shapePages)); -	const int paletteCount = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 13 : 4; -	const int numColors = _use16ColorMode ? 16 : ((_vm->gameFlags().platform == Common::kPlatformAmiga) ? 32 : 256); +	const int paletteCount = _isAmiga ? 13 : 4; +	const int numColors = _use16ColorMode ? 16 : (_isAmiga ? 32 : 256);  	_interfacePaletteEnabled = false; @@ -205,6 +206,8 @@ void Screen::setResolution() {  void Screen::updateScreen() {  	if (_useOverlays)  		updateDirtyRectsOvl(); +	else if (_isAmiga && _interfacePaletteEnabled) +		updateDirtyRectsAmiga();  	else  		updateDirtyRects(); @@ -219,30 +222,86 @@ void Screen::updateScreen() {  }  void Screen::updateDirtyRects() { -	// TODO: Enable dirty rect handling for the AMIGA version -	if (_forceFullUpdate || _vm->gameFlags().platform == Common::kPlatformAmiga) { -		if (_interfacePaletteEnabled) { -			_system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, 136); +	if (_forceFullUpdate) { +		_system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); +	} else { +		const byte *page0 = getCPagePtr(0); +		Common::List<Common::Rect>::iterator it; +		for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) { +			_system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height()); +		} +	} +	_forceFullUpdate = false; +	_dirtyRects.clear(); +} -			// Page 8 is not used by Kyra 1 AMIGA, thus we can use it to adjust the colors -			copyRegion(0, 136, 0, 0, 320, 64, 0, 8, CR_NO_P_CHECK); +void Screen::updateDirtyRectsAmiga() { +	if (_forceFullUpdate) { +		_system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, 136); -			uint8 *dst = getPagePtr(8); -			for (int y = 0; y < 64; ++y) -				for (int x = 0; x < 320; ++x) -					*dst++ += 32; +		// Page 8 is not used by Kyra 1 AMIGA, thus we can use it to adjust the colors +		copyRegion(0, 136, 0, 0, 320, 64, 0, 8, CR_NO_P_CHECK); -			_system->copyRectToScreen(getCPagePtr(8), SCREEN_W, 0, 136, SCREEN_W, 64); -		} else { -			_system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); -		} +		uint8 *dst = getPagePtr(8); +		for (int y = 0; y < 64; ++y) +			for (int x = 0; x < 320; ++x) +				*dst++ += 32; + +		_system->copyRectToScreen(getCPagePtr(8), SCREEN_W, 0, 136, SCREEN_W, 64);  	} else {  		const byte *page0 = getCPagePtr(0);  		Common::List<Common::Rect>::iterator it; +  		for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) { -			_system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height()); +			if (it->bottom <= 136) { +				_system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, it->width(), it->height()); +			} else { +				// Check whether the rectangle is part of both the screen and the interface +				if (it->top < 136) { +					// The rectangle covers both screen part and interface part + +					const int screenHeight = 136 - it->top; +					const int interfaceHeight = it->bottom - 136; + +					const int width = it->width(); +					const int lineAdd = SCREEN_W - width; + +					// Copy the screen part verbatim +					_system->copyRectToScreen(page0 + it->top * SCREEN_W + it->left, SCREEN_W, it->left, it->top, width, screenHeight); + +					// Adjust the interface part +					copyRegion(it->left, 136, 0, 0, width, interfaceHeight, 0, 8, Screen::CR_NO_P_CHECK); + +					uint8 *dst = getPagePtr(8); +					for (int y = 0; y < interfaceHeight; ++y) { +						for (int x = 0; x < width; ++x) +							*dst++ += 32; +						dst += lineAdd; +					} + +					_system->copyRectToScreen(getCPagePtr(8), SCREEN_W, it->left, 136, width, interfaceHeight); +				} else { +					// The rectangle only covers the interface part + +					const int width = it->width(); +					const int height = it->height(); +					const int lineAdd = SCREEN_W - width; + +					copyRegion(it->left, it->top, 0, 0, width, height, 0, 8, Screen::CR_NO_P_CHECK); + +					uint8 *dst = getPagePtr(8); +					for (int y = 0; y < height; ++y) { +						for (int x = 0; x < width; ++x) +							*dst++ += 32; +						dst += lineAdd; +					} + +					_system->copyRectToScreen(getCPagePtr(8), SCREEN_W, it->left, it->top, width, height); +				} +			}  		}  	} +  	_forceFullUpdate = false;  	_dirtyRects.clear();  } @@ -606,7 +665,7 @@ void Screen::setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue) {  }  void Screen::getRealPalette(int num, uint8 *dst) { -	const int colors = (_vm->gameFlags().platform == Common::kPlatformAmiga ? 32 : 256); +	const int colors = _isAmiga ? 32 : 256;  	const uint8 *palData = getPalette(num).getData();  	if (!palData) { @@ -649,7 +708,7 @@ void Screen::enableInterfacePalette(bool e) {  }  void Screen::setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b) { -	if (_vm->gameFlags().platform != Common::kPlatformAmiga) +	if (!_isAmiga)  		return;  	uint8 screenPal[32 * 4]; @@ -1001,7 +1060,7 @@ bool Screen::loadFont(FontId fontId, const char *filename) {  	Font *&fnt = _fonts[fontId];  	if (!fnt) { -		if (_vm->gameFlags().platform == Common::kPlatformAmiga) +		if (_isAmiga)  			fnt = new AMIGAFont();  		else  			fnt = new DOSFont(); @@ -1131,6 +1190,8 @@ void Screen::drawCharANSI(uint8 c, int x, int y) {  	const int charWidth = fnt->getCharWidth(c);  	const int charHeight = fnt->getHeight(); +	if (x < 0 || y < 0) +		return;  	if (x + charWidth > SCREEN_W || y + charHeight > SCREEN_H)  		return; @@ -2785,7 +2846,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette  		error("Unhandled bitmap compression %d", compType);  	} -	if (_vm->gameFlags().platform == Common::kPlatformAmiga) { +	if (_isAmiga) {  		if (!scumm_stricmp(ext, "MSC"))  			Screen::convertAmigaMsc(dstData);  		else @@ -2806,7 +2867,7 @@ bool Screen::loadPalette(const char *filename, Palette &pal) {  	debugC(3, kDebugLevelScreen, "Screen::loadPalette('%s', %p)", filename, (const void *)&pal); -	if (_vm->gameFlags().platform == Common::kPlatformAmiga) +	if (_isAmiga)  		pal.loadAmigaPalette(*stream, 0, stream->size() / Palette::kAmigaBytesPerColor);  	else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode)  		pal.loadPC98Palette(*stream, 0, stream->size() / Palette::kPC98BytesPerColor); @@ -2825,7 +2886,7 @@ bool Screen::loadPaletteTable(const char *filename, int firstPalette) {  	debugC(3, kDebugLevelScreen, "Screen::loadPaletteTable('%s', %d)", filename, firstPalette); -	if (_vm->gameFlags().platform == Common::kPlatformAmiga) { +	if (_isAmiga) {  		const int numColors = getPalette(firstPalette).getNumColors();  		const int palSize = getPalette(firstPalette).getNumColors() * Palette::kAmigaBytesPerColor;  		const int numPals = stream->size() / palSize; @@ -2848,7 +2909,7 @@ bool Screen::loadPaletteTable(const char *filename, int firstPalette) {  void Screen::loadPalette(const byte *data, Palette &pal, int bytes) {  	Common::MemoryReadStream stream(data, bytes, false); -	if (_vm->gameFlags().platform == Common::kPlatformAmiga) +	if (_isAmiga)  		pal.loadAmigaPalette(stream, 0, stream.size() / Palette::kAmigaBytesPerColor);  	else if (_vm->gameFlags().platform == Common::kPlatformPC98 && _use16ColorMode)  		pal.loadPC98Palette(stream, 0, stream.size() / Palette::kPC98BytesPerColor); diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 41837c90e3..73a29ee2c7 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -356,6 +356,7 @@ public:  	virtual void setScreenPalette(const Palette &pal);  	// AMIGA version only +	bool isInterfacePaletteEnabled() const { return _interfacePaletteEnabled; }  	void enableInterfacePalette(bool e);  	void setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b); @@ -451,6 +452,7 @@ public:  protected:  	uint8 *getPagePtr(int pageNum);  	void updateDirtyRects(); +	void updateDirtyRectsAmiga();  	void updateDirtyRectsOvl();  	void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h); @@ -477,6 +479,7 @@ protected:  	bool _useOverlays;  	bool _useSJIS;  	bool _use16ColorMode; +	bool _isAmiga;  	Graphics::FontSJIS *_sjisFont;  	uint8 _sjisInvisibleColor; diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp index feddb29dd2..ed7bef0178 100644 --- a/engines/kyra/screen_lok.cpp +++ b/engines/kyra/screen_lok.cpp @@ -80,6 +80,9 @@ const ScreenDim *Screen_LoK::getScreenDim(int dim) {  }  void Screen_LoK::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { +	if (_vm->gameFlags().platform == Common::kPlatformAmiga) +		return; +  	assert(_vm->palTable1()[palIndex]);  	Palette tempPal(getPalette(0).getNumColors()); diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp index 929fbae1eb..a778a2066b 100644 --- a/engines/kyra/script_lok.cpp +++ b/engines/kyra/script_lok.cpp @@ -236,6 +236,8 @@ int KyraEngine_LoK::o1_fadeSpecialPalette(EMCState *script) {  			}  		} else {  			setupZanthiaPalette(stackPos(0)); +			_screen->getPalette(0).copy(_screen->getPalette(4), 12, 1); +			_screen->fadePalette(_screen->getPalette(0), 2);  		}  	} else {  		debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); @@ -1090,7 +1092,9 @@ int KyraEngine_LoK::o1_specialEventDisplayBrynnsNote(EMCState *script) {  	_screen->copyRegion(63, 8, 63, 8, 194, 128, 2, 0);  	_screen->updateScreen();  	_screen->showMouse(); -	_screen->setFont(Screen::FID_6_FNT); + +	if (_flags.platform != Common::kPlatformAmiga && !_flags.isTalkie) +		_screen->setFont(Screen::FID_6_FNT);  	return 0;  } @@ -1101,7 +1105,9 @@ int KyraEngine_LoK::o1_specialEventRemoveBrynnsNote(EMCState *script) {  	_screen->loadPageFromDisk("HIDPAGE.TMP", 2);  	_screen->updateScreen();  	_screen->showMouse(); -	_screen->setFont(Screen::FID_8_FNT); + +	if (_flags.platform != Common::kPlatformAmiga && !_flags.isTalkie) +		_screen->setFont(Screen::FID_8_FNT);  	return 0;  } @@ -1388,7 +1394,7 @@ int KyraEngine_LoK::o1_waitForConfirmationMouseClick(EMCState *script) {  		updateInput(); -		int input = checkInput(_buttonList, false) & 0xFF; +		int input = checkInput(0, false) & 0xFF;  		removeInputTop();  		if (input == 200)  			break; diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index 3c953ef1d4..8425bf9b0c 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -36,6 +36,7 @@  #include "common/system.h"  #include "common/savefile.h" +#include "common/list.h"  namespace Kyra { @@ -555,7 +556,9 @@ void KyraEngine_LoK::seq_winterScroll1() {  		_animator->sprites()[0].active = 0;  		_sprites->_anims[1].play = true;  		_animator->sprites()[1].active = 1; -		setGameFlag(0xA2); + +		if (_flags.platform != Common::kPlatformAmiga) +			setGameFlag(0xA2);  	}  	for (int i = midpoint; i < 123 + numFrames; ++i) { @@ -569,10 +572,15 @@ void KyraEngine_LoK::seq_winterScroll1() {  			_sprites->_anims[i].play = false;  			_animator->sprites()[i].active = 0;  		} -		_screen->getPalette(0).copy(palTable2()[0], 0, 20, 228); -		_screen->fadePalette(_screen->getPalette(0), 72); -		_screen->setScreenPalette(_screen->getPalette(0)); -		setGameFlag(0xB3); + +		if (_flags.platform == Common::kPlatformAmiga) { +			_screen->copyPalette(0, 11); +		} else { +			_screen->getPalette(0).copy(palTable2()[0], 0, 20, 228); +			_screen->fadePalette(_screen->getPalette(0), 72); +			_screen->setScreenPalette(_screen->getPalette(0)); +			setGameFlag(0xB3); +		}  	} else {  		delayWithTicks(120);  	} @@ -673,7 +681,7 @@ void KyraEngine_LoK::seq_makeBrandonNormal2() {  		_animator->animRefreshNPC(0);  		delayWithTicks(8);  	} -	_animator->setBrandonAnimSeqSize(4, 48); +	_animator->setBrandonAnimSeqSize(3, 48);  	_currentCharacter->currentAnimFrame = 7;  	_animator->animRefreshNPC(0); @@ -718,10 +726,16 @@ void KyraEngine_LoK::seq_makeBrandonWisp() {  	_animator->animRefreshNPC(0);  	_animator->updateAllObjectShapes(); -	if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) -		_screen->fadeSpecialPalette(30, 234, 13, 4); -	else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) -		_screen->fadeSpecialPalette(14, 228, 15, 4); +	if (_flags.platform == Common::kPlatformAmiga) { +		if ((_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) ||  +			(_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186)) +			_screen->fadePalette(_screen->getPalette(10), 0x54); +	} else { +		if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) +			_screen->fadeSpecialPalette(30, 234, 13, 4); +		else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) +			_screen->fadeSpecialPalette(14, 228, 15, 4); +	}  	freeShapes123();  	_screen->showMouse(); @@ -770,6 +784,7 @@ void KyraEngine_LoK::seq_dispelMagicAnimation() {  void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) {  	int newItem = -1; +  	static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C };  	static const uint8 flaskTable2[] = { 0x47, 0x49, 0x4B, 0x4D }; @@ -791,63 +806,135 @@ void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) {  	setMouseItem(newItem);  	_screen->showMouse();  	_itemInHand = newItem; +  	assert(_fullFlask);  	assert(type < _fullFlask_Size && type >= 0); +  	static const uint16 voiceEntries[] = {  		0x1F40, 0x1F41, 0x1F42, 0x1F45  	};  	assert(type < ARRAYSIZE(voiceEntries)); +  	characterSays(voiceEntries[type], _fullFlask[type], 0, -2);  }  void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) { -	uint8 red, green, blue; +	if (_flags.platform == Common::kPlatformAmiga) { +		uint8 r, g, b; + +		switch (item) { +		case 60: case 61: +			// 0xC22 +			r = 50; +			g = 8; +			b = 8; +			break; -	switch (item) { -	case 60: -	case 61: -		red = 63; -		green = blue = 6; -		break; -	case 62: -	case 63: -		red = green = 0; -		blue = 67; -		break; -	case 64: -	case 65: -		red = 84; -		green = 78; -		blue = 14; -		break; -	case 66: -		red = blue = 0; -		green = 48; -		break; -	case 67: -		red = 100; -		green = 48; -		blue = 23; -		break; -	case 68: -		red = 73; -		green = 0; -		blue = 89; -		break; -	case 69: -		red = green = 73; -		blue = 86; -		break; -	default: -		red = 33; -		green = 66; -		blue = 100; -	} -	red   = (uint8)((double)red   * 0.63); -	green = (uint8)((double)green * 0.63); -	blue  = (uint8)((double)blue  * 0.63); +		case 62: case 63: case 76: +		case 77: +			// 0x00E +			r = 0; +			g = 0; +			b = 58; +			break; + +		case 64: case 65: +			// 0xFF5 +			r = 63; +			g = 63; +			b = 21; +			break; + +		case 66: +			// 0x090 +			r = 0; +			g = 37; +			b = 0; +			break; + +		case 67: +			// 0xC61 +			r = 50; +			g = 25; +			b = 4; +			break; + +		case 68: +			// 0xE2E +			r = 58; +			g = 8; +			b = 58; +			break; + +		case 69: +			// 0xBBB +			r = 46; +			g = 46; +			b = 46; +			break; -	_screen->setPaletteIndex(0xFE, red, green, blue); +		default: +			// 0xFFF +			r = 63; +			g = 63; +			b = 63; +		} + +		_screen->setPaletteIndex(16, r, g, b); +	} else { +		uint8 red, green, blue; + +		switch (item) { +		case 60: case 61: +			red = 63; +			green = blue = 6; +			break; + +		case 62: case 63: +			red = green = 0; +			blue = 67; +			break; + +		case 64: case 65: +			red = 84; +			green = 78; +			blue = 14; +			break; + +		case 66: +			red = blue = 0; +			green = 48; +			break; + +		case 67: +			red = 100; +			green = 48; +			blue = 23; +			break; + +		case 68: +			red = 73; +			green = 0; +			blue = 89; +			break; + +		case 69: +			red = green = 73; +			blue = 86; +			break; + +		default: +			red = 33; +			green = 66; +			blue = 100; +		} + +		red   = red * 0x3F / 100; +		green = green * 0x3F / 100; +		blue  = blue * 0x3F / 100; + +		_screen->setPaletteIndex(0xFE, red, green, blue); +	}  	_screen->hideMouse();  	checkAmuletAnimFlags(); @@ -862,7 +949,9 @@ void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) {  		_animator->animRefreshNPC(0);  		delayWithTicks(5);  	} +  	snd_playSoundEffect(0x34); +  	for (int i = 0; i < 2; ++i) {  		_currentCharacter->currentAnimFrame = 130;  		_animator->animRefreshNPC(0); @@ -886,7 +975,10 @@ void KyraEngine_LoK::seq_playDrinkPotionAnim(int item, int unk2, int flags) {  	_currentCharacter->currentAnimFrame = 7;  	_animator->animRefreshNPC(0);  	freeShapes123(); -	_screen->setPaletteIndex(0xFE, 30, 30, 30); + +	if (_flags.platform != Common::kPlatformAmiga) +		_screen->setPaletteIndex(0xFE, 30, 30, 30); +  	_screen->showMouse();  } @@ -901,20 +993,25 @@ int KyraEngine_LoK::seq_playEnd() {  	if (_endSequenceNeedLoading) {  		snd_playWanderScoreViaMap(50, 1);  		setupPanPages(); +  		_finalA = createWSAMovie();  		assert(_finalA);  		_finalA->open("finala.wsa", 1, 0); +	  		_finalB = createWSAMovie();  		assert(_finalB);  		_finalB->open("finalb.wsa", 1, 0); +	  		_finalC = createWSAMovie();  		assert(_finalC);  		_endSequenceNeedLoading = 0;  		_finalC->open("finalc.wsa", 1, 0); +	  		_screen->_curPage = 0;  		_beadStateVar = 0;  		_malcolmFlag = 0;  		_unkEndSeqVar2 = _system->getMillis() + 600 * _tickLength; +  		_screen->copyRegion(312, 0, 312, 0, 8, 136, 0, 2);  	} @@ -943,17 +1040,25 @@ int KyraEngine_LoK::seq_playEnd() {  			_endSequenceSkipFlag = 1;  			if (_text->printed())  				_text->restoreTalkTextMessageBkgd(2, 0); +  			_screen->_curPage = 0;  			_screen->hideMouse(); -			_screen->fadeSpecialPalette(32, 228, 20, 60); + +			if (_flags.platform != Common::kPlatformAmiga) +				_screen->fadeSpecialPalette(32, 228, 20, 60); +	  			delay(60 * _tickLength); +  			_screen->loadBitmap("GEMHEAL.CPS", 3, 3, &_screen->getPalette(0));  			_screen->setScreenPalette(_screen->getPalette(0));  			_screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0); +  			uint32 nextTime = _system->getMillis() + 120 * _tickLength; -			_finalA = new WSAMovie_v1(this); + +			_finalA = createWSAMovie();  			assert(_finalA);  			_finalA->open("finald.wsa", 1, 0); +  			delayUntil(nextTime);  			snd_playSoundEffect(0x40);  			for (int i = 0; i < 22; ++i) { @@ -967,6 +1072,7 @@ int KyraEngine_LoK::seq_playEnd() {  				_screen->updateScreen();  			}  			delete _finalA; +  			_finalA = 0;  			seq_playEnding();  			return 1; @@ -985,11 +1091,13 @@ void KyraEngine_LoK::seq_brandonToStone() {  	assert(_brandonStoneTable);  	setupShapes123(_brandonStoneTable, 14, 0);  	_animator->setBrandonAnimSeqSize(5, 51); +  	for (int i = 123; i <= 136; ++i) {  		_currentCharacter->currentAnimFrame = i;  		_animator->animRefreshNPC(0);  		delayWithTicks(8);  	} +  	_animator->resetBrandonAnimSeqSize();  	freeShapes123();  	_screen->showMouse(); @@ -1001,8 +1109,17 @@ void KyraEngine_LoK::seq_playEnding() {  	_screen->hideMouse();  	_screen->_curPage = 0;  	_screen->fadeToBlack(); -	_screen->loadBitmap("REUNION.CPS", 3, 3, &_screen->getPalette(0)); -	_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + +	if (_flags.platform == Common::kPlatformAmiga) { +		_screen->loadBitmap("GEMCUT.CPS", 3, 3, &_screen->getPalette(0)); +		_screen->copyRegion(232, 136, 176, 56, 56, 56, 2, 2); +		_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); +		_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK); +	} else { +		_screen->loadBitmap("REUNION.CPS", 3, 3, &_screen->getPalette(0)); +		_screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); +	} +  	_screen->_curPage = 0;  	// XXX  	assert(_homeString); @@ -1017,28 +1134,37 @@ void KyraEngine_LoK::seq_playEnding() {  	_seqPlayerFlag = false;  	_screen->showMouse(); -	seq_playCredits(); +	if (_flags.platform == Common::kPlatformAmiga) { +		while (!shouldQuit()) +			seq_playCreditsAmiga(); +	} else { +		seq_playCredits(); +	}  } +namespace { +struct CreditsLine { +	int16 x, y; +	Screen::FontId font; +	uint8 *str; +}; +} // end of anonymous namespace +  void KyraEngine_LoK::seq_playCredits() {  	static const uint8 colorMap[] = { 0, 0, 0xC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };  	static const char stringTerms[] = { 0x5, 0xd, 0x0}; -	static const int numStrings = 250; -	struct { -		int16 x, y; -		uint8 code; -		uint8 unk1; -		Screen::FontId font; -		uint8 *str; -	} strings[numStrings]; +	typedef Common::List<CreditsLine> CreditsLineList; +	CreditsLineList lines; -	memset(strings, 0, sizeof(strings)); +	_screen->enableInterfacePalette(false);  	_screen->hideMouse(); -	if (!_flags.isTalkie) { +	if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga) {  		_screen->loadFont(Screen::FID_CRED6_FNT, "CREDIT6.FNT");  		_screen->loadFont(Screen::FID_CRED8_FNT, "CREDIT8.FNT"); + +		_screen->setFont(Screen::FID_CRED8_FNT);  	} else  		_screen->setFont(Screen::FID_8_FNT); @@ -1073,94 +1199,96 @@ void KyraEngine_LoK::seq_playCredits() {  	uint8 *currentString = buffer;  	int currentY = 200; -	for (int i = 0; i < numStrings; i++) { -		if (*nextString == 0) -			break; - +	do {  		currentString = nextString;  		nextString = (uint8 *)strpbrk((const char *)currentString, stringTerms);  		if (!nextString)  			nextString = (uint8 *)strchr((const char *)currentString, 0); -		strings[i].code = nextString[0]; +		CreditsLine line; + +		int lineEndCode = nextString[0];  		*nextString = 0; -		if (strings[i].code != 0) +		if (lineEndCode != 0)  			nextString++; +		int alignment = 0;  		if (*currentString == 3 || *currentString == 4) { -			strings[i].unk1 = *currentString; +			alignment = *currentString;  			currentString++;  		}  		if (*currentString == 1) {  			currentString++; -			if (!_flags.isTalkie) + +			if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga)  				_screen->setFont(Screen::FID_CRED6_FNT); -		} else { -			if (*currentString == 2) -				currentString++; -			if (!_flags.isTalkie) +		} else if (*currentString == 2) { +			currentString++; + +			if (!_flags.isTalkie && _flags.platform != Common::kPlatformAmiga)  				_screen->setFont(Screen::FID_CRED8_FNT);  		} -		strings[i].font = _screen->_currentFont; -		if (strings[i].unk1 == 3) -			strings[i].x = 157 - _screen->getTextWidth((const char *)currentString); -		else if (strings[i].unk1 == 4) -			strings[i].x = 161; +		line.font = _screen->_currentFont; + +		if (alignment == 3) +			line.x = 157 - _screen->getTextWidth((const char *)currentString); +		else if (alignment == 4) +			line.x = 161;  		else -			strings[i].x = (320  - _screen->getTextWidth((const char *)currentString)) / 2 + 1; +			line.x = (320  - _screen->getTextWidth((const char *)currentString)) / 2 + 1; -		strings[i].y = currentY; -		if (strings[i].code != 5) +		line.y = currentY; +		if (lineEndCode != 5)  			currentY += 10; -		strings[i].str = currentString; -	} +		line.str = currentString; + +		lines.push_back(line); +	} while (*nextString);  	_screen->setCurPage(2);  	_screen->getPalette(2).clear();  	_screen->setScreenPalette(_screen->getPalette(2)); -	_screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 0, Screen::CR_NO_P_CHECK); + +	_screen->copyRegion(0, 32, 0, 32, 320, 128, 4, 0, Screen::CR_NO_P_CHECK);  	_screen->fadePalette(_screen->getPalette(0), 0x5A); -	Common::Event event;  	bool finished = false;  	int bottom = 201; -	while (!finished) { +	while (!finished && !shouldQuit()) {  		uint32 startLoop = _system->getMillis(); +  		if (bottom > 175) { -			_screen->copyRegion(8, 32, 8, 32, 312, 128, 4, 2, Screen::CR_NO_P_CHECK); +			_screen->copyRegion(0, 32, 0, 32, 320, 128, 4, 2, Screen::CR_NO_P_CHECK);  			bottom = 0; -			for (int i = 0; i < numStrings; i++) { -				if (strings[i].y < 200 && strings[i].y > 0) { -					if (strings[i].font != _screen->_currentFont) -						_screen->setFont(strings[i].font); -					_screen->printText((const char *)strings[i].str, strings[i].x, strings[i].y, 15, 0); +			for (CreditsLineList::iterator it = lines.begin(); it != lines.end(); ++it) { +				if (it->y < 0) { +					it = lines.erase(it); +					continue;  				} -				strings[i].y--; -				if (strings[i].y > bottom) -					bottom = strings[i].y; + +				if (it->y < 200) { +					if (it->font != _screen->_currentFont) +						_screen->setFont(it->font); + +					_screen->printText((const char *)it->str, it->x, it->y, 15, 0); +				} + +				it->y--; +				if (it->y > bottom) +					bottom = it->y;  			} -			_screen->copyRegion(8, 32, 8, 32, 312, 128, 2, 0, Screen::CR_NO_P_CHECK); + +			_screen->copyRegion(0, 32, 0, 32, 320, 128, 2, 0, Screen::CR_NO_P_CHECK);  			_screen->updateScreen();  		} -		while (_eventMan->pollEvent(event)) { -			switch (event.type) { -			case Common::EVENT_KEYDOWN: -				finished = true; -				break; -			case Common::EVENT_RTL: -			case Common::EVENT_QUIT: -				finished = true; -				break; -			default: -				break; -			} -		} +		if (checkInput(0, false)) +			finished = true;  		uint32 now = _system->getMillis();  		uint32 nextLoop = startLoop + _tickLength * 5; @@ -1176,6 +1304,123 @@ void KyraEngine_LoK::seq_playCredits() {  	_screen->showMouse();  } +void KyraEngine_LoK::seq_playCreditsAmiga() { +	_screen->setFont(Screen::FID_8_FNT); + +	_screen->loadBitmap("CHALET.CPS", 4, 2, &_screen->getPalette(0)); +	_screen->copyPage(2, 0); +	_screen->setCurPage(2); + +	_screen->getPalette(2).clear(); +	_screen->setScreenPalette(_screen->getPalette(2)); + +	_screen->getPalette(0).fill(16, 1, 63); +	_screen->fadePalette(_screen->getPalette(0), 0x5A); + +	const char *theEnd = "THE END"; + +	const int width = _screen->getTextWidth(theEnd); +	int x = (320 - width) / 2 + 1; + +	_screen->copyRegion(x, 8, x, 8, width, 56, 0, 2, Screen::CR_NO_P_CHECK); +	_screen->copyRegion(x, 8, 0, 8, width, 11, 0, 2, Screen::CR_NO_P_CHECK); +	_screen->printText(theEnd, 0, 10, 31, 0); + +	for (int y = 18, h = 1; y >= 10 && !shouldQuit(); --y, ++h) { +		uint32 endTime = _system->getMillis() + 3 * _tickLength; + +		_screen->copyRegion(0, y, x, 8, width, h, 2, 0, Screen::CR_NO_P_CHECK); +		_screen->updateScreen(); + +		delayUntil(endTime); +	} + +	for (int y = 8; y <= 62 && !shouldQuit(); ++y) { +		uint32 endTime = _system->getMillis() + 3 * _tickLength; + +		_screen->copyRegion(x, y, 0, 8, width, 11, 2, 2, Screen::CR_NO_P_CHECK); +		_screen->printText(theEnd, 0, 9, 31, 0); +		_screen->copyRegion(0, 8, x, y, width, 11, 2, 0, Screen::CR_NO_P_CHECK); +		_screen->updateScreen(); + +		delayUntil(endTime); +	} + +	int size = 0; +	const uint8 *bufferTmp = _staticres->loadRawData(k1CreditsStrings, size); +	char *buffer = new char[size]; +	assert(buffer); +	memcpy(buffer, bufferTmp, size); +	_staticres->unloadId(k1CreditsStrings); + +	char stringBuffer[81]; +	memset(stringBuffer, 0, sizeof(stringBuffer)); + +	char *cur = buffer; +	char *specialString = stringBuffer; +	bool fillRectFlag = false, subWidth = false, centerFlag = false; +	x = 0; +	int specialX = 0; + +	const int fontHeight = _screen->getFontHeight(); + +	do { +		char code = *cur; + +		if (code == 3) { +			fillRectFlag = subWidth = true; +		} else if (code == 5) { +			centerFlag = true; +		} else if (code == 4) { +			if (fillRectFlag) { +				_screen->fillRect(0, 0, 319, 20, 0); + +				if (subWidth) +					specialX = 157 - _screen->getTextWidth(stringBuffer); + +				_screen->printText(stringBuffer, specialX + 8, 0, 31, 0); +			} + +			specialString = stringBuffer; +			*specialString = 0; + +			x = 161; +		} else if (code == 13) { +			if (!fillRectFlag) +				_screen->fillRect(0, 0, 319, 20, 0); + +			uint32 nextTime = _system->getMillis() + 8 * _tickLength; + +			if (centerFlag) +				x = (320 - _screen->getTextWidth(stringBuffer)) / 2 - 8; + +			_screen->printText(stringBuffer, x + 8, 0, 31, 0); + +			for (int i = 0; i < fontHeight; ++i) { +				_screen->copyRegion(0, 141, 0, 140, 320, 59, 0, 0, Screen::CR_NO_P_CHECK); +				_screen->copyRegion(0, i, 0, 198, 320, 3, 2, 0, Screen::CR_NO_P_CHECK); +				_screen->updateScreen(); + +				delayUntil(nextTime); +				nextTime = _system->getMillis() + 8 * _tickLength; +			} + +			specialString = stringBuffer; +			*specialString = 0; + +			centerFlag = fillRectFlag = false; +		} else { +			*specialString++ = code; +			*specialString = 0; +		} + +		if (checkInput(0, false)) +			break; +	} while (++cur != buffer + size && !shouldQuit()); + +	delete[] buffer; +} +  bool KyraEngine_LoK::seq_skipSequence() const {  	return shouldQuit() || _abortIntroFlag;  } diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp index 451b77cec2..28d4844d7d 100644 --- a/engines/kyra/sound_midi.cpp +++ b/engines/kyra/sound_midi.cpp @@ -658,6 +658,9 @@ void SoundMidiPC::loadSfxFile(Common::String file) {  }  void SoundMidiPC::playTrack(uint8 track) { +	if (!_musicEnabled) +		return; +  	haltTrack();  	Common::StackLock lock(_mutex); @@ -685,6 +688,9 @@ bool SoundMidiPC::isPlaying() {  }  void SoundMidiPC::playSoundEffect(uint8 track) { +	if (!_sfxEnabled) +		return; +  	Common::StackLock lock(_mutex);  	for (int i = 0; i < 3; ++i) {  		if (!_sfx[i]->isPlaying()) { diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp index f644feeb65..9877ceebc4 100644 --- a/engines/kyra/sprites_lol.cpp +++ b/engines/kyra/sprites_lol.cpp @@ -496,9 +496,8 @@ int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int  		_monsterCurBlock = block;  		if (testWallFlag(block, -1, wallFlag))  			return 1; -	} - -	_monsterCurBlock = 0; +		_monsterCurBlock = 0; +	}	  	if (!(testFlag & 2))  		return 0; @@ -1372,12 +1371,12 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {  	static const int8 walkMonsterTable1[] = { 7, -6, 5, -4, 3, -2, 1, 0 };  	static const int8 walkMonsterTable2[] = { -7, 6, -5, 4, -3, 2, -1, 0 }; -	if (++_monsterCountUnk > 10) { -		_monsterCountUnk = 0; -		_monsterShiftAlt ^= 1; +	if (++_monsterStepCounter > 10) { +		_monsterStepCounter = 0; +		_monsterStepMode ^= 1;  	} -	const int8 *tbl = _monsterShiftAlt ? walkMonsterTable2 : walkMonsterTable1; +	const int8 *tbl = _monsterStepMode ? walkMonsterTable2 : walkMonsterTable1;  	int sx = monster->x;  	int sy = monster->y; @@ -1411,8 +1410,10 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {  		uint8 w = _levelBlockProperties[_monsterCurBlock].walls[(s >> 1) ^ 2];  		if (_wllWallFlags[w] & 0x20) { -			if (_wllBuffer3[w] == 5) +			if (_wllBuffer3[w] == 5) {  				openCloseDoor(_monsterCurBlock, 1); +				return -1; +			}  		}  		if (_wllWallFlags[w] & 8) @@ -1423,10 +1424,10 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {  }  int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) { -	int8 b1x = block1 & 0x1f; -	int8 b1y = block1 >> 5; -	int8 b2x = block2 & 0x1f; -	int8 b2y = block2 >> 5; +	int b1x = block1 & 0x1f; +	int b1y = block1 >> 5; +	int b2x = block2 & 0x1f; +	int b2y = block2 >> 5;  	uint8 dy = ABS(b2y - b1y);  	uint8 dx = ABS(b2x - b1x); @@ -1434,7 +1435,7 @@ int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) {  	if (dx > dy)  		SWAP(dx, dy); -	return (dx << 1) + dy; +	return (dx >> 1) + dy;  }  int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction, int distance, uint16 curBlock) { @@ -1444,7 +1445,7 @@ int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction  		return 5;  	int dir = calcMonsterDirection(monsterBlock & 0x1f, monsterBlock >> 5, curBlock & 0x1f, curBlock >> 5); -	if ((dir & 1) || (dir != direction << 1)) +	if ((dir & 1) || (dir != (direction << 1)))  		return 5;  	if (((monsterBlock & 0x1f) != (curBlock & 0x1f)) && ((monsterBlock & 0xffe0) != (curBlock & 0xffe0))) diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 2062b9e88a..e33d24bf59 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -44,7 +44,7 @@  namespace Kyra { -#define RESFILE_VERSION 48 +#define RESFILE_VERSION 49  namespace {  bool checkKyraDat(Common::SeekableReadStream *file) { diff --git a/engines/kyra/text.cpp b/engines/kyra/text.cpp index 6965dbc985..a20e94fc1f 100644 --- a/engines/kyra/text.cpp +++ b/engines/kyra/text.cpp @@ -179,7 +179,7 @@ void TextDisplayer::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {  void TextDisplayer::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {  	if (_talkMessagePrinted) {  		_talkMessagePrinted = false; -		_screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage); +		_screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage, Screen::CR_NO_P_CHECK);  	}  } @@ -226,19 +226,25 @@ void TextDisplayer::printText(const char *str, int x, int y, uint8 c0, uint8 c1,  }  void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX) { -	uint8 colorTable[] = {0x0F, 0x09, 0xC9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};  	int top, left, x1, x2, w, x;  	char *msg; -	uint8 color = colorTable[charNum];  	text = preprocessString(text);  	int lineCount = buildMessageSubstrings(text);  	w = getWidestLineWidth(lineCount);  	x = charX;  	calcWidestLineBounds(x1, x2, w, x); -	if (_vm->gameFlags().platform == Common::kPlatformAmiga) +	uint8 color = 0; +	if (_vm->gameFlags().platform == Common::kPlatformAmiga) { +		const uint8 colorTable[] = { 0x1F, 0x1B, 0xC9, 0x80, 0x1E, 0x81, 0x11, 0xD8, 0x55, 0x3A, 0x3A }; +		color = colorTable[charNum]; +  		setTextColor(color); +	} else { +		const uint8 colorTable[] = { 0x0F, 0x09, 0xC9, 0x80, 0x05, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3A }; +		color = colorTable[charNum]; +	}  	for (int i = 0; i < lineCount; ++i) {  		top = i * 10 + _talkMessageY; diff --git a/engines/saga/displayinfo.h b/engines/saga/displayinfo.h index 092d7d4e91..b29f709323 100644 --- a/engines/saga/displayinfo.h +++ b/engines/saga/displayinfo.h @@ -281,6 +281,8 @@ static const GameDisplayInfo ITE_DisplayInfo = {  }; +#if defined(ENABLE_IHNM) || defined(ENABLE_SAGA2) +  // IHNM  #define IHNM_CONVERSE_MAX_TEXT_WIDTH (485 - 8)  #define IHNM_CONVERSE_TEXT_HEIGHT       10 @@ -361,7 +363,10 @@ static PanelButton IHNM_SavePanelButtons[] = {  	{kPanelButtonSaveText, -1,30, 0,0, kTextEnterSaveGameName,'-',0, 0,0,0},  }; +#endif +  #ifdef ENABLE_IHNM +  static const GameDisplayInfo IHNM_DisplayInfo = {  	640, 480,	// logical width&height diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 83b43542d4..6a275a9adb 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -402,12 +402,6 @@ List *lookup_list(EngineState *s, reg_t addr);  #define _K_SOUND_STATUS_PLAYING 3 - -/* Kernel optimization flags */ -#define KERNEL_OPT_FLAG_GOT_EVENT (1<<0) -#define KERNEL_OPT_FLAG_GOT_2NDEVENT (1<<1) - -  /******************** Kernel functions ********************/  // New kernel functions diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index c4b3f5d71a..5ac09e6c76 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -42,12 +42,6 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) {  	int oldx, oldy;  	int modifier_mask = s->_version <= SCI_VERSION_0 ? SCI_EVM_ALL : SCI_EVM_NO_FOOLOCK; -	if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_2NDEVENT) { -		// Penalty time- too many requests to this function without waiting! -		int delay = s->script_000->locals_block->_locals[SCI_VARIABLE_GAME_SPEED].offset; -		gfxop_sleep(s->gfx_state, delay * 1000 / 60); -	} -  	// If there's a simkey pending, and the game wants a keyboard event, use the  	// simkey instead of a normal event  	if (g_debug_simulated_key && (mask & SCI_EVT_KEYBOARD)) { @@ -71,15 +65,6 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) {  	//gfxop_set_pointer_position(s->gfx_state, Common::Point(s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y)); -	if (e.type) -		s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT); -	else { -		if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_EVENT) -			s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_2NDEVENT; -		else -			s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_EVENT; -	} -  	switch (e.type) {  	case SCI_EVT_QUIT:  		quit_vm(); diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index c7086ddef7..915b07e8a3 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -664,12 +664,13 @@ reg_t kWait(EngineState *s, int funct_nr, int argc, reg_t *argv) {  	s->r_acc = make_reg(0, ((long)time - (long)s->last_wait_time) * 60 / 1000);  	s->last_wait_time = time; -	// Reset optimization flags: Game is playing along nicely anyway -	s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT); -  	sleep_time *= g_debug_sleeptime_factor;  	GFX_ASSERT(gfxop_sleep(s->gfx_state, sleep_time * 1000 / 60)); +	// Reset speed throttler: Game is playing along nicely anyway +	if (sleep_time > 0) +		s->speedThrottler->reset(); +  	return s->r_acc;  } diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 11dd56f2aa..0341ecb73d 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -311,13 +311,15 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod  void script_debug(EngineState *s, bool bp) {  	// Do we support a separate console? -	/* if (sci_debug_flags & _DEBUG_FLAG_LOGGING) { */ +#if 0 +	if (sci_debug_flags & _DEBUG_FLAG_LOGGING) {  		printf("%d: acc=%04x:%04x  ", script_step_counter, PRINT_REG(s->r_acc));  		disassemble(s, scriptState.xs->addr.pc, 0, 1);  		if (scriptState.seeking == kDebugSeekGlobal)  			printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial,  			          scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial])); -	/* } */ +	} +#endif  #if 0  	if (!scriptState.debugging) diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 405c9ec66f..f0e9863068 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -114,9 +114,12 @@ EngineState::EngineState(ResourceManager *res, sci_version_t version, uint32 fla  	gc_countdown = 0;  	successor = 0; + +	speedThrottler = new SpeedThrottler(version);  }  EngineState::~EngineState() { +	delete speedThrottler;  }  uint16 EngineState::currentRoomNumber() const { diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 3db926ab3d..a814a20df8 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -119,6 +119,46 @@ public:  	bool isOpen() const;  }; + +class SpeedThrottler { +public: +	enum { +		kSegmentLength = 20 /**< Time segment length in ms */ +	}; + +	SpeedThrottler(sci_version_t version) { +		if (version >= SCI_VERSION_1_1) +			_maxInstructions = 3300; +		else if (version >= SCI_VERSION_1) +			_maxInstructions = 2200; +		else +			_maxInstructions = 1100; +		reset(); +	} + +	void postInstruction() { +		if (++_curInstructions >= _maxInstructions) { +			uint32 time = g_system->getMillis(); +			uint32 elapsed = time - _timestamp; + +			if (elapsed < kSegmentLength) +				g_system->delayMillis(kSegmentLength - elapsed); + +			reset(); +		} +	} + +	void reset() { +		_timestamp = g_system->getMillis(); +		_curInstructions = 0; +	} + +private: +	uint32 _timestamp; /**< Timestamp of current time segment */ +	uint32 _maxInstructions; /**< Maximum amount of instructions per time segment */ +	uint32 _curInstructions; /**< Amount of instructions executed in current time segment */ +}; +  struct EngineState : public Common::Serializable {  public:  	EngineState(ResourceManager *res, sci_version_t version, uint32 flags); @@ -258,6 +298,8 @@ public:  	MessageState _msgState; +	SpeedThrottler *speedThrottler; +  	EngineState *successor; /**< Successor of this state: Used for restoring */  private: diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 02c287a99a..ae07c314d4 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -1424,6 +1424,8 @@ void run_vm(EngineState *s, int restoring) {  		}  //#endif  		++script_step_counter; + +		s->speedThrottler->postInstruction();  	}  } diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index 3839a75261..1802d0d39c 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -687,6 +687,16 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i  					width -= 16;  				if (width <= 0)  					return; + +				// HACK: In this way we won't get a screen with dirty side strips when +				// loading a narrow room in a full screen room. +				if (width == 224 && height == 240 && x == 16) {  +					char blackbuf[16 * 240]; +					memset(blackbuf, 0, 16 * 240); // Prepare a buffer 16px wide and 240px high, to fit on a lateral strip + +					width = 240; // Fix right strip +					_system->copyRectToScreen((const byte *)blackbuf, 16, 0, 0, 16, 240); // Fix left strip +				}  			}  		} diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp index 92b72bd9be..47b25c57d1 100644 --- a/engines/scumm/he/animation_he.cpp +++ b/engines/scumm/he/animation_he.cpp @@ -23,7 +23,7 @@   *   */ - +#ifdef ENABLE_HE  #include "scumm/he/animation_he.h"  #include "scumm/he/intern_he.h" @@ -129,3 +129,5 @@ void MoviePlayer::setPalette(byte *pal) {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/animation_he.h b/engines/scumm/he/animation_he.h index e2fc1d04b7..0adba35d53 100644 --- a/engines/scumm/he/animation_he.h +++ b/engines/scumm/he/animation_he.h @@ -23,7 +23,7 @@   *   */ -#ifndef SCUMM_HE_ANIMATION_H +#if !defined(SCUMM_HE_ANIMATION_H) && defined(ENABLE_HE)  #define SCUMM_HE_ANIMATION_H  #include "common/file.h" diff --git a/engines/scumm/he/cup_player_he.cpp b/engines/scumm/he/cup_player_he.cpp index 39615edb6a..a284632fb1 100644 --- a/engines/scumm/he/cup_player_he.cpp +++ b/engines/scumm/he/cup_player_he.cpp @@ -23,6 +23,7 @@   *   */ +#ifdef ENABLE_HE  #include "common/system.h"  #include "sound/audiostream.h" @@ -521,3 +522,5 @@ void CUP_Player::handleTOIL(Common::SeekableReadStream &dataStream, uint32 dataS  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/floodfill_he.cpp b/engines/scumm/he/floodfill_he.cpp index d3578e2189..491b91c17e 100644 --- a/engines/scumm/he/floodfill_he.cpp +++ b/engines/scumm/he/floodfill_he.cpp @@ -23,7 +23,7 @@   *   */ - +#ifdef ENABLE_HE  #include "scumm/he/floodfill_he.h"  #include "scumm/he/intern_he.h" @@ -293,3 +293,5 @@ void Wiz::fillWizFlood(const WizParameters *params) {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/logic_he.cpp b/engines/scumm/he/logic_he.cpp index a24f4d4665..b7d2c9264c 100644 --- a/engines/scumm/he/logic_he.cpp +++ b/engines/scumm/he/logic_he.cpp @@ -23,7 +23,7 @@   *   */ - +#ifdef ENABLE_HE  #include "scumm/he/intern_he.h"  #include "scumm/he/logic_he.h" @@ -1058,3 +1058,5 @@ int LogicHEmoonbase::versionID() {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/logic_he.h b/engines/scumm/he/logic_he.h index 29304b7468..f5ecdd429a 100644 --- a/engines/scumm/he/logic_he.h +++ b/engines/scumm/he/logic_he.h @@ -26,8 +26,6 @@  #if !defined(SCUMM_HE_LOGIC_HE_H) && defined(ENABLE_HE)  #define SCUMM_HE_LOGIC_HE_H - -  namespace Scumm {  class ScummEngine_v90he; diff --git a/engines/scumm/he/palette_he.cpp b/engines/scumm/he/palette_he.cpp index 812c39d173..02f3f3fc5c 100644 --- a/engines/scumm/he/palette_he.cpp +++ b/engines/scumm/he/palette_he.cpp @@ -8,6 +8,7 @@   * modify it under the terms of the GNU General Public License   * as published by the Free Software Foundation; either version 2   * of the License, or (at your option) any later version. +   * This program is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the @@ -22,6 +23,7 @@   *   */ +#ifdef ENABLE_HE  #include "common/system.h"  #include "scumm/scumm.h" @@ -420,3 +422,5 @@ void ScummEngine_v99he::updatePalette() {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index 2748633bdc..49e490a8ec 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -23,6 +23,8 @@   *   */ +#ifdef ENABLE_HE +  #include "common/system.h"  #include "scumm/actor.h" @@ -3028,3 +3030,5 @@ void ScummEngine_v100he::decodeParseString(int m, int n) {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/script_v71he.cpp b/engines/scumm/he/script_v71he.cpp index c832d64316..46a8868949 100644 --- a/engines/scumm/he/script_v71he.cpp +++ b/engines/scumm/he/script_v71he.cpp @@ -23,6 +23,8 @@   *   */ +#ifdef ENABLE_HE +  #include "scumm/actor.h"  #include "scumm/he/intern_he.h"  #include "scumm/scumm.h" @@ -446,3 +448,5 @@ void ScummEngine_v71he::o71_polygonHit() {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp index c6489004d7..0c2c01d419 100644 --- a/engines/scumm/he/script_v72he.cpp +++ b/engines/scumm/he/script_v72he.cpp @@ -23,6 +23,8 @@   *   */ +#ifdef ENABLE_HE +  #include "common/config-manager.h"  #include "common/savefile.h"  #include "common/system.h" @@ -2048,3 +2050,5 @@ void ScummEngine_v72he::decodeParseString(int m, int n) {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp index fb63568e9f..dd44180fa0 100644 --- a/engines/scumm/he/script_v80he.cpp +++ b/engines/scumm/he/script_v80he.cpp @@ -23,6 +23,8 @@   *   */ +#ifdef ENABLE_HE +  #include "common/config-file.h"  #include "common/config-manager.h"  #include "common/savefile.h" @@ -529,3 +531,5 @@ void ScummEngine_v80he::o80_pickVarRandom() {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp index 8c50dfecc3..e302af1144 100644 --- a/engines/scumm/he/script_v90he.cpp +++ b/engines/scumm/he/script_v90he.cpp @@ -23,6 +23,8 @@   *   */ +#ifdef ENABLE_HE +  #include "scumm/actor.h"  #include "scumm/charset.h"  #include "scumm/he/animation_he.h" @@ -2365,3 +2367,5 @@ void ScummEngine_v90he::o90_kernelSetFunctions() {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp index 67248f4c22..01f29d5db9 100644 --- a/engines/scumm/he/sound_he.cpp +++ b/engines/scumm/he/sound_he.cpp @@ -23,7 +23,6 @@   *   */ -  #include "scumm/actor.h"  #include "scumm/file.h"  #include "scumm/imuse/imuse.h" diff --git a/engines/scumm/he/sprite_he.cpp b/engines/scumm/he/sprite_he.cpp index aed03f746b..5f751d8285 100644 --- a/engines/scumm/he/sprite_he.cpp +++ b/engines/scumm/he/sprite_he.cpp @@ -23,7 +23,7 @@   *   */ - +#ifdef ENABLE_HE  #include "scumm/he/intern_he.h"  #include "scumm/resource.h" @@ -1442,3 +1442,5 @@ void Sprite::saveOrLoadSpriteData(Serializer *s) {  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index b79c35740e..b00294cb96 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -23,7 +23,7 @@   *   */ - +#ifdef ENABLE_HE  #include "common/system.h"  #include "graphics/cursorman.h" @@ -2679,3 +2679,5 @@ int ScummEngine_v90he::computeWizHistogram(int resNum, int state, int x, int y,  }  } // End of namespace Scumm + +#endif // ENABLE_HE diff --git a/graphics/sjis.h b/graphics/sjis.h index b5d997a19a..93279d0dd5 100644 --- a/graphics/sjis.h +++ b/graphics/sjis.h @@ -24,11 +24,15 @@  // The code in this file is currently only used in KYRA and SCI.  // So if neither of those is enabled, we will skip compiling it. +// We also enable this code for ScummVM builds including support +// for dynamic engine plugins.  // If you plan to use this code in another engine, you will have  // to add the proper define check here. -// Also please add the define check at the comment after the -// matching #endif further down this file. -#if defined(ENABLE_KYRA) || defined(ENABLE_SCI) +#if !(defined(ENABLE_KYRA) || defined(ENABLE_SCI) || defined(DYNAMIC_MODULES)) + +// If neither of the above mentioned is enabled, do not include the SJIS code. + +#else  #ifndef GRAPHICS_SJIS_H  #define GRAPHICS_SJIS_H @@ -184,5 +188,5 @@ private:  #endif -#endif // defined(ENABLE_KYRA) || defined(ENABLE_SCI) +#endif // engine and dynamic plugins guard diff --git a/sound/adpcm.cpp b/sound/adpcm.cpp index 37b14140b7..5cf1171fcb 100644 --- a/sound/adpcm.cpp +++ b/sound/adpcm.cpp @@ -302,11 +302,13 @@ int ADPCMInputStream::readBufferMS(int channels, int16 *buffer, const int numSam  			for (i = 0; i < channels; i++)  				_status.ch[i].sample1 = _stream->readSint16LE(); -			for (i = 0; i < channels; i++) -				buffer[samples++] = _status.ch[i].sample2 = _stream->readSint16LE(); +			for (i = 0; i < channels; i++) { +				_status.ch[i].sample2 = _stream->readSint16LE(); +				buffer[samples++] = TO_LE_16(_status.ch[i].sample2); +			}  			for (i = 0; i < channels; i++) -				buffer[samples++] = _status.ch[i].sample1; +				buffer[samples++] = TO_LE_16(_status.ch[i].sample1);  			_blockPos = channels * 7;  		} diff --git a/tools/create_kyradat/amiga.h b/tools/create_kyradat/amiga.h index 4dbc404d28..3b3aa2d5a5 100644 --- a/tools/create_kyradat/amiga.h +++ b/tools/create_kyradat/amiga.h @@ -39,8 +39,8 @@ const ExtractEntry kyra1AmigaEng[] = {  	{ kBranStoneShapes, 0x00039C32, 0x00039CA0 },  	{ kWispJewelStrings, 0x00004A54, 0x00004AAA },  	{ kMagicJewelStrings, 0x00004AAA, 0x00004ABE }, -	{ kFlaskFullString, 0x00017B04, 0x00017B9E }, -	{ kFullFlaskString, 0x00017B9E, 0x00017BBA }, +	{ kFlaskFullString, 0x00017B9E, 0x00017BBA }, +	{ kFullFlaskString, 0x00017B04, 0x00017B9E },  	{ kOutroReunionSeq, 0x00030A4A, 0x00030F94 },  	{ kOutroHomeString, 0x0000C6FA, 0x0000C6FF },  	{ kVeryCleverString, 0x0000B322, 0x0000B354 }, diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp index 2e53efbaff..780282bab2 100644 --- a/tools/create_kyradat/create_kyradat.cpp +++ b/tools/create_kyradat/create_kyradat.cpp @@ -31,7 +31,7 @@  #include "md5.h"  enum { -	kKyraDatVersion = 48, +	kKyraDatVersion = 49,  	kIndexSize = 12  }; @@ -500,7 +500,7 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32  			if (g->special == kAmigaVersion) {  				if (i + 1 >= size)  					++entries; -				else if (!data[i+1]) +				else if (!data[i+1] && !(i & 1))  					continue;  				else  					++entries; @@ -616,7 +616,7 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32  		// we need to strip some aligment zeros out here  		int dstPos = 0;  		for (uint32 i = 0; i < size; ++i) { -			if (!data[i]) { +			if (!data[i] && !(i & 1)) {  				if (i + 1 > size)  					continue;  				else if (i + 1 < size && !data[i+1])  | 
