aboutsummaryrefslogtreecommitdiff
path: root/engines/agos
diff options
context:
space:
mode:
authorDavid Corrales2007-06-23 18:51:33 +0000
committerDavid Corrales2007-06-23 18:51:33 +0000
commitcacd7a28fd51d960947de88abbf30c487e66529d (patch)
treef3baa59853bfb307e452b86b9d93c4737b1fa6ab /engines/agos
parent0ac96302fe9c04df79cb01a77d19535b45fe2db0 (diff)
parent90c2210dae8c91fa8babc6b05564e15c9d445d18 (diff)
downloadscummvm-rg350-cacd7a28fd51d960947de88abbf30c487e66529d.tar.gz
scummvm-rg350-cacd7a28fd51d960947de88abbf30c487e66529d.tar.bz2
scummvm-rg350-cacd7a28fd51d960947de88abbf30c487e66529d.zip
Merged the FSNode branch with trunk r27031:27680
svn-id: r27681
Diffstat (limited to 'engines/agos')
-rw-r--r--engines/agos/agos.cpp145
-rw-r--r--engines/agos/agos.h190
-rw-r--r--engines/agos/animation.cpp77
-rw-r--r--engines/agos/animation.h5
-rw-r--r--engines/agos/charset.cpp273
-rw-r--r--engines/agos/cursor.cpp74
-rw-r--r--engines/agos/debugger.cpp24
-rw-r--r--engines/agos/detection.cpp9
-rw-r--r--engines/agos/detection_tables.h117
-rw-r--r--engines/agos/draw.cpp298
-rw-r--r--engines/agos/event.cpp87
-rw-r--r--engines/agos/gfx.cpp86
-rw-r--r--engines/agos/icons.cpp249
-rw-r--r--engines/agos/input.cpp44
-rw-r--r--engines/agos/intern.h8
-rw-r--r--engines/agos/items.cpp6
-rw-r--r--engines/agos/menus.cpp13
-rw-r--r--engines/agos/oracle.cpp13
-rw-r--r--engines/agos/res.cpp223
-rw-r--r--engines/agos/res_snd.cpp269
-rw-r--r--engines/agos/rooms.cpp2
-rw-r--r--engines/agos/saveload.cpp253
-rw-r--r--engines/agos/script.cpp60
-rw-r--r--engines/agos/script_e1.cpp173
-rw-r--r--engines/agos/script_e2.cpp101
-rw-r--r--engines/agos/script_ff.cpp22
-rw-r--r--engines/agos/script_pp.cpp23
-rw-r--r--engines/agos/script_s1.cpp18
-rw-r--r--engines/agos/script_s2.cpp6
-rw-r--r--engines/agos/script_ww.cpp2
-rw-r--r--engines/agos/sound.cpp72
-rw-r--r--engines/agos/string.cpp14
-rw-r--r--engines/agos/subroutine.cpp10
-rw-r--r--engines/agos/verb.cpp45
-rw-r--r--engines/agos/vga.cpp79
-rw-r--r--engines/agos/vga_e2.cpp89
-rw-r--r--engines/agos/vga_ff.cpp2
-rw-r--r--engines/agos/vga_s2.cpp10
-rw-r--r--engines/agos/vga_ww.cpp74
-rw-r--r--engines/agos/window.cpp128
-rw-r--r--engines/agos/zones.cpp2
41 files changed, 2269 insertions, 1126 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index 33737057f8..c98257f028 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -124,6 +124,10 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_tableIndexBase = 0;
_textIndexBase = 0;
+ _numMusic = 0;
+ _numSFX = 0;
+ _numSpeech = 0;
+
_numBitArray1 = 0;
_numBitArray2 = 0;
_numBitArray3 = 0;
@@ -132,6 +136,7 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_numVars = 0;
_numVideoOpcodes = 0;
_vgaBaseDelay = 0;
+ _vgaPeriod = 0;
_strippedTxtMem = 0;
_textMem = 0;
@@ -197,13 +202,10 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_litBoxFlag = 0;
_mortalFlag = 0;
_displayScreen = false;
- _updateScreen = false;
_syncFlag2 = 0;
_inCallBack = 0;
_cepeFlag = 0;
- _copyPartialMode = 0;
_fastMode = 0;
- _useBackGround = 0;
_backFlag = 0;
@@ -298,6 +300,8 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_leftButtonDown = 0;
_rightButtonDown = 0;
_clickOnly = 0;
+ _leftClick = 0;
+ _oneClick = 0;
_noRightClick = false;
_leftButton = 0;
@@ -312,7 +316,6 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_scrollUpHitArea = 0;
_scrollDownHitArea = 0;
-
_noOverWrite = 0;
_rejectBlock = false;
@@ -331,6 +334,7 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_showPreposition = 0;
_showMessageFlag = 0;
+ _newDirtyClip = false;
_copyScnFlag = 0;
_vgaSpriteChanged = 0;
@@ -348,8 +352,6 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_curSfxFile = 0;
_syncCount = 0;
- _timer5 = 0;
- _timer4 = 0;
_iconToggleCount = 0;
_voiceCount = 0;
@@ -466,6 +468,9 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_planarBuf = 0;
+ _midiEnabled = false;
+ _nativeMT32 = false;
+
_vgaTickCounter = 0;
_moviePlay = 0;
@@ -494,7 +499,6 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_noOracleScroll = 0;
_backGroundBuf = 0;
- _frontBuf = 0;
_backBuf = 0;
_scaleBuf = 0;
@@ -566,34 +570,34 @@ int AGOSEngine::init() {
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
- // Setup midi driver
- MidiDriver *driver = 0;
- if (getGameType() == GType_FF || getGameType() == GType_PP || getGameId() == GID_SIMON1CD32) {
- driver = MidiDriver::createMidi(MD_NULL);
- _native_mt32 = false;
- } else {
+ if ((getGameType() == GType_SIMON2 && getPlatform() == Common::kPlatformWindows) ||
+ (getGameType() == GType_SIMON1 && getPlatform() == Common::kPlatformWindows) ||
+ ((getFeatures() & GF_TALKIE) && getPlatform() == Common::kPlatformAcorn) ||
+ (getPlatform() == Common::kPlatformPC)) {
+
+ // Setup midi driver
int midiDriver = MidiDriver::detectMusicDriver(MDT_ADLIB | MDT_MIDI);
- _native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
- driver = MidiDriver::createMidi(midiDriver);
- if (_native_mt32) {
+ _nativeMT32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
+ MidiDriver *driver = MidiDriver::createMidi(midiDriver);
+ if (_nativeMT32) {
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
}
- }
- _midi.mapMT32toGM (getGameType() != GType_SIMON2 && !_native_mt32);
+ _midi.mapMT32toGM (getGameType() != GType_SIMON2 && !_nativeMT32);
+
+ _midi.setDriver(driver);
+ int ret = _midi.open();
+ if (ret)
+ warning("MIDI Player init failed: \"%s\"", _midi.getErrorName (ret));
- _midi.setDriver(driver);
- int ret = _midi.open();
- if (ret)
- warning("MIDI Player init failed: \"%s\"", _midi.getErrorName (ret));
- _midi.setVolume(ConfMan.getInt("music_volume"));
+ _midi.setVolume(ConfMan.getInt("music_volume"));
- if (ConfMan.hasKey("music_mute") && ConfMan.getBool("music_mute") == 1)
- _midi.pause(_musicPaused ^= 1);
+
+ _midiEnabled = true;
+ }
// allocate buffers
_backGroundBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
- _frontBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
if (getGameType() == GType_FF || getGameType() == GType_PP) {
_backBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
@@ -607,7 +611,11 @@ int AGOSEngine::init() {
} else if (getGameType() == GType_WW || getGameType() == GType_ELVIRA2) {
_window4BackScn = (byte *)calloc(224 * 127, 1);
} else if (getGameType() == GType_ELVIRA1) {
- _window4BackScn = (byte *)calloc(224 * 127, 1);
+ if (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_DEMO)) {
+ _window4BackScn = (byte *)calloc(224 * 196, 1);
+ } else {
+ _window4BackScn = (byte *)calloc(224 * 144, 1);
+ }
_window6BackScn = (byte *)calloc(48 * 80, 1);
}
@@ -618,6 +626,14 @@ int AGOSEngine::init() {
_moviePlay = new MoviePlayer(this, _mixer);
+ if (ConfMan.hasKey("music_mute") && ConfMan.getBool("music_mute") == 1) {
+ _musicPaused = true;
+ if (_midiEnabled) {
+ _midi.pause(_musicPaused);
+ }
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, 0);
+ }
+
if (ConfMan.hasKey("sfx_mute") && ConfMan.getBool("sfx_mute") == 1) {
if (getGameId() == GID_SIMON1DOS)
_midi._enable_sfx ^= 1;
@@ -693,6 +709,7 @@ void AGOSEngine_PuzzlePack::setupGame() {
_tableMemSize = 200000;
_frameCount = 1;
_vgaBaseDelay = 5;
+ _vgaPeriod = (getGameId() == GID_DIMP) ? 35 : 30;
_numBitArray1 = 128;
_numItemStore = 10;
_numTextBoxes = 40;
@@ -713,6 +730,7 @@ void AGOSEngine_Feeble::setupGame() {
_tableMemSize = 200000;
_frameCount = 1;
_vgaBaseDelay = 5;
+ _vgaPeriod = 50;
_numBitArray1 = 16;
_numBitArray2 = 16;
_numBitArray3 = 16;
@@ -736,19 +754,24 @@ void AGOSEngine_Simon2::setupGame() {
_itemMemSize = 20000;
_tableMemSize = 100000;
// Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2
- if ((getGameType() == GType_SIMON2) && _native_mt32)
+ if (getGameType() == GType_SIMON2 && _nativeMT32)
_musicIndexBase = (1128 + 612) / 4;
else
_musicIndexBase = 1128 / 4;
_soundIndexBase = 1660 / 4;
_frameCount = 1;
_vgaBaseDelay = 1;
+ _vgaPeriod = 45;
_numBitArray1 = 16;
_numBitArray2 = 16;
_numItemStore = 10;
_numTextBoxes = 20;
_numVars = 255;
+ _numMusic = 93;
+ _numSFX = 222;
+ _numSpeech = 3632;
+
AGOSEngine::setupGame();
}
@@ -768,12 +791,17 @@ void AGOSEngine_Simon1::setupGame() {
_soundIndexBase = 0;
_frameCount = 1;
_vgaBaseDelay = 1;
+ _vgaPeriod = 50;
_numBitArray1 = 16;
_numBitArray2 = 16;
_numItemStore = 10;
_numTextBoxes = 20;
_numVars = 255;
+ _numMusic = 34;
+ _numSFX = 127;
+ _numSpeech = 1996;
+
AGOSEngine::setupGame();
}
@@ -789,12 +817,15 @@ void AGOSEngine_Waxworks::setupGame() {
_tableMemSize = 50000;
_frameCount = 4;
_vgaBaseDelay = 1;
+ _vgaPeriod = 50;
_numBitArray1 = 16;
_numBitArray2 = 15;
_numItemStore = 50;
_numTextBoxes = 10;
_numVars = 255;
+ _numMusic = 9;
+
AGOSEngine::setupGame();
}
@@ -810,11 +841,14 @@ void AGOSEngine_Elvira2::setupGame() {
_tableMemSize = 100000;
_frameCount = 4;
_vgaBaseDelay = 1;
+ _vgaPeriod = 50;
_numBitArray1 = 16;
_numBitArray2 = 15;
_numItemStore = 50;
_numVars = 255;
+ _numMusic = 9;
+
AGOSEngine::setupGame();
}
@@ -830,8 +864,11 @@ void AGOSEngine_Elvira1::setupGame() {
_tableMemSize = 256000;
_frameCount = 4;
_vgaBaseDelay = 1;
+ _vgaPeriod = 50;
_numVars = 512;
+ _numMusic = 14;
+
AGOSEngine::setupGame();
}
@@ -876,7 +913,10 @@ void AGOSEngine::setupGame() {
}
AGOSEngine::~AGOSEngine() {
- delete _gameFile;
+ // Sync with AGOSEngine::shutdown()
+ // In Simon 2, this gets deleted along with _sound further down
+ if (getGameType() != GType_SIMON2)
+ delete _gameFile;
_midi.close();
@@ -892,7 +932,6 @@ AGOSEngine::~AGOSEngine() {
free(_textMem);
free(_backGroundBuf);
- free(_frontBuf);
free(_backBuf);
free(_scaleBuf);
@@ -906,7 +945,7 @@ AGOSEngine::~AGOSEngine() {
delete _dummyItem2;
delete _dummyItem3;
- delete [] _dummyWindow;
+ delete _dummyWindow;
delete [] _windowList;
delete _debugger;
@@ -925,13 +964,17 @@ void AGOSEngine::pause() {
bool music_status = _musicPaused;
_midi.pause(true);
+ _mixer->pauseAll(true);
_sound->ambientPause(true);
+
while (_pause) {
delay(1);
if (_keyPressed == 'p')
_pause = 0;
}
+
_midi.pause(music_status);
+ _mixer->pauseAll(false);
_sound->ambientPause(ambient_status);
}
@@ -982,7 +1025,7 @@ int AGOSEngine::go() {
}
if (getGameType() == GType_ELVIRA1 && getFeatures() & GF_DEMO) {
- loadMusic(0);
+ playMusic(0, 0);
}
if ((getPlatform() == Common::kPlatformAmiga || getPlatform() == Common::kPlatformMacintosh) &&
@@ -1004,18 +1047,44 @@ int AGOSEngine::go() {
}
void AGOSEngine::shutdown() {
- delete _gameFile;
+ // Sync with AGOSEngine::~AGOSEngine()
+ // In Simon 2, this gets deleted along with _sound further down
+ if (getGameType() != GType_SIMON2)
+ delete _gameFile;
_midi.close();
- free(_stringTabPtr);
- free(_itemArrayPtr);
free(_itemHeapPtr - _itemHeapCurPos);
free(_tablesHeapPtr - _tablesHeapCurPos);
- free(_tblList);
- free(_zoneBuffers);
- free(_iconFilePtr);
+
free(_gameOffsetsPtr);
+ free(_iconFilePtr);
+ free(_itemArrayPtr);
+ free(_stringTabPtr);
+ free(_strippedTxtMem);
+ free(_tblList);
+ free(_textMem);
+
+ free(_backGroundBuf);
+ free(_backBuf);
+ free(_scaleBuf);
+
+ free(_window4BackScn);
+ free(_window6BackScn);
+
+ free(_variableArray);
+ free(_variableArray2);
+
+ delete _dummyItem1;
+ delete _dummyItem2;
+ delete _dummyItem3;
+
+ delete _dummyWindow;
+ delete [] _windowList;
+
+ delete _debugger;
+ delete _moviePlay;
+ delete _sound;
_system->quit();
}
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index d51c1169cf..e487c38cc7 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -90,7 +90,8 @@ struct VgaSprite {
int16 x, y;
uint16 flags;
uint16 priority;
- uint16 windowNum, zoneNum;
+ uint16 windowNum;
+ uint16 zoneNum;
VgaSprite() { memset(this, 0, sizeof(*this)); }
};
@@ -117,8 +118,9 @@ struct AnimTable {
int16 y;
uint16 width;
uint16 height;
- uint16 window;
+ uint16 windowNum;
uint16 id;
+ uint16 zoneNum;
AnimTable() { memset(this, 0, sizeof(*this)); }
};
@@ -169,7 +171,7 @@ public:
void setupVgaOpcodes();
VgaOpcodeProc _vga_opcode_table[100];
- uint _numVideoOpcodes;
+ uint8 _numVideoOpcodes;
virtual void setupVideoOpcodes(VgaOpcodeProc *op);
@@ -187,7 +189,7 @@ public:
const char *getFileName(int type) const;
protected:
- void playSting(uint a);
+ void playSting(uint16 a);
const byte *_vcPtr; /* video code ptr */
uint16 _vc_get_out_of_code;
@@ -195,18 +197,22 @@ protected:
uint32 *_gameOffsetsPtr;
- uint _numBitArray1, _numBitArray2, _numBitArray3;
- uint _numItemStore, _numVars;
- uint _vgaBaseDelay;
+ uint8 _numMusic, _numSFX;
+ uint16 _numSpeech;
- uint _musicIndexBase;
- uint _soundIndexBase;
- uint _tableIndexBase;
- uint _textIndexBase;
+ uint8 _numBitArray1, _numBitArray2, _numBitArray3, _numItemStore;
+ uint16 _numVars;
- uint _itemMemSize;
- uint _tableMemSize;
- uint _vgaMemSize;
+ uint8 _vgaBaseDelay, _vgaPeriod;
+
+ uint16 _musicIndexBase;
+ uint16 _soundIndexBase;
+ uint16 _tableIndexBase;
+ uint16 _textIndexBase;
+
+ uint32 _itemMemSize;
+ uint32 _tableMemSize;
+ uint32 _vgaMemSize;
const GameSpecificSettings *gss;
@@ -255,9 +261,9 @@ protected:
Subroutine *_subroutineList;
uint _subroutine;
- uint _dxSurfacePitch;
+ uint16 _dxSurfacePitch;
- uint _recursionDepth;
+ uint8 _recursionDepth;
uint32 _lastVgaTick;
@@ -273,14 +279,10 @@ protected:
bool _litBoxFlag;
bool _mortalFlag;
bool _displayScreen;
- bool _updateScreen;
bool _syncFlag2;
bool _inCallBack;
bool _cepeFlag;
- byte _copyPartialMode;
bool _fastMode;
- bool _useBackGround;
-
bool _backFlag;
uint16 _debugMode;
@@ -297,9 +299,10 @@ protected:
bool _vgaVar9;
int16 _chanceModifier;
bool _restoreWindow6;
- int _scrollX, _scrollXMax, _scrollWidth;
- int _scrollY, _scrollYMax, _scrollHeight;
- int _scrollCount, _scrollFlag;
+ int16 _scrollX, _scrollXMax;
+ int16 _scrollY, _scrollYMax;
+ int16 _scrollCount, _scrollFlag;
+ uint16 _scrollWidth, _scrollHeight;
const byte *_scrollImage;
byte _boxStarHeight;
@@ -318,8 +321,8 @@ protected:
int _agosMenu;
byte _textMenu[10];
- uint _currentRoom, _superRoomNumber;
- uint _wallOn;
+ uint16 _currentRoom, _superRoomNumber;
+ uint8 _wallOn;
uint16 _hyperLink, _newLines;
uint16 _oracleMaxScrollY, _noOracleScroll;
@@ -355,8 +358,8 @@ protected:
uint16 _windowNum;
- uint _printCharCurPos, _printCharMaxPos, _printCharPixelCount;
- uint _numLettersToPrint;
+ int16 _printCharCurPos, _printCharMaxPos, _printCharPixelCount;
+ uint16 _numLettersToPrint;
uint _numTextBoxes;
@@ -381,7 +384,7 @@ protected:
byte _leftButtonDown;
byte _leftButton, _leftButtonCount, _leftButtonOld;
byte _rightButtonDown;
- bool _clickOnly;
+ bool _clickOnly, _leftClick, _oneClick;
bool _noRightClick;
Item *_dummyItem1;
@@ -412,6 +415,7 @@ protected:
bool _showPreposition;
bool _showMessageFlag;
+ bool _newDirtyClip;
uint _copyScnFlag, _vgaSpriteChanged;
byte *_block, *_blockEnd;
@@ -423,7 +427,7 @@ protected:
byte *_curVgaFile2;
byte *_curSfxFile;
- uint16 _syncCount, _timer5, _timer4;
+ uint16 _syncCount;
int16 _iconToggleCount, _voiceCount;
uint32 _lastTickCount, _thisTickCount;
@@ -439,7 +443,7 @@ protected:
int16 _baseY;
float _scale;
Common::Rect _feebleRect;
- int _scaleX, _scaleY, _scaleWidth, _scaleHeight;
+ int16 _scaleX, _scaleY, _scaleWidth, _scaleHeight;
VgaTimerEntry *_nextVgaTimerToProcess;
@@ -476,7 +480,7 @@ protected:
HitArea _hitAreas[250];
- AnimTable _screenAnim1[60];
+ AnimTable _screenAnim1[90];
VgaPointersEntry _vgaBufferPointers[450];
VgaSprite _vgaSprites[200];
VgaSleepStruct _waitEndTable[60];
@@ -499,9 +503,9 @@ protected:
byte _videoBuf1[32000];
uint16 _videoWindows[128];
- uint16 _window3Flag;
- uint16 _window4Flag;
- uint16 _window6Flag;
+ uint8 _window3Flag;
+ uint8 _window4Flag;
+ uint8 _window6Flag;
byte *_window4BackScn;
byte *_window6BackScn;
@@ -515,7 +519,8 @@ protected:
byte _lettersToPrintBuf[80];
MidiPlayer _midi;
- bool _native_mt32;
+ bool _midiEnabled;
+ bool _nativeMT32;
int _vgaTickCounter;
@@ -543,7 +548,6 @@ protected:
bool _oopsValid;
byte *_backGroundBuf;
- byte *_frontBuf;
byte *_backBuf;
byte *_scaleBuf;
@@ -567,7 +571,7 @@ protected:
void setupStringTable(byte *mem, int num);
void setupLocalStringTable(byte *mem, int num);
void readGamePcText(Common::SeekableReadStream *in);
- void readItemChildren(Common::SeekableReadStream *in, Item *item, uint tmp);
+ virtual void readItemChildren(Common::SeekableReadStream *in, Item *item, uint tmp);
void readItemFromGamePc(Common::SeekableReadStream *in, Item *item);
void loadGamePcFile();
void readGamePcFile(Common::SeekableReadStream *in);
@@ -597,7 +601,7 @@ protected:
void allocItemHeap();
void allocTablesHeap();
- Subroutine *createSubroutine(uint a);
+ Subroutine *createSubroutine(uint16 a);
void readSubroutine(Common::SeekableReadStream *in, Subroutine *sub);
SubroutineLine *createSubroutineLine(Subroutine *sub, int a);
void readSubroutineLine(Common::SeekableReadStream *in, SubroutineLine *new_table, Subroutine *sub);
@@ -628,9 +632,9 @@ protected:
uint getVarWrapper();
uint getVarOrWord();
uint getVarOrByte();
- uint readVariable(uint variable);
+ uint readVariable(uint16 variable);
void writeNextVarContents(uint16 contents);
- void writeVariable(uint variable, uint16 contents);
+ void writeVariable(uint16 variable, uint16 contents);
Item *derefItem(uint item);
Item *getNextItemPtr();
@@ -641,11 +645,11 @@ protected:
Item *actor();
void showMessageFormat(const char *s, ...);
- const byte *getStringPtrByID(uint stringId);
- const byte *getLocalStringByID(uint stringId);
+ const byte *getStringPtrByID(uint16 stringId);
+ const byte *getLocalStringByID(uint16 stringId);
uint getNextStringID();
- void addTimeEvent(uint timeout, uint subroutine_id);
+ void addTimeEvent(uint16 timeout, uint16 subroutine_id);
void delTimeEvent(TimeEvent *te);
Item *findInByClass(Item *i, int16 m);
@@ -665,8 +669,8 @@ protected:
void setItemParent(Item *item, Item *parent);
void setItemState(Item *item, int value);
- void stopAnimate(uint a);
- void stopAnimateSimon2(uint a, uint b);
+ void stopAnimate(uint16 a);
+ void stopAnimateSimon2(uint16 a, uint16 b);
void enableBox(uint hitarea);
void disableBox(uint hitarea);
@@ -729,11 +733,11 @@ protected:
void mouseOff();
void mouseOn();
- bool loadRoomItems(uint item);
+ bool loadRoomItems(uint16 item);
- virtual bool loadTablesIntoMem(uint subr_id);
- bool loadXTablesIntoMem(uint subr_id);
- void loadTextIntoMem(uint stringId);
+ virtual bool loadTablesIntoMem(uint16 subr_id);
+ bool loadXTablesIntoMem(uint16 subr_id);
+ void loadTextIntoMem(uint16 stringId);
uint loadTextFile(const char *filename, byte *dst);
Common::File *openTablesFile(const char *filename);
@@ -777,7 +781,8 @@ protected:
virtual void handleMouseMoved();
virtual void drawMousePointer();
- virtual void addArrows(WindowBlock *window);
+ void drawArrow(uint16 x, uint16 y, int8 dir);
+ virtual void addArrows(WindowBlock *window, uint8 num);
void removeArrows(WindowBlock *window, uint num);
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
@@ -801,14 +806,13 @@ protected:
void justifyStart();
void justifyOutPut(byte chr);
- void loadZone(uint zoneNum);
+ void loadZone(uint16 zoneNum);
void animate(uint16 windowNum, uint16 zoneNum, uint16 vgaSpriteId, int16 x, int16 y, uint16 palette, bool vgaScript = false);
void setImage(uint16 vga_res_id, bool vgaScript = false);
void setWindowImage(uint16 mode, uint16 vga_res_id);
void setWindowImageEx(uint16 mode, uint16 vga_res);
- void playSpeech(uint speech_id, uint vga_sprite_id);
void skipSpeech();
bool printNameOf(Item *item, uint x, uint y);
@@ -1051,9 +1055,10 @@ public:
int16 levelOf(Item *item);
int16 moreText(Item *i);
void lobjFunc(Item *i, const char *f);
- uint confirmQuit();
+ uint confirmYesOrNo(uint16 x, uint16 y);
uint continueOrQuit();
void printScroll();
+ virtual void printStats();
void synchChain(Item *i);
protected:
@@ -1082,10 +1087,10 @@ protected:
void checkScrollY(int16 y, int16 ypos);
void centreScroll();
- void clearVideoWindow(uint windowNum, uint color);
- void clearVideoBackGround(uint windowNum, uint color);
+ void clearVideoWindow(uint16 windowNum, uint16 color);
+ void clearVideoBackGround(uint16 windowNum, uint16 color);
- void setPaletteSlot(uint srcOffs, uint dstOffs);
+ void setPaletteSlot(uint16 srcOffs, uint8 dstOffs);
void checkWaitEndTable();
void startOverlayAnims();
@@ -1116,12 +1121,12 @@ protected:
void sendWindow(uint a);
- void restoreWindow(WindowBlock *window);
- void colorWindow(WindowBlock *window);
+ virtual void colorWindow(WindowBlock *window);
+ void colorBlock(WindowBlock *window, uint16 x, uint16 y, uint16 w, uint16 h);
- void restoreBlock(uint h, uint w, uint y, uint x);
+ void restoreWindow(WindowBlock *window);
+ void restoreBlock(uint16 h, uint16 w, uint16 y, uint16 x);
- byte *getFrontBuf();
byte *getBackBuf();
byte *getBackGround();
byte *getScaleBuf();
@@ -1129,9 +1134,9 @@ protected:
byte *convertImage(VC10_state *state, bool compressed);
bool decrunchFile(byte *src, byte *dst, uint32 size);
- void loadVGABeardFile(uint id);
- void loadVGAVideoFile(uint id, uint type);
- bool loadVGASoundFile(uint id, uint type);
+ void loadVGABeardFile(uint16 id);
+ void loadVGAVideoFile(uint16 id, uint8 type);
+ bool loadVGASoundFile(uint16 id, uint8 type);
int init();
int go();
@@ -1146,11 +1151,12 @@ protected:
virtual void animateSprites();
void dirtyClips();
+ void dirtyClipCheck(int16 x, int16 y, int16 w, int16 h);
void dirtyBackGround();
void restoreBackGround();
void saveBackGround(VgaSprite *vsp);
- void clearSurfaces(uint num_lines);
+ void clearSurfaces();
void displayScreen();
void dumpVideoScript(const byte *src, bool one_opcode_only);
@@ -1161,10 +1167,10 @@ protected:
void dumpSingleBitmap(int file, int image, const byte *offs, int w, int h, byte base);
void dumpBitmap(const char *filename, const byte *offs, int w, int h, int flags, const byte *palette, byte base);
- void clearBackFromTop(uint lines);
- void fillFrontFromBack(uint x, uint y, uint w, uint h);
- void fillBackGroundFromBack(uint lines);
- void fillBackFromFront(uint x, uint y, uint w, uint h);
+ void fillBackFromBackGround(uint16 height, uint16 width);
+ void fillBackFromFront();
+ void fillBackGroundFromBack();
+ void fillBackGroundFromFront();
virtual void doOutput(const byte *src, uint len);
void clsCheck(WindowBlock *window);
@@ -1184,10 +1190,13 @@ protected:
void tidyIconArray(uint i);
virtual void windowNewLine(WindowBlock *window);
+ void windowScroll(WindowBlock *window);
void windowDrawChar(WindowBlock *window, uint x, uint y, byte chr);
- void loadMusic(uint music);
- void loadModule(uint music);
+ void loadMusic(uint16 track);
+ void playModule(uint16 music);
+ virtual void playMusic(uint16 music, uint16 track);
+ void stopMusic();
void checkTimerCallback();
void delay(uint delay);
@@ -1202,12 +1211,12 @@ protected:
void fastFadeIn();
void slowFadeIn();
- void vcStopAnimation(uint file, uint sprite);
+ virtual void vcStopAnimation(uint16 zone, uint16 sprite);
+ bool confirmOverWrite(WindowBlock *window);
+ int16 matchSaveGame(const char *name, uint16 max);
void disableFileBoxes();
- virtual void listSaveGames(char *dst);
virtual void userGame(bool load);
- virtual int userGameGetKey(bool *b, char *buf, uint maxChar);
void userGameBackSpace(WindowBlock *window, int x, byte b = 0);
void fileError(WindowBlock *window, bool save_error);
@@ -1275,8 +1284,6 @@ public:
void oe1_bitSet();
void oe1_bitTest();
void oe1_zoneDisk();
- void oe1_saveUserGame();
- void oe1_loadUserGame();
void oe1_printStats();
void oe1_stopTune();
void oe1_printPlayerDamage();
@@ -1309,6 +1316,7 @@ public:
void oe2_moveDirn();
void oe2_doClass();
void oe2_pObj();
+ void oe2_loadGame();
void oe2_drawItem();
void oe2_doTable();
void oe2_pauseGame();
@@ -1347,6 +1355,7 @@ public:
void oe2_b2Zero();
void oe2_b2NotZero();
+ virtual void printStats();
protected:
typedef void (AGOSEngine_Elvira2::*OpcodeProcElvira2) ();
struct OpcodeEntryElvira2 {
@@ -1356,12 +1365,14 @@ protected:
const OpcodeEntryElvira2 *_opcodesElvira2;
+ virtual void readItemChildren(Common::SeekableReadStream *in, Item *item, uint tmp);
+
virtual bool loadGame(const char *filename, bool restartMode = false);
virtual bool saveGame(uint slot, const char *caption);
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
- virtual void addArrows(WindowBlock *window);
+ virtual void addArrows(WindowBlock *window, uint8 num);
virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr);
virtual void moveDirn(Item *i, uint x);
@@ -1370,6 +1381,10 @@ protected:
uint16 getExitState(Item *item, uint16 x, uint16 d);
void setExitState(Item *i, uint16 n, uint16 d, uint16 s);
void setSRExit(Item *i, int n, int d, uint16 s);
+
+ virtual void listSaveGames(char *dst);
+ virtual void userGame(bool load);
+ virtual int userGameGetKey(bool *b, char *buf, uint maxChar);
};
class AGOSEngine_Waxworks : public AGOSEngine_Elvira2 {
@@ -1417,10 +1432,10 @@ protected:
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
- virtual void addArrows(WindowBlock *window);
+ virtual void addArrows(WindowBlock *window, uint8 num);
virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr);
- virtual bool loadTablesIntoMem(uint subr_id);
+ virtual bool loadTablesIntoMem(uint16 subr_id);
virtual void moveDirn(Item *i, uint x);
};
@@ -1469,12 +1484,20 @@ protected:
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
- virtual void addArrows(WindowBlock *window);
+ virtual void handleMouseMoved();
+
+ virtual void addArrows(WindowBlock *window, uint8 num);
virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr);
+ virtual void playSpeech(uint16 speech_id, uint16 vga_sprite_id);
+
virtual void listSaveGames(char *dst);
virtual void userGame(bool load);
virtual int userGameGetKey(bool *b, char *buf, uint maxChar);
+
+ virtual void playMusic(uint16 music, uint16 track);
+
+ virtual void vcStopAnimation(uint16 zone, uint16 sprite);
};
class AGOSEngine_Simon2 : public AGOSEngine_Simon1 {
@@ -1511,8 +1534,10 @@ protected:
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
- virtual void addArrows(WindowBlock *window);
+ virtual void addArrows(WindowBlock *window, uint8 num);
virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr);
+
+ virtual void playSpeech(uint16 speech_id, uint16 vga_sprite_id);
};
class AGOSEngine_Feeble : public AGOSEngine_Simon2 {
@@ -1582,7 +1607,7 @@ protected:
void swapCharacterLogo();
virtual void timer_proc1();
- virtual void addArrows(WindowBlock *window);
+ virtual void addArrows(WindowBlock *window, uint8 num);
virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr);
virtual void resetVerbs();
@@ -1596,6 +1621,8 @@ protected:
virtual void drawIconArray(uint i, Item *item_ptr, int line, int classMask);
+ virtual void colorWindow(WindowBlock *window);
+
virtual void doOutput(const byte *src, uint len);
virtual void printScreenText(uint vga_sprite_id, uint color, const char *string_ptr, int16 x, int16 y, int16 width);
@@ -1649,6 +1676,7 @@ public:
void opp_sync();
void opp_saveUserGame();
void opp_loadUserGame();
+ void opp_playTune();
void opp_saveOopsPosition();
void opp_resetGameTime();
void opp_resetPVCount();
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp
index 1e1eaaf7e9..8748cff54e 100644
--- a/engines/agos/animation.cpp
+++ b/engines/agos/animation.cpp
@@ -30,6 +30,7 @@
#include "common/system.h"
#include "graphics/cursorman.h"
+#include "graphics/surface.h"
#include "agos/animation.h"
#include "agos/intern.h"
@@ -44,6 +45,8 @@ MoviePlayer::MoviePlayer(AGOSEngine *vm, Audio::Mixer *mixer)
: DXAPlayer(), _vm(vm), _mixer(mixer) {
_omniTV = false;
+ _omniTVFile = 0;
+
_leftButtonDown = false;
_rightButtonDown = false;
@@ -103,25 +106,31 @@ bool MoviePlayer::load(const char *filename) {
void MoviePlayer::playOmniTV() {
// Load OmniTV video
- if (!_fd.isOpen()) {
- _vm->_variableArray[254] = 6747;
- return;
- } else {
+ if (_fd) {
_vm->setBitFlag(42, false);
_omniTV = true;
startSound();
- return;
+ } else {
+ if (_omniTVFile) {
+ // Restore state
+ _fd = _omniTVFile;
+ _mixer->pauseHandle(_omniTVSound, false);
+
+ _vm->setBitFlag(42, false);
+ _omniTV = true;
+ } else {
+ _vm->_variableArray[254] = 6747;
+ }
}
}
void MoviePlayer::play() {
- // The OmniTV videos were not included with Amiga and Macintosh versions.
- if (_vm->getPlatform() == Common::kPlatformWindows && _vm->getBitFlag(40)) {
+ if (_vm->getBitFlag(40)) {
playOmniTV();
return;
}
- if (!_fd.isOpen()) {
+ if (!_fd) {
return;
}
@@ -132,7 +141,7 @@ void MoviePlayer::play() {
// Resolution is smaller in Amiga verison so always clear screen
if (_width == 384 && _height == 280) {
- memset(_vm->_frontBuf, 0, _vm->_screenHeight * _vm->_screenWidth);
+ _vm->clearSurfaces();
}
_ticks = _vm->_system->getMillis();
@@ -147,14 +156,15 @@ void MoviePlayer::play() {
_vm->o_killAnimate();
if (_vm->getBitFlag(41)) {
- memcpy(_vm->_backBuf, _vm->_frontBuf, _frameSize);
+ _vm->fillBackFromFront();
} else {
uint8 palette[1024];
memset(palette, 0, sizeof(palette));
- _vm->clearSurfaces(480);
+ _vm->clearSurfaces();
_vm->_system->setPalette(palette, 0, 256);
}
+ _vm->fillBackGroundFromBack();
_vm->_fastFadeOutFlag = true;
}
@@ -162,14 +172,14 @@ void MoviePlayer::startSound() {
byte *buffer;
uint32 offset, size, tag;
- tag = _fd.readUint32BE();
+ tag = _fd->readUint32BE();
if (tag == MKID_BE('WAVE')) {
- size = _fd.readUint32BE();
+ size = _fd->readUint32BE();
if (_sequenceNum) {
Common::File in;
- _fd.seek(size, SEEK_CUR);
+ _fd->seek(size, SEEK_CUR);
in.open((const char *)"audio.wav");
if (!in.isOpen()) {
@@ -186,7 +196,7 @@ void MoviePlayer::startSound() {
in.close();
} else {
buffer = (byte *)malloc(size);
- _fd.read(buffer, size);
+ _fd->read(buffer, size);
}
Common::MemoryReadStream stream(buffer, size);
@@ -197,8 +207,13 @@ void MoviePlayer::startSound() {
}
if (_bgSoundStream != NULL) {
- _mixer->stopHandle(_bgSound);
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream);
+ if (_omniTV) {
+ _mixer->stopHandle(_omniTVSound);
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_omniTVSound, _bgSoundStream);
+ } else {
+ _mixer->stopHandle(_bgSound);
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream);
+ }
}
}
@@ -207,8 +222,12 @@ void MoviePlayer::nextFrame() {
return;
if (_vm->getBitFlag(42)) {
+ // Save state
+ _omniTVFile = _fd;
+ _mixer->pauseHandle(_omniTVSound, true);
+
+ _fd = 0;
_omniTV = false;
- closeFile();
return;
}
@@ -223,6 +242,7 @@ void MoviePlayer::nextFrame() {
_frameNum++;
} else {
_omniTV = false;
+ _omniTVFile = 0;
closeFile();
_vm->_variableArray[254] = 6747;
}
@@ -230,9 +250,8 @@ void MoviePlayer::nextFrame() {
void MoviePlayer::handleNextFrame() {
decodeNextFrame();
- processFrame();
-
- _vm->_system->updateScreen();
+ if (processFrame())
+ _vm->_system->updateScreen();
_frameNum++;
Common::Event event;
@@ -285,9 +304,10 @@ void MoviePlayer::setPalette(byte *pal) {
_vm->_system->setPalette(palette, 0, 256);
}
-void MoviePlayer::processFrame() {
- copyFrameToBuffer(_vm->getFrontBuf(), (_vm->_screenWidth - _width) / 2, (_vm->_screenHeight - _height) / 2, _vm->_screenWidth);
- _vm->_system->copyRectToScreen(_vm->getFrontBuf(), _vm->_screenWidth, 0, 0, _vm->_screenWidth, _vm->_screenHeight);
+bool MoviePlayer::processFrame() {
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+ copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - _width) / 2, (_vm->_screenHeight - _height) / 2, _vm->_screenWidth);
+ _vm->_system->unlockScreen();
if ((_bgSoundStream == NULL) || ((int)(_mixer->getSoundElapsedTime(_bgSound) * _framesPerSec) / 1000 < _frameNum + 1) ||
_frameSkipped > _framesPerSec) {
@@ -309,10 +329,13 @@ void MoviePlayer::processFrame() {
while (_vm->_system->getMillis() < _ticks)
_vm->_system->delayMillis(10);
}
- } else {
- warning("dropped frame %i", _frameNum);
- _frameSkipped++;
+
+ return true;
}
+
+ warning("dropped frame %i", _frameNum);
+ _frameSkipped++;
+ return false;
}
const char * MoviePlayer::_sequenceList[90] = {
diff --git a/engines/agos/animation.h b/engines/agos/animation.h
index 07b2ebcd93..6776395ab7 100644
--- a/engines/agos/animation.h
+++ b/engines/agos/animation.h
@@ -44,6 +44,9 @@ class MoviePlayer : public Graphics::DXAPlayer {
Audio::SoundHandle _bgSound;
Audio::AudioStream *_bgSoundStream;
+ Audio::SoundHandle _omniTVSound;
+ Common::SeekableReadStream *_omniTVFile;
+
bool _omniTV;
bool _leftButtonDown;
bool _rightButtonDown;
@@ -64,7 +67,7 @@ private:
void playOmniTV();
void handleNextFrame();
- void processFrame();
+ bool processFrame();
void startSound();
};
diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp
index 40b0a84390..9a37d90c33 100644
--- a/engines/agos/charset.cpp
+++ b/engines/agos/charset.cpp
@@ -25,9 +25,13 @@
#include "common/stdafx.h"
+#include "common/system.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
+#include "graphics/surface.h"
+
namespace AGOS {
void AGOSEngine_Feeble::doOutput(const byte *src, uint len) {
@@ -539,19 +543,7 @@ void AGOSEngine::justifyOutPut(byte chr) {
doOutput(&chr, 1);
clsCheck(_textWindow);
} else if (chr == 0 || chr == ' ' || chr == 10) {
- bool fit;
-
- // Note that in FF, _printCharCurPos may be greater than
- // _printCharMaxPos. In Simon, that is probably prevented by
- // testing if _printCharCurPos == _printCharMaxPos below.
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- fit = _printCharMaxPos > _printCharCurPos + _printCharPixelCount;
- } else {
- fit = _printCharMaxPos - _printCharCurPos >= _printCharPixelCount;
- }
-
- if (fit) {
+ if (_printCharMaxPos - _printCharCurPos >= _printCharPixelCount) {
_printCharCurPos += _printCharPixelCount;
doOutput(_lettersToPrintBuf, _numLettersToPrint);
@@ -707,17 +699,48 @@ void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) {
void AGOSEngine::windowNewLine(WindowBlock *window) {
window->textColumn = 0;
- window->textColumnOffset = 0;
+ window->textColumnOffset = (getGameType() == GType_ELVIRA2) ? 4 : 0;
window->textLength = 0;
if (window->textRow == window->height) {
- // TODO
- debug(0, "Window Scroll");
+ if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 ||
+ getGameType() == GType_WW) {
+ windowScroll(window);
+ }
} else {
window->textRow++;
}
}
+void AGOSEngine::windowScroll(WindowBlock *window) {
+ _lockWord |= 0x8000;
+
+ if (window->height != 1) {
+ Graphics::Surface *screen = _system->lockScreen();
+
+ byte *src, *dst;
+ uint16 w, h;
+
+ w = window->width * 8;
+ h = (window->height -1) * 8;
+
+ dst = (byte *)screen->pixels + window->y * _screenWidth + window->x * 8;
+ src = dst + 8 * _screenWidth;
+
+ do {
+ memcpy(dst, src, w);
+ src += _screenWidth;
+ dst += _screenWidth;
+ } while (--h);
+
+ _system->unlockScreen();
+ }
+
+ colorBlock(window, window->x * 8, (window->height - 1) * 8 + window->y, window->width * 8, 8);
+
+ _lockWord &= ~0x8000;
+}
+
#ifdef PALMOS_68K
static const byte *feeble_windowFont;
static const byte *czech_simonFont;
@@ -729,6 +752,8 @@ static const byte *hebrew_simonFont;
static const byte *italian_simonFont;
static const byte *spanish_simonFont;
static const byte *english_simonFont;
+static const byte *spanish_commonFont;
+static const byte *italian_commonFont;
static const byte *french_commonFont;
static const byte *english_commonFont;
#else
@@ -1839,6 +1864,208 @@ static const byte english_simonFont[] = {
240, 240, 240, 240, 240, 240, 240, 240,
};
+static const byte spanish_commonFont[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20,
+ 0x00, 0x50, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x90, 0x00, 0x60, 0x90, 0x90, 0x68, 0x00,
+ 0x00, 0x90, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
+ 0x00, 0x90, 0x00, 0x90, 0x90, 0x90, 0x60, 0x00,
+ 0x00, 0x10, 0x28, 0x10, 0x2A, 0x44, 0x3A, 0x00,
+ 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x00,
+ 0x00, 0x20, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00,
+ 0x00, 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00,
+ 0x00, 0x70, 0x88, 0xF0, 0x88, 0x88, 0xF0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
+ 0x10, 0x20, 0x00, 0x78, 0x70, 0x40, 0x38, 0x00,
+ 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00,
+ 0x00, 0x20, 0x60, 0x20, 0x20, 0x20, 0x70, 0x00,
+ 0x00, 0x70, 0x88, 0x10, 0x20, 0x48, 0xF8, 0x00,
+ 0x00, 0x70, 0x88, 0x30, 0x08, 0x88, 0x70, 0x00,
+ 0x00, 0x10, 0x20, 0x40, 0x90, 0xF8, 0x10, 0x00,
+ 0x00, 0xF8, 0x80, 0x70, 0x08, 0x88, 0x70, 0x00,
+ 0x00, 0x70, 0x88, 0x80, 0xF0, 0x88, 0x70, 0x00,
+ 0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x00,
+ 0x00, 0x70, 0x88, 0x70, 0x88, 0x88, 0x70, 0x00,
+ 0x00, 0x70, 0x88, 0x78, 0x08, 0x88, 0x70, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00,
+ 0x20, 0x40, 0x00, 0x60, 0x90, 0x90, 0x68, 0x00,
+ 0x20, 0x40, 0x00, 0x60, 0x20, 0x28, 0x30, 0x00,
+ 0x20, 0x40, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
+ 0x20, 0x40, 0x00, 0x98, 0x90, 0x90, 0xE8, 0x00,
+ 0x00, 0x3C, 0x42, 0x04, 0x08, 0x00, 0x08, 0x00,
+ 0x28, 0x50, 0x00, 0xD8, 0x68, 0x48, 0x48, 0x00,
+ 0x20, 0x50, 0x50, 0x70, 0x50, 0x50, 0x88, 0x00,
+ 0xF0, 0x48, 0x48, 0x70, 0x48, 0x48, 0xF0, 0x00,
+ 0x30, 0x48, 0x80, 0x80, 0x80, 0x48, 0x30, 0x00,
+ 0xF0, 0x48, 0x48, 0x48, 0x48, 0x48, 0xF0, 0x00,
+ 0xF8, 0x40, 0x40, 0x70, 0x40, 0x40, 0xF8, 0x00,
+ 0xF8, 0x40, 0x40, 0x70, 0x40, 0x40, 0xE0, 0x00,
+ 0x38, 0x40, 0x80, 0x98, 0x88, 0x48, 0x30, 0x00,
+ 0xC8, 0x48, 0x48, 0x78, 0x48, 0x48, 0xC8, 0x00,
+ 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00,
+ 0x78, 0x10, 0x10, 0x10, 0x90, 0x90, 0x60, 0x00,
+ 0xC8, 0x50, 0x60, 0x40, 0x60, 0x50, 0xC8, 0x00,
+ 0xE0, 0x40, 0x40, 0x40, 0x40, 0x48, 0xF8, 0x00,
+ 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88, 0x00,
+ 0xC8, 0x48, 0x68, 0x58, 0x58, 0x48, 0xC8, 0x00,
+ 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00,
+ 0xF0, 0x48, 0x48, 0x70, 0x40, 0x40, 0xC0, 0x00,
+ 0x60, 0x90, 0x90, 0x90, 0xB0, 0x90, 0x68, 0x00,
+ 0xF0, 0x48, 0x48, 0x70, 0x50, 0x48, 0xC8, 0x00,
+ 0x70, 0x88, 0x80, 0x60, 0x10, 0x88, 0x70, 0x00,
+ 0xF8, 0xA8, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00,
+ 0x88, 0x50, 0x50, 0x50, 0x50, 0x50, 0x20, 0x00,
+ 0x88, 0x88, 0x88, 0x50, 0x50, 0x50, 0x20, 0x00,
+ 0x88, 0x88, 0x88, 0x88, 0xA8, 0xD8, 0x88, 0x00,
+ 0x88, 0x50, 0x70, 0x20, 0x70, 0x50, 0x88, 0x00,
+ 0x88, 0x48, 0x30, 0x20, 0x40, 0x80, 0xC0, 0x00,
+ 0xF8, 0x88, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00,
+ 0x00, 0x0E, 0x08, 0x08, 0x08, 0x08, 0x0E, 0x00,
+ 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00,
+ 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00,
+ 0x00, 0x20, 0x00, 0x20, 0x40, 0x88, 0x70, 0x00,
+ 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
+ 0x00, 0x90, 0x00, 0x90, 0x90, 0x90, 0x60, 0x00,
+ 0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x68, 0x00,
+ 0x40, 0x40, 0x50, 0x68, 0x48, 0x48, 0xF0, 0x00,
+ 0x00, 0x00, 0x30, 0x48, 0x40, 0x48, 0x30, 0x00,
+ 0x10, 0x10, 0x70, 0x90, 0x90, 0x90, 0x68, 0x00,
+ 0x00, 0x00, 0x70, 0x48, 0x70, 0x40, 0x38, 0x00,
+ 0x10, 0x38, 0x20, 0x70, 0x20, 0x20, 0x20, 0x40,
+ 0x00, 0x00, 0x78, 0x90, 0x90, 0x90, 0x70, 0x10,
+ 0xC0, 0x40, 0x58, 0x68, 0x48, 0x48, 0xC8, 0x00,
+ 0x20, 0x00, 0x60, 0x20, 0x20, 0x28, 0x30, 0x00,
+ 0x10, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x60,
+ 0x40, 0x40, 0x70, 0x48, 0x70, 0x50, 0xC8, 0x00,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x50, 0x60, 0x00,
+ 0x00, 0x00, 0xA8, 0xF8, 0xA8, 0xA8, 0xA8, 0x00,
+ 0x00, 0x00, 0xD8, 0x68, 0x48, 0x48, 0x48, 0x00,
+ 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x30, 0x00,
+ 0x00, 0x00, 0xF0, 0x48, 0x48, 0x70, 0x40, 0xC0,
+ 0x00, 0x00, 0x70, 0x90, 0x90, 0x70, 0x18, 0x10,
+ 0x00, 0x00, 0xD8, 0x68, 0x40, 0x40, 0xE0, 0x00,
+ 0x00, 0x00, 0x38, 0x40, 0x30, 0x08, 0x70, 0x00,
+ 0x20, 0x20, 0x70, 0x20, 0x20, 0x28, 0x30, 0x00,
+ 0x00, 0x00, 0x98, 0x90, 0x90, 0x90, 0xE8, 0x00,
+ 0x00, 0x00, 0x88, 0x88, 0x50, 0x50, 0x20, 0x00,
+ 0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xF8, 0xA8, 0x00,
+ 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00,
+ 0x00, 0x00, 0x98, 0x90, 0x90, 0x70, 0x10, 0x60,
+ 0x00, 0x00, 0x78, 0x10, 0x20, 0x40, 0x78, 0x00,
+ 0x20, 0x50, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
+ 0x00, 0x0E, 0x08, 0x30, 0x08, 0x08, 0x0E, 0x00,
+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x00, 0x70, 0x10, 0x0C, 0x10, 0x10, 0x70, 0x00,
+ 0x00, 0x14, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
+ 0x00, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00,
+};
+
+static const byte italian_commonFont[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20,
+ 0x00, 0x50, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x90, 0x00, 0x60, 0x90, 0x90, 0x68, 0x00,
+ 0x00, 0x90, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
+ 0x40, 0x20, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
+ 0x00, 0x10, 0x28, 0x10, 0x2A, 0x44, 0x3A, 0x00,
+ 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x00,
+ 0x00, 0x20, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00,
+ 0x00, 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00,
+ 0x40, 0x20, 0x00, 0x60, 0x20, 0x28, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
+ 0x10, 0x20, 0x00, 0x78, 0x70, 0x40, 0x38, 0x00,
+ 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00,
+ 0x00, 0x20, 0x60, 0x20, 0x20, 0x20, 0x70, 0x00,
+ 0x00, 0x70, 0x88, 0x10, 0x20, 0x48, 0xF8, 0x00,
+ 0x00, 0x70, 0x88, 0x30, 0x08, 0x88, 0x70, 0x00,
+ 0x00, 0x10, 0x20, 0x40, 0x90, 0xF8, 0x10, 0x00,
+ 0x00, 0xF8, 0x80, 0x70, 0x08, 0x88, 0x70, 0x00,
+ 0x00, 0x70, 0x88, 0x80, 0xF0, 0x88, 0x70, 0x00,
+ 0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x00,
+ 0x00, 0x70, 0x88, 0x70, 0x88, 0x88, 0x70, 0x00,
+ 0x00, 0x70, 0x88, 0x78, 0x08, 0x88, 0x70, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00,
+ 0x40, 0x20, 0x00, 0x60, 0x90, 0x90, 0x68, 0x00,
+ 0x40, 0x20, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
+ 0x20, 0x10, 0x00, 0x78, 0x70, 0x40, 0x38, 0x00,
+ 0x20, 0x50, 0x00, 0x78, 0x70, 0x40, 0x38, 0x00,
+ 0x00, 0x3C, 0x42, 0x04, 0x08, 0x00, 0x08, 0x00,
+ 0x20, 0x50, 0x00, 0x60, 0x20, 0x28, 0x30, 0x00,
+ 0x20, 0x50, 0x50, 0x70, 0x50, 0x50, 0x88, 0x00,
+ 0xF0, 0x48, 0x48, 0x70, 0x48, 0x48, 0xF0, 0x00,
+ 0x30, 0x48, 0x80, 0x80, 0x80, 0x48, 0x30, 0x00,
+ 0xF0, 0x48, 0x48, 0x48, 0x48, 0x48, 0xF0, 0x00,
+ 0xF8, 0x40, 0x40, 0x70, 0x40, 0x40, 0xF8, 0x00,
+ 0xF8, 0x40, 0x40, 0x70, 0x40, 0x40, 0xE0, 0x00,
+ 0x38, 0x40, 0x80, 0x98, 0x88, 0x48, 0x30, 0x00,
+ 0xC8, 0x48, 0x48, 0x78, 0x48, 0x48, 0xC8, 0x00,
+ 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00,
+ 0x78, 0x10, 0x10, 0x10, 0x90, 0x90, 0x60, 0x00,
+ 0xC8, 0x50, 0x60, 0x40, 0x60, 0x50, 0xC8, 0x00,
+ 0xE0, 0x40, 0x40, 0x40, 0x40, 0x48, 0xF8, 0x00,
+ 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88, 0x00,
+ 0xC8, 0x48, 0x68, 0x58, 0x58, 0x48, 0xC8, 0x00,
+ 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00,
+ 0xF0, 0x48, 0x48, 0x70, 0x40, 0x40, 0xC0, 0x00,
+ 0x60, 0x90, 0x90, 0x90, 0xB0, 0x90, 0x68, 0x00,
+ 0xF0, 0x48, 0x48, 0x70, 0x50, 0x48, 0xC8, 0x00,
+ 0x70, 0x88, 0x80, 0x60, 0x10, 0x88, 0x70, 0x00,
+ 0xF8, 0xA8, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00,
+ 0x88, 0x50, 0x50, 0x50, 0x50, 0x50, 0x20, 0x00,
+ 0x88, 0x88, 0x88, 0x50, 0x50, 0x50, 0x20, 0x00,
+ 0x88, 0x88, 0x88, 0x88, 0xA8, 0xD8, 0x88, 0x00,
+ 0x88, 0x50, 0x70, 0x20, 0x70, 0x50, 0x88, 0x00,
+ 0x88, 0x48, 0x30, 0x20, 0x40, 0x80, 0xC0, 0x00,
+ 0xF8, 0x88, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00,
+ 0x00, 0x0E, 0x08, 0x08, 0x08, 0x08, 0x0E, 0x00,
+ 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00,
+ 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00,
+ 0x00, 0x30, 0x48, 0x40, 0x48, 0x30, 0x10, 0x30,
+ 0x00, 0x50, 0x00, 0x60, 0x20, 0x28, 0x30, 0x00,
+ 0x20, 0x10, 0x00, 0x98, 0x90, 0x90, 0xE8, 0x00,
+ 0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x68, 0x00,
+ 0x40, 0x40, 0x50, 0x68, 0x48, 0x48, 0xF0, 0x00,
+ 0x00, 0x00, 0x30, 0x48, 0x40, 0x48, 0x30, 0x00,
+ 0x10, 0x10, 0x70, 0x90, 0x90, 0x90, 0x68, 0x00,
+ 0x00, 0x00, 0x70, 0x48, 0x70, 0x40, 0x38, 0x00,
+ 0x10, 0x38, 0x20, 0x70, 0x20, 0x20, 0x20, 0x40,
+ 0x00, 0x00, 0x78, 0x90, 0x90, 0x90, 0x70, 0x10,
+ 0xC0, 0x40, 0x58, 0x68, 0x48, 0x48, 0xC8, 0x00,
+ 0x20, 0x00, 0x60, 0x20, 0x20, 0x28, 0x30, 0x00,
+ 0x10, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x60,
+ 0x40, 0x40, 0x70, 0x48, 0x70, 0x50, 0xC8, 0x00,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x50, 0x60, 0x00,
+ 0x00, 0x00, 0xA8, 0xF8, 0xA8, 0xA8, 0xA8, 0x00,
+ 0x00, 0x00, 0xD8, 0x68, 0x48, 0x48, 0x48, 0x00,
+ 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x30, 0x00,
+ 0x00, 0x00, 0xF0, 0x48, 0x48, 0x70, 0x40, 0xC0,
+ 0x00, 0x00, 0x70, 0x90, 0x90, 0x70, 0x18, 0x10,
+ 0x00, 0x00, 0xD8, 0x68, 0x40, 0x40, 0xE0, 0x00,
+ 0x00, 0x00, 0x38, 0x40, 0x30, 0x08, 0x70, 0x00,
+ 0x20, 0x20, 0x70, 0x20, 0x20, 0x28, 0x30, 0x00,
+ 0x00, 0x00, 0x98, 0x90, 0x90, 0x90, 0xE8, 0x00,
+ 0x00, 0x00, 0x88, 0x88, 0x50, 0x50, 0x20, 0x00,
+ 0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xF8, 0xA8, 0x00,
+ 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00,
+ 0x00, 0x00, 0x98, 0x90, 0x90, 0x70, 0x10, 0x60,
+ 0x00, 0x00, 0x78, 0x10, 0x20, 0x40, 0x78, 0x00,
+ 0x20, 0x50, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
+ 0x00, 0x0E, 0x08, 0x30, 0x08, 0x08, 0x0E, 0x00,
+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x00, 0x70, 0x10, 0x0C, 0x10, 0x10, 0x70, 0x00,
+ 0x00, 0x14, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
+ 0x00, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x00,
+};
+
static const byte french_commonFont[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20,
@@ -2052,14 +2279,16 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
_lockWord |= 0x8000;
- dst = getFrontBuf() + y * _dxSurfacePitch + x + window->textColumnOffset;
+ Graphics::Surface *screen = _system->lockScreen();
if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ dst = getBackGround() + y * _dxSurfacePitch + x + window->textColumnOffset;
h = 13;
w = feebleFontSize[chr - 0x20];
src = feeble_windowFont + (chr - 0x20) * 13;
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ dst = (byte *)screen->pixels + y * _dxSurfacePitch + x + window->textColumnOffset;
h = 8;
w = 6;
@@ -2095,13 +2324,17 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
error("windowDrawChar: Unknown language %d\n", _language);
}
} else {
+ dst = (byte *)screen->pixels + y * _dxSurfacePitch + x + window->textColumnOffset;
h = 8;
w = 6;
- // TODO: Add font tables for German and Spanish
+ // TODO: Add font tables for German
switch (_language) {
case Common::ES_ESP:
- src = english_commonFont + (chr - 0x20) * 8;
+ src = spanish_commonFont + (chr - 0x20) * 8;
+ break;
+ case Common::IT_ITA:
+ src = italian_commonFont + (chr - 0x20) * 8;
break;
case Common::FR_FRA:
src = french_commonFont + (chr - 0x20) * 8;
@@ -2139,6 +2372,8 @@ void AGOSEngine::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) {
dst += _dxSurfacePitch;
} while (--h);
+ _system->unlockScreen();
+
_lockWord &= ~0x8000;
}
diff --git a/engines/agos/cursor.cpp b/engines/agos/cursor.cpp
index c43e243bf3..35bb8ea216 100644
--- a/engines/agos/cursor.cpp
+++ b/engines/agos/cursor.cpp
@@ -380,7 +380,7 @@ void AGOSEngine_PuzzlePack::handleMouseMoved() {
drawMousePointer();
}
-void AGOSEngine::handleMouseMoved() {
+void AGOSEngine_Simon1::handleMouseMoved() {
uint x;
if (_mouseHideCount) {
@@ -399,13 +399,6 @@ void AGOSEngine::handleMouseMoved() {
resetVerbs();
}
- if (_leftButton == 0) {
- if (_dragMode != 0) {
- _dragEnd = 1;
- }
- _dragCount = 0;
- }
-
if (getGameType() == GType_FF) {
if (getBitFlag(99)) { // Oracle
if (_mouse.x >= 10 && _mouse.x <= 635 && _mouse.y >= 5 && _mouse.y <= 475) {
@@ -449,7 +442,50 @@ void AGOSEngine::handleMouseMoved() {
get_out2:;
_vgaVar9 = 0;
}
- } else if (getGameType() == GType_WW) {
+ }
+
+ if (_mouse != _mouseOld)
+ _needHitAreaRecalc++;
+
+ if (_leftButtonOld == 0 && _leftButtonCount != 0) {
+ boxController(_mouse.x, _mouse.y, 3);
+ }
+ _leftButtonOld = _leftButton;
+
+ x = 0;
+ if (_lastHitArea3 == 0 && _leftButtonDown != 0) {
+ _leftButtonDown = 0;
+ x = 1;
+ } else {
+ if (_litBoxFlag == 0 && _needHitAreaRecalc == 0)
+ goto get_out;
+ }
+
+ boxController(_mouse.x, _mouse.y, x);
+ _lastHitArea3 = _lastHitArea;
+ if (x == 1 && _lastHitArea == NULL)
+ _lastHitArea3 = (HitArea *) -1;
+
+get_out:
+ _mouseOld = _mouse;
+ drawMousePointer();
+
+ _needHitAreaRecalc = 0;
+ _litBoxFlag = 0;
+}
+
+void AGOSEngine::handleMouseMoved() {
+ uint x;
+
+ if (_mouseHideCount) {
+ CursorMan.showMouse(false);
+ return;
+ }
+
+ CursorMan.showMouse(true);
+ _mouse = _eventMan->getMousePos();
+
+ if (getGameType() == GType_WW) {
if (_variableArray[51] != 0 && _mouseCursor != _variableArray[51]) {
_mouseCursor = _variableArray[51];
_needHitAreaRecalc++;
@@ -466,10 +502,20 @@ void AGOSEngine::handleMouseMoved() {
}
}
+ if (_leftClick == true) {
+ _leftClick = false;
+ if (_dragMode != 0) {
+ _dragEnd = 1;
+ } else {
+ _oneClick = true;
+ }
+ _dragCount = 0;
+ }
+
if (_mouse != _mouseOld)
_needHitAreaRecalc++;
- if (_leftButtonOld == 0 && _leftButtonCount != 0) {
+ if (_leftButtonOld == 0 && _leftButton != 0) {
_lastClickRem = 0;
boxController(_mouse.x, _mouse.y, 3);
}
@@ -493,8 +539,8 @@ void AGOSEngine::handleMouseMoved() {
}
x = 0;
- if (_lastHitArea3 == 0 && _leftButtonDown != 0) {
- _leftButtonDown = 0;
+ if (_oneClick == true) {
+ _oneClick = false;
x = 1;
} else {
if (_litBoxFlag == 0 && _needHitAreaRecalc == 0)
@@ -504,11 +550,7 @@ void AGOSEngine::handleMouseMoved() {
boxstuff:
boxController(_mouse.x, _mouse.y, x);
_lastHitArea3 = _lastHitArea;
- if (x == 1 && _lastHitArea == NULL)
- _lastHitArea3 = (HitArea *) -1;
-
get_out:
-
_mouseOld = _mouse;
drawMousePointer();
diff --git a/engines/agos/debugger.cpp b/engines/agos/debugger.cpp
index 7a455fa0f9..ce50460621 100644
--- a/engines/agos/debugger.cpp
+++ b/engines/agos/debugger.cpp
@@ -83,13 +83,17 @@ bool Debugger::Cmd_DebugLevel(int argc, const char **argv) {
bool Debugger::Cmd_PlayMusic(int argc, const char **argv) {
if (argc > 1) {
uint music = atoi(argv[1]);
- uint range = (_vm->getGameType() == GType_SIMON2) ? 93 : 34;
- if (music <= range) {
- _vm->loadMusic(music);
- if (_vm->getGameType() == GType_SIMON2)
+ if (music <= _vm->_numMusic) {
+ if (_vm->getGameType() == GType_PP) {
+ // TODO
+ } else if (_vm->getGameType() == GType_SIMON2) {
+ _vm->loadMusic(music);
_vm->_midi.startTrack(0);
+ } else {
+ _vm->playMusic(music, 0);
+ }
} else
- DebugPrintf("Music out of range (0 - %d)\n", range);
+ DebugPrintf("Music out of range (0 - %d)\n", _vm->_numMusic);
} else
DebugPrintf("Syntax: music <musicnum>\n");
@@ -99,11 +103,10 @@ bool Debugger::Cmd_PlayMusic(int argc, const char **argv) {
bool Debugger::Cmd_PlaySound(int argc, const char **argv) {
if (argc > 1) {
uint sound = atoi(argv[1]);
- uint range = (_vm->getGameType() == GType_SIMON2) ? 222 : 127;
- if (sound <= range)
+ if (sound <= _vm->_numSFX)
_vm->_sound->playEffects(sound);
else
- DebugPrintf("Sound out of range (0 - %d)\n", range);
+ DebugPrintf("Sound out of range (0 - %d)\n", _vm->_numSFX);
} else
DebugPrintf("Syntax: sound <soundnum>\n");
@@ -113,11 +116,10 @@ bool Debugger::Cmd_PlaySound(int argc, const char **argv) {
bool Debugger::Cmd_PlayVoice(int argc, const char **argv) {
if (argc > 1) {
uint voice = atoi(argv[1]);
- uint range = (_vm->getGameType() == GType_SIMON2) ? 3632 : 1996;
- if (voice <= range)
+ if (voice <= _vm->_numSpeech)
_vm->_sound->playVoice(voice);
else
- DebugPrintf("Voice out of range (0 - %d)\n", range);
+ DebugPrintf("Voice out of range (0 - %d)\n", _vm->_numSpeech);
} else
DebugPrintf("Syntax: voice <voicenum>\n");
diff --git a/engines/agos/detection.cpp b/engines/agos/detection.cpp
index dbb4c8faf1..0f5aa2768a 100644
--- a/engines/agos/detection.cpp
+++ b/engines/agos/detection.cpp
@@ -106,7 +106,7 @@ GameList Engine_AGOS_gameIDList() {
}
GameDescriptor Engine_AGOS_findGameID(const char *gameid) {
- return Common::AdvancedDetector::findGameID(gameid, detectionParams);
+ return Common::AdvancedDetector::findGameID(gameid, simonGames, obsoleteGameIDsTable);
}
GameList Engine_AGOS_detectGames(const FSList &fslist) {
@@ -117,7 +117,8 @@ PluginError Engine_AGOS_create(OSystem *syst, Engine **engine) {
assert(engine);
const char *gameid = ConfMan.get("gameid").c_str();
- //const AGOSGameDescription gd = (const AGOSGameDescription *)Common::AdvancedDetector::detectBestMatchingGame(detectionParams);
+ //Common::EncapsulatedADGameDesc encapsulatedDesc = Common::AdvancedDetector::detectBestMatchingGame(detectionParams);
+ //const AGOSGameDescription *gd = (const AGOSGameDescription *)(encapsulatedDesc.realDesc);
//if (gd == 0) {
// return kNoGameDataFoundError;
//}
@@ -154,7 +155,9 @@ REGISTER_PLUGIN(AGOS, "AGOS", "AGOS (C) Adventure Soft");
namespace AGOS {
bool AGOSEngine::initGame() {
- _gameDescription = (const AGOSGameDescription *)Common::AdvancedDetector::detectBestMatchingGame(detectionParams);
+ Common::EncapsulatedADGameDesc encapsulatedDesc = Common::AdvancedDetector::detectBestMatchingGame(detectionParams);
+ _gameDescription = (const AGOSGameDescription *)(encapsulatedDesc.realDesc);
+
return (_gameDescription != 0);
}
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index cfb795efbd..cb6123dc54 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -56,7 +56,6 @@ static const AGOSGameDescription gameDescriptions[] = {
{
{ "gameamiga", GAME_BASEFILE, "7bdaff4a118d8035047cf9b1393b3fa0", -1},
{ "icon.dat", GAME_ICONFILE, "2db931e84f1ca01f0816dddfae3f49e1", -1},
- { "start", GAME_RESTFILE, "c111be88c7f6d40e3f9b128939c1236d", -1},
{ NULL, 0, NULL, 0}
},
Common::EN_ANY,
@@ -69,6 +68,46 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_OLD_BUNDLE | GF_CRUNCHED | GF_PLANAR
},
+ // Elvira 1 - French Amiga Floppy
+ {
+ {
+ "elvira1",
+ "Floppy",
+ {
+ { "gameamiga", GAME_BASEFILE, "ab1a0798f74e71cc58a06e7e0db6f8a7", -1},
+ { "icon.dat", GAME_ICONFILE, "2db931e84f1ca01f0816dddfae3f49e1", -1},
+ { NULL, 0, NULL, 0}
+ },
+ Common::FR_FRA,
+ Common::kPlatformAmiga,
+ Common::ADGF_NO_FLAGS
+ },
+
+ GType_ELVIRA1,
+ GID_ELVIRA1,
+ GF_OLD_BUNDLE | GF_CRUNCHED | GF_PLANAR
+ },
+
+ // Elvira 1 - German Amiga Floppy
+ {
+ {
+ "elvira1",
+ "Floppy",
+ {
+ { "gameamiga", GAME_BASEFILE, "bde0334344c7b3a278ccc9a300f3085c", -1},
+ { "icon.dat", GAME_ICONFILE, "2db931e84f1ca01f0816dddfae3f49e1", -1},
+ { NULL, 0, NULL, 0}
+ },
+ Common::DE_DEU,
+ Common::kPlatformAmiga,
+ Common::ADGF_NO_FLAGS
+ },
+
+ GType_ELVIRA1,
+ GID_ELVIRA1,
+ GF_OLD_BUNDLE | GF_CRUNCHED | GF_PLANAR
+ },
+
// Elvira 1 - English Atari ST Floppy Demo
{
{
@@ -100,7 +139,6 @@ static const AGOSGameDescription gameDescriptions[] = {
{
{ "gamest", GAME_BASEFILE, "8942859018fcfb2dbed13e83d974d1ab", -1},
{ "icon.dat", GAME_ICONFILE, "2db931e84f1ca01f0816dddfae3f49e1", -1},
- { "start", GAME_RESTFILE, "cd711028e209c47b81d04141fff2587b", -1},
{ "tbllist", GAME_TBLFILE, "5b6ff494bf7e24213758598ef4ac0a8b", -1},
{ NULL, 0, NULL, 0}
},
@@ -123,7 +161,6 @@ static const AGOSGameDescription gameDescriptions[] = {
{
{ "gamest", GAME_BASEFILE, "ce2100ba71284f55ac302847d7f94747", -1},
{ "icon.dat", GAME_ICONFILE, "2db931e84f1ca01f0816dddfae3f49e1", -1},
- { "start", GAME_RESTFILE, "cd711028e209c47b81d04141fff2587b", -1},
{ "tbllist", GAME_TBLFILE, "5b6ff494bf7e24213758598ef4ac0a8b", -1},
{ NULL, 0, NULL, 0}
},
@@ -146,7 +183,6 @@ static const AGOSGameDescription gameDescriptions[] = {
{
{ "gamepc", GAME_BASEFILE, "a49e132a1f18306dd5d1ec2fe435e178", -1},
{ "icon.dat", GAME_ICONFILE, "fda48c9da7f3e72d0313e2f5f760fc45", -1},
- { "start", GAME_RESTFILE, "69fb4f12108b39ae659f108cad4d3efe", -1},
{ "tbllist", GAME_TBLFILE, "319f6b227c7822a551f57d24e70f8149", -1},
{ NULL, 0, NULL, 0}
},
@@ -160,20 +196,19 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_OLD_BUNDLE
},
- // Elvira 1 - German DOS Floppy
+ // Elvira 1 - French DOS Floppy
{
{
"elvira1",
"Floppy",
{
- { "gamepc", GAME_BASEFILE, "d0b593143e21fc150c044819df2c0b98", -1},
+ { "gamepc", GAME_BASEFILE, "9076d507d60cc454df662316438ec843", -1},
{ "icon.dat", GAME_ICONFILE, "fda48c9da7f3e72d0313e2f5f760fc45", -1},
- { "start", GAME_RESTFILE, "69fb4f12108b39ae659f108cad4d3efe", -1},
{ "tbllist", GAME_TBLFILE, "319f6b227c7822a551f57d24e70f8149", -1},
{ NULL, 0, NULL, 0}
},
- Common::DE_DEU,
+ Common::FR_FRA,
Common::kPlatformPC,
Common::ADGF_NO_FLAGS
},
@@ -183,20 +218,19 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_OLD_BUNDLE
},
- // Elvira 1 - French DOS Floppy
+ // Elvira 1 - German DOS Floppy
{
{
"elvira1",
"Floppy",
{
- { "gamepc", GAME_BASEFILE, "9076d507d60cc454df662316438ec843", -1},
+ { "gamepc", GAME_BASEFILE, "d0b593143e21fc150c044819df2c0b98", -1},
{ "icon.dat", GAME_ICONFILE, "fda48c9da7f3e72d0313e2f5f760fc45", -1},
- { "start", GAME_RESTFILE, "69fb4f12108b39ae659f108cad4d3efe", -1},
{ "tbllist", GAME_TBLFILE, "319f6b227c7822a551f57d24e70f8149", -1},
{ NULL, 0, NULL, 0}
},
- Common::FR_FRA,
+ Common::DE_DEU,
Common::kPlatformPC,
Common::ADGF_NO_FLAGS
},
@@ -256,6 +290,31 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_OLD_BUNDLE | GF_CRUNCHED | GF_PLANAR
},
+ // Elvira 2 - Italian Amiga Floppy
+ {
+ {
+ "elvira2",
+ "Floppy",
+
+ {
+ { "gameamiga", GAME_BASEFILE, "3d4e0c8da4ebd222e50de2dffed92955", -1},
+ { "icon.dat", GAME_ICONFILE, "a88b1c02e13ab04dd790ec30502c323d", -1},
+ { "menus.dat", GAME_MENUFILE, "a2fdc88a77c8bdffec6b36cbeda4d955", -1},
+ { "start", GAME_RESTFILE, "a9f876c6c66dfd011b971da3dc7b4ada", -1},
+ { "stripped.txt", GAME_STRFILE, "41c975a9c1106cb5298a0bc3df0a266e", -1},
+ { "tbllist", GAME_TBLFILE, "177f5f2640e80ef92d1421d32de06a5e", -1},
+ { NULL, 0, NULL, 0}
+ },
+ Common::IT_ITA,
+ Common::kPlatformAmiga,
+ Common::ADGF_NO_FLAGS
+ },
+
+ GType_ELVIRA2,
+ GID_ELVIRA2,
+ GF_OLD_BUNDLE | GF_CRUNCHED | GF_PLANAR
+ },
+
// Elvira 2 - English Atari ST Floppy
{
{
@@ -357,6 +416,31 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_OLD_BUNDLE
},
+ // Elvira 2 - French DOS Floppy
+ {
+ {
+ "elvira2",
+ "Floppy",
+
+ {
+ { "gamepc", GAME_BASEFILE, "4bf28ab00f5324fd938e632595742382", -1},
+ { "icon.dat", GAME_ICONFILE, "83a7278bff55c82fbb3aef92981866c9", -1},
+ { "menus.dat", GAME_MENUFILE, "a2fdc88a77c8bdffec6b36cbeda4d955", -1},
+ { "start", GAME_RESTFILE, "4d380a35ba941d03ee5084c71d20055b", -1},
+ { "stripped.txt", GAME_STRFILE, "c3a8f644551a27c8a2fec0f8070b46b7", -1},
+ { "tbllist", GAME_TBLFILE, "8252660df0edbdbc3e6377e155bbd0c5", -1},
+ { NULL, 0, NULL, 0}
+ },
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ Common::ADGF_NO_FLAGS
+ },
+
+ GType_ELVIRA2,
+ GID_ELVIRA2,
+ GF_OLD_BUNDLE
+ },
+
// Elvira 2 - German DOS Floppy
{
{
@@ -382,22 +466,22 @@ static const AGOSGameDescription gameDescriptions[] = {
GF_OLD_BUNDLE
},
- // Elvira 2 - French DOS Floppy
+ // Elvira 2 - Italian DOS Floppy
{
{
"elvira2",
"Floppy",
{
- { "gamepc", GAME_BASEFILE, "4bf28ab00f5324fd938e632595742382", -1},
+ { "gamepc", GAME_BASEFILE, "09a3f1087f2977ff462ad2417bde0a5c", -1},
{ "icon.dat", GAME_ICONFILE, "83a7278bff55c82fbb3aef92981866c9", -1},
{ "menus.dat", GAME_MENUFILE, "a2fdc88a77c8bdffec6b36cbeda4d955", -1},
- { "start", GAME_RESTFILE, "4d380a35ba941d03ee5084c71d20055b", -1},
+ { "start", GAME_RESTFILE, "016107aced82d0cc5d758a9fba716270", -1},
{ "stripped.txt", GAME_STRFILE, "c3a8f644551a27c8a2fec0f8070b46b7", -1},
{ "tbllist", GAME_TBLFILE, "8252660df0edbdbc3e6377e155bbd0c5", -1},
{ NULL, 0, NULL, 0}
},
- Common::FR_FRA,
+ Common::IT_ITA,
Common::kPlatformPC,
Common::ADGF_NO_FLAGS
},
@@ -443,7 +527,6 @@ static const AGOSGameDescription gameDescriptions[] = {
{ "icon.pkd", GAME_ICONFILE, "4822a91c18b1b2005ac17fc617f7dcbe", -1},
{ "menus.dat", GAME_MENUFILE, "3409eeb8ca8b46fc04da99de67573f5e", -1},
{ "start", GAME_RESTFILE, "b575b336e741dde1725edd4079d5ab67", -1},
- { "statelst", GAME_STATFILE, "469e98c69f00928a8366ba415d91902d", -1},
{ "stripped.txt", GAME_STRFILE, "6faaebff2786216900061eeb978f10af", -1},
{ "tbllist", GAME_TBLFILE, "95c44bfc380770a6b6dd0dfcc69e80a0", -1},
{ "xtbllist", GAME_XTBLFILE, "6c7b3db345d46349a5226f695c03e20f", -1},
diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp
index f5f7161805..bb28da73b5 100644
--- a/engines/agos/draw.cpp
+++ b/engines/agos/draw.cpp
@@ -27,22 +27,16 @@
#include "common/system.h"
+#include "graphics/surface.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
namespace AGOS {
-byte *AGOSEngine::getFrontBuf() {
- if (getGameType() != GType_PP && getGameType() != GType_FF)
- _updateScreen = true;
-
- _dxSurfacePitch = _screenWidth;
- return _frontBuf;
-}
-
byte *AGOSEngine::getBackBuf() {
_dxSurfacePitch = _screenWidth;
- return _useBackGround ? _backGroundBuf : _backBuf;
+ return _backBuf;
}
byte *AGOSEngine::getBackGround() {
@@ -166,27 +160,29 @@ void AGOSEngine::animateSprites() {
_vgaSpriteChanged++;
}
- if ((getGameType() == GType_ELVIRA1 && !_variableArray[293] ||
- getGameType() == GType_ELVIRA2 && !_variableArray[71]) &&
- _wallOn) {
+ if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) {
+ const uint8 var = (getGameType() == GType_ELVIRA1) ? 293 : 71;
+ if (_wallOn && !_variableArray[var]) {
+ _wallOn--;
- VC10_state state;
- state.srcPtr = getBackGround() + 504;
- state.height = 127;
- state.width = 14;
- state.y = 0;
- state.x = 0;
- state.palette = 0;
- state.paletteMod = 0;
- state.flags = kDFNonTrans;
+ VC10_state state;
+ state.srcPtr = getBackGround() + 3 * _screenWidth + 3 * 16;
+ state.height = state.draw_height = 127;
+ state.width = state.draw_width = 14;
+ state.y = 0;
+ state.x = 0;
+ state.palette = 0;
+ state.paletteMod = 0;
+ state.flags = kDFNonTrans;
- _windowNum = 4;
+ _windowNum = 4;
- _backFlag = 1;
- drawImage(&state);
- _backFlag = 0;
+ _backFlag = 1;
+ drawImage(&state);
+ _backFlag = 0;
- _vgaSpriteChanged++;
+ _vgaSpriteChanged++;
+ }
}
if (!_scrollFlag && !_vgaSpriteChanged) {
@@ -209,7 +205,12 @@ void AGOSEngine::animateSprites() {
restoreBackGround();
vsp = _vgaSprites;
- while (vsp->id) {
+ for (; vsp->id !=0; vsp++) {
+ if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
+ !(vsp->windowNum & 0x8000)) {
+ continue;
+ }
+
vsp->windowNum &= 0x7FFF;
vpe = &_vgaBufferPointers[vsp->zoneNum];
@@ -223,10 +224,10 @@ void AGOSEngine::animateSprites() {
saveBackGround(vsp);
drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags);
- vsp++;
}
if (getGameType() == GType_ELVIRA1 && _variableArray[293]) {
+ // Used by the Fire Wall and Ice Wall spells
debug(0, "Using special wall");
uint8 color, h, len;
@@ -256,10 +257,9 @@ void AGOSEngine::animateSprites() {
}
_window4Flag = 1;
- setMoveRect(0, 224, 0, 127);
+ setMoveRect(0, 0, 224, 127);
} else if (getGameType() == GType_ELVIRA2 && _variableArray[71] & 2) {
- debug(0, "Using special wall");
-
+ // Used by the Unholy Barrier spell
uint8 color, h, len;
byte *dst = _window4BackScn;
@@ -284,14 +284,14 @@ void AGOSEngine::animateSprites() {
while (len--) {
dst += 2;
*dst++ = color;
- dst++;
+ dst += 1;
}
dst += 448;
h--;
}
_window4Flag = 1;
- setMoveRect(0, 224, 0, 127);
+ setMoveRect(0, 0, 224, 127);
}
if (_window6Flag == 1)
@@ -304,7 +304,123 @@ void AGOSEngine::animateSprites() {
}
void AGOSEngine::dirtyClips() {
- // TODO
+ int16 x, y, w, h;
+restart:
+ _newDirtyClip = 0;
+
+ VgaSprite *vsp = _vgaSprites;
+ while (vsp->id != 0) {
+ if (vsp->windowNum & 0x8000) {
+ x = vsp->x;
+ y = vsp->y;
+ w = 1;
+ h = 1;
+
+ if (vsp->image != 0) {
+ VgaPointersEntry *vpe = &_vgaBufferPointers[vsp->zoneNum];
+ const byte *ptr = vpe->vgaFile2 + vsp->image * 8;
+ w = READ_BE_UINT16(ptr + 6) / 8;
+ h = ptr[5];
+ }
+
+ dirtyClipCheck(x, y, w, h);
+ }
+ vsp++;
+ }
+
+ AnimTable *animTable = _screenAnim1;
+ while (animTable->srcPtr != 0) {
+ if (animTable->windowNum & 0x8000) {
+ x = animTable->x + _scrollX;
+ y = animTable->y;
+ w = animTable->width * 2;
+ h = animTable->height;
+
+ dirtyClipCheck(x, y, w, h);
+ }
+ animTable++;
+ }
+
+ if (_newDirtyClip != 0)
+ goto restart;
+
+}
+
+void AGOSEngine::dirtyClipCheck(int16 x, int16 y, int16 w, int16 h) {
+ int16 width, height, tmp;
+
+ VgaSprite *vsp = _vgaSprites;
+ for (; vsp->id != 0; vsp++) {
+ if (vsp->windowNum & 0x8000)
+ continue;
+
+ if (vsp->image == 0)
+ continue;
+
+ VgaPointersEntry *vpe = &_vgaBufferPointers[vsp->zoneNum];
+ const byte *ptr = vpe->vgaFile2 + vsp->image * 8;
+ width = READ_BE_UINT16(ptr + 6) / 8;
+ height = ptr[5];
+
+ tmp = vsp->x;
+ if (tmp >= x) {
+ tmp -= w;
+ if (tmp >= x)
+ continue;
+ } else {
+ tmp += width;
+ if (tmp < x)
+ continue;
+ }
+
+ tmp = vsp->y;
+ if (tmp >= y) {
+ tmp -= h;
+ if (tmp >= y)
+ continue;
+ } else {
+ tmp += height;
+ if (tmp < y)
+ continue;
+ }
+
+ vsp->windowNum |= 0x8000;
+ _newDirtyClip = 1;
+ }
+
+ AnimTable *animTable = _screenAnim1;
+ for (; animTable->srcPtr != 0; animTable++) {
+ if (animTable->windowNum & 0x8000)
+ continue;
+
+ width = animTable->width * 2;
+ height = animTable->height;
+
+ tmp = animTable->x + _scrollX;
+ if (tmp >= x) {
+ tmp -= w;
+ if (tmp >= x)
+ continue;
+ } else {
+ tmp += width;
+ if (tmp < x)
+ continue;
+ }
+
+ tmp = animTable->y;
+ if (tmp >= y) {
+ tmp -= h;
+ if (tmp >= y)
+ continue;
+ } else {
+ tmp += height;
+ if (tmp < y)
+ continue;
+ }
+
+ animTable->windowNum |= 0x8000;
+ _newDirtyClip = 1;
+ }
}
void AGOSEngine::restoreBackGround() {
@@ -326,12 +442,11 @@ void AGOSEngine::restoreBackGround() {
animTable--;
if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
- !(animTable->window & 0x8000)) {
- //continue;
+ !(animTable->windowNum & 0x8000)) {
+ continue;
}
- animTable->window &= 0x7FFF;
- _windowNum = animTable->window;
+ _windowNum = animTable->windowNum & 0x7FFF;
VC10_state state;
state.srcPtr = animTable->srcPtr;
@@ -346,9 +461,9 @@ void AGOSEngine::restoreBackGround() {
_backFlag = 1;
drawImage(&state);
- //if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2) {
+ if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2) {
animTable->srcPtr = 0;
- //}
+ }
}
_backFlag = 0;
@@ -357,7 +472,7 @@ void AGOSEngine::restoreBackGround() {
animTable = animTableTmp = _screenAnim1;
while (animTable->srcPtr) {
- if (!(animTable->window & 8000)) {
+ if (!(animTable->windowNum & 0x8000)) {
memcpy(animTableTmp, animTable, sizeof(AnimTable));
animTableTmp++;
}
@@ -402,8 +517,12 @@ void AGOSEngine::saveBackGround(VgaSprite *vsp) {
}
animTable->height = ptr[5];
- animTable->window = vsp->windowNum;
+ animTable->windowNum = vsp->windowNum;
animTable->id = vsp->id;
+ animTable->zoneNum = vsp->zoneNum;
+
+ animTable++;
+ animTable->srcPtr = 0;
}
void AGOSEngine::displayBoxStars() {
@@ -422,10 +541,13 @@ void AGOSEngine::displayBoxStars() {
uint curHeight = (getGameType() == GType_SIMON2) ? _boxStarHeight : 134;
+
for (int i = 0; i < 5; i++) {
ha = _hitAreas;
count = ARRAYSIZE(_hitAreas);
+ Graphics::Surface *screen = _system->lockScreen();
+
do {
if (ha->id != 0 && ha->flags & kBFBoxInUse && !(ha->flags & kBFBoxDead)) {
@@ -453,7 +575,7 @@ void AGOSEngine::displayBoxStars() {
if (x_ >= 311)
continue;
- dst = getFrontBuf();
+ dst = (byte *)screen->pixels;
dst += (((_dxSurfacePitch / 4) * y_) * 4) + x_;
@@ -492,6 +614,8 @@ void AGOSEngine::displayBoxStars() {
}
} while (ha++, --count);
+ _system->unlockScreen();
+
delay(100);
setMoveRect(0, 0, 320, curHeight);
@@ -509,11 +633,7 @@ void AGOSEngine::scrollScreen() {
const byte *src;
uint x, y;
- if (getGameType() == GType_SIMON2) {
- dst = getBackGround();
- } else {
- dst = getFrontBuf();
- }
+ dst = getBackGround();
if (_scrollXMax == 0) {
uint screenSize = 8 * _screenWidth;
@@ -536,8 +656,7 @@ void AGOSEngine::scrollScreen() {
_scrollY += _scrollFlag;
vcWriteVar(250, _scrollY);
- memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight);
- memcpy(_backGroundBuf, _backBuf, _screenHeight * _scrollWidth);
+ fillBackFromBackGround(_screenHeight, _scrollWidth);
} else {
if (_scrollFlag < 0) {
memmove(dst + 8, dst, _screenWidth * _scrollHeight - 8);
@@ -565,8 +684,7 @@ void AGOSEngine::scrollScreen() {
if (getGameType() == GType_SIMON2) {
memcpy(_window4BackScn, _backGroundBuf, _scrollHeight * _screenWidth);
} else {
- memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight);
- memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth);
+ fillBackFromBackGround(_scrollHeight, _screenWidth);
}
setMoveRect(0, 0, 320, _scrollHeight);
@@ -575,49 +693,48 @@ void AGOSEngine::scrollScreen() {
}
_scrollFlag = 0;
-}
-void AGOSEngine::clearBackFromTop(uint lines) {
- memset(_backBuf, 0, lines * _screenWidth);
-}
+ if (getGameType() == GType_SIMON2) {
+ AnimTable *animTable = _screenAnim1;
+ while (animTable->srcPtr) {
+ animTable->srcPtr = 0;
+ animTable++;
+ }
-void AGOSEngine::clearSurfaces(uint num_lines) {
- memset(_backBuf, 0, num_lines * _screenWidth);
+ VgaSprite *vsp = _vgaSprites;
+ while (vsp->id) {
+ vsp->windowNum |= 0x8000;
+ vsp++;
+ }
+ }
+}
- _system->copyRectToScreen(_backBuf, _screenWidth, 0, 0, _screenWidth, num_lines);
+void AGOSEngine::clearSurfaces() {
+ _system->clearScreen();
- if (_useBackGround) {
- memset(_frontBuf, 0, num_lines * _screenWidth);
- memset(_backGroundBuf, 0, num_lines * _screenWidth);
+ if (_backBuf) {
+ memset(_backBuf, 0, _screenHeight * _screenWidth);
}
}
-void AGOSEngine::fillFrontFromBack(uint x, uint y, uint w, uint h) {
- uint offs = x + y * _screenWidth;
- byte *s = _backBuf + offs;
- byte *d = _frontBuf + offs;
-
- do {
- memcpy(d, s, w);
- d += _screenWidth;
- s += _screenWidth;
- } while (--h);
+void AGOSEngine::fillBackFromBackGround(uint16 height, uint16 width) {
+ memcpy(_backBuf, _backGroundBuf, height * width);
}
-void AGOSEngine::fillBackFromFront(uint x, uint y, uint w, uint h) {
- uint offs = x + y * _screenWidth;
- byte *s = _frontBuf + offs;
- byte *d = _backBuf + offs;
+void AGOSEngine::fillBackFromFront() {
+ Graphics::Surface *screen = _system->lockScreen();
+ memcpy(_backBuf, (byte *)screen->pixels, _screenHeight * _screenWidth);
+ _system->unlockScreen();
+}
- do {
- memcpy(d, s, w);
- d += _screenWidth;
- s += _screenWidth;
- } while (--h);
+void AGOSEngine::fillBackGroundFromBack() {
+ memcpy(_backGroundBuf, _backBuf, _screenHeight * _screenWidth);
}
-void AGOSEngine::fillBackGroundFromBack(uint lines) {
- memcpy(_backGroundBuf, _backBuf, lines * _screenWidth);
+void AGOSEngine::fillBackGroundFromFront() {
+ Graphics::Surface *screen = _system->lockScreen();
+ memcpy(_backGroundBuf, (byte *)screen->pixels, _screenHeight * _screenWidth);
+ _system->unlockScreen();
}
void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) {
@@ -643,18 +760,18 @@ void AGOSEngine::displayScreen() {
}
}
+ Graphics::Surface *screen = _system->lockScreen();
if (getGameType() == GType_PP || getGameType() == GType_FF) {
- _system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
- _system->updateScreen();
+ memcpy((byte *)screen->pixels, getBackBuf(), _screenWidth * _screenHeight);
if (getGameId() != GID_DIMP)
- memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight);
+ fillBackFromBackGround(_screenHeight, _screenWidth);
} else {
if (_window4Flag == 2) {
_window4Flag = 0;
uint16 srcWidth, width, height;
- byte *dst = getFrontBuf();
+ byte *dst = (byte *)screen->pixels;
const byte *src = _window4BackScn;
if (_window3Flag == 1) {
@@ -688,18 +805,17 @@ void AGOSEngine::displayScreen() {
_window6Flag = 0;
byte *src = _window6BackScn;
- byte *dst = getFrontBuf() + 16320;
+ byte *dst = (byte *)screen->pixels + 16320;
for (int i = 0; i < 80; i++) {
memcpy(dst, src, 48);
dst += _screenWidth;
src += 48;
}
}
-
- _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
- _system->updateScreen();
}
+ _system->unlockScreen();
+
if (getGameType() == GType_FF && _scrollFlag) {
scrollScreen();
}
diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp
index 8570859bb8..32329f34d9 100644
--- a/engines/agos/event.cpp
+++ b/engines/agos/event.cpp
@@ -34,11 +34,13 @@
#include "gui/about.h"
+#include "graphics/surface.h"
+
#include "sound/audiocd.h"
namespace AGOS {
-void AGOSEngine::addTimeEvent(uint timeout, uint subroutine_id) {
+void AGOSEngine::addTimeEvent(uint16 timeout, uint16 subroutine_id) {
TimeEvent *te = (TimeEvent *)malloc(sizeof(TimeEvent)), *first, *last = NULL;
time_t cur_time;
@@ -366,13 +368,17 @@ static const byte _image4[32] = {
void AGOSEngine::drawStuff(const byte *src, uint xoffs) {
const uint8 y = (getPlatform() == Common::kPlatformAtariST) ? 132 : 135;
- byte *dst = getFrontBuf() + y * _screenWidth + xoffs;
+
+ Graphics::Surface *screen = _system->lockScreen();
+ byte *dst = (byte *)screen->pixels + y * _screenWidth + xoffs;
for (uint h = 0; h < 6; h++) {
memcpy(dst, src, 4);
src += 4;
dst += _screenWidth;
}
+
+ _system->unlockScreen();
}
void AGOSEngine::imageEvent2(VgaTimerEntry * vte, uint dx) {
@@ -424,28 +430,27 @@ void AGOSEngine::delay(uint amount) {
uint32 start = _system->getMillis();
uint32 cur = start;
- uint this_delay, vga_period;
+ uint this_delay, vgaPeriod;
AudioCD.updateCD();
if (_debugger->isAttached())
_debugger->onFrame();
- if (_fastMode)
- vga_period = 10;
- else if (getGameType() == GType_SIMON2)
- vga_period = 45;
- else
- vga_period = 50;
+ vgaPeriod = (_fastMode) ? 10 : _vgaPeriod;
+ if (getGameType() == GType_PP && getGameId() != GID_DIMP) {
+ if (vgaPeriod == 15 && _variableArray[999] == 0)
+ vgaPeriod = 30;
+ }
_rnd.getRandomNumber(2);
do {
- while (!_inCallBack && cur >= _lastVgaTick + vga_period && !_pause) {
- _lastVgaTick += vga_period;
+ while (!_inCallBack && cur >= _lastVgaTick + vgaPeriod && !_pause) {
+ _lastVgaTick += vgaPeriod;
// don't get too many frames behind
- if (cur >= _lastVgaTick + vga_period * 2)
+ if (cur >= _lastVgaTick + vgaPeriod * 2)
_lastVgaTick = cur;
_inCallBack = true;
@@ -456,15 +461,16 @@ void AGOSEngine::delay(uint amount) {
while (_eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode >= '0' && event.kbd.keycode <='9'
+ if (event.kbd.keycode >= Common::KEYCODE_0 && event.kbd.keycode <= Common::KEYCODE_9
&& (event.kbd.flags == Common::KBD_ALT ||
event.kbd.flags == Common::KBD_CTRL)) {
- _saveLoadSlot = event.kbd.keycode - '0';
+ _saveLoadSlot = event.kbd.keycode - Common::KEYCODE_0;
// There is no save slot 0
if (_saveLoadSlot == 0)
_saveLoadSlot = 10;
+ memset(_saveLoadName, 0, sizeof(_saveLoadName));
sprintf(_saveLoadName, "Quick %d", _saveLoadSlot);
_saveLoadType = (event.kbd.flags == Common::KBD_ALT) ? 1 : 2;
@@ -473,14 +479,17 @@ void AGOSEngine::delay(uint amount) {
if (!_mouseHideCount && !_showPreposition)
quickLoadOrSave();
} else if (event.kbd.flags == Common::KBD_CTRL) {
- if (event.kbd.keycode == 'a') {
+ if (event.kbd.keycode == Common::KEYCODE_a) {
GUI::Dialog *_aboutDialog;
_aboutDialog = new GUI::AboutDialog();
_aboutDialog->runModal();
- } else if (event.kbd.keycode == 'f')
+ } else if (event.kbd.keycode == Common::KEYCODE_f) {
_fastMode ^= 1;
- else if (event.kbd.keycode == 'd')
+ } else if (event.kbd.keycode == Common::KEYCODE_d) {
_debugger->attach();
+ } else if (event.kbd.keycode == Common::KEYCODE_u) {
+ dumpAllSubroutines();
+ }
}
if (getGameType() == GType_PP) {
@@ -491,7 +500,7 @@ void AGOSEngine::delay(uint amount) {
}
// Make sure backspace works right (this fixes a small issue on OS X)
- if (event.kbd.keycode == 8)
+ if (event.kbd.keycode == Common::KEYCODE_BACKSPACE)
_keyPressed = 8;
else
_keyPressed = (byte)event.kbd.ascii;
@@ -510,6 +519,7 @@ void AGOSEngine::delay(uint amount) {
_leftButton = 0;
_leftButtonCount = 0;
+ _leftClick = true;
break;
case Common::EVENT_RBUTTONDOWN:
if (getGameType() == GType_FF)
@@ -544,32 +554,17 @@ void AGOSEngine::delay(uint amount) {
}
void AGOSEngine::timer_callback() {
- // FIXME: _timer5 is never set
- if (_timer5) {
- _syncFlag2 = true;
- _timer5--;
- } else {
- if (getGameId() == GID_DIMP) {
- _thisTickCount = _system->getMillis();
- if (_thisTickCount < _lastTickCount)
- _lastTickCount = 0;
-
- if ((_thisTickCount - _lastTickCount) <= 35)
- return;
-
- _lastTickCount = _thisTickCount;
+ if (getGameId() == GID_DIMP) {
+ _lastTickCount = _system->getMillis();
- timer_proc1();
- dimp_idle();
- } else {
- timer_proc1();
- }
+ timer_proc1();
+ dimp_idle();
+ } else {
+ timer_proc1();
}
}
void AGOSEngine_Feeble::timer_proc1() {
- _timer4++;
-
if (_lockWord & 0x80E9 || _lockWord & 2)
return;
@@ -598,11 +593,6 @@ void AGOSEngine_Feeble::timer_proc1() {
animateSprites();
}
- if (_copyPartialMode == 2) {
- fillFrontFromBack(0, 0, _screenWidth, _screenHeight);
- _copyPartialMode = 0;
- }
-
if (_displayScreen) {
if (getGameType() == GType_FF) {
if (!getBitFlag(78)) {
@@ -621,8 +611,6 @@ void AGOSEngine_Feeble::timer_proc1() {
}
void AGOSEngine::timer_proc1() {
- _timer4++;
-
if (_lockWord & 0x80E9 || _lockWord & 2)
return;
@@ -640,13 +628,6 @@ void AGOSEngine::timer_proc1() {
processVgaEvents();
}
- if (_updateScreen) {
- _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
- _system->updateScreen();
-
- _updateScreen = false;
- }
-
if (_displayScreen) {
displayScreen();
_displayScreen = false;
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index 6486cc8ca7..2b530fdcd6 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -25,6 +25,10 @@
#include "common/stdafx.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
#include "agos/vga.h"
@@ -289,6 +293,9 @@ void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scro
}
void AGOSEngine_Feeble::drawImage(VC10_state *state) {
+ state->surf_addr = getBackBuf();
+ state->surf_pitch = _dxSurfacePitch;
+
if (state->flags & kDFCompressed) {
if (state->flags & kDFScaled) {
state->surf_addr = getScaleBuf();
@@ -357,8 +364,9 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) {
scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scaleY + _scrollY);
}
} else {
- if (!drawImage_clip(state))
+ if (!drawImage_clip(state)) {
return;
+ }
state->surf_addr += state->x + state->y * state->surf_pitch;
@@ -373,14 +381,18 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) {
if (state->flags & kDFMasked) {
if (getGameType() == GType_FF && !getBitFlag(81)) {
- if (state->x > _feebleRect.right)
+ if (state->x > _feebleRect.right) {
return;
- if (state->y > _feebleRect.bottom)
+ }
+ if (state->y > _feebleRect.bottom) {
return;
- if (state->x + state->width < _feebleRect.left)
+ }
+ if (state->x + state->width < _feebleRect.left) {
return;
- if (state->y + state->height < _feebleRect.top)
+ }
+ if (state->y + state->height < _feebleRect.top) {
return;
+ }
}
dstPtr = state->surf_addr;
@@ -423,8 +435,9 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) {
}
}
} else {
- if (!drawImage_clip(state))
+ if (!drawImage_clip(state)) {
return;
+ }
state->surf_addr += state->x + state->y * state->surf_pitch;
@@ -448,7 +461,7 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) {
dst += _screenWidth;
src += state->width;
} while (--state->draw_height);
- }
+ }
}
void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) {
@@ -629,6 +642,8 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
if (!drawImage_clip(state))
return;
+ Graphics::Surface *screen = _system->lockScreen();
+
if (getFeatures() & GF_32COLOR)
state->palette = 0xC0;
@@ -663,7 +678,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
_window4Flag = 1;
} else {
- state->surf_addr = getFrontBuf();
+ state->surf_addr = (byte *)screen->pixels;
state->surf_pitch = _screenWidth;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -697,7 +712,7 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
state->surf2_addr = getBackGround();
state->surf2_pitch = _screenWidth;
- state->surf_addr = getFrontBuf();
+ state->surf_addr = (byte *)screen->pixels;
state->surf_pitch = _screenWidth;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -717,6 +732,8 @@ void AGOSEngine_Simon1::drawImage(VC10_state *state) {
} else {
drawVertImage(state);
}
+
+ _system->unlockScreen();
}
void AGOSEngine::drawBackGroundImage(VC10_state *state) {
@@ -812,6 +829,8 @@ void AGOSEngine::drawImage(VC10_state *state) {
if (!drawImage_clip(state))
return;
+ Graphics::Surface *screen = _system->lockScreen();
+
uint16 xoffs, yoffs;
if (getGameType() == GType_WW) {
if (_windowNum == 4 || (_windowNum >= 10 && _windowNum <= 27)) {
@@ -827,7 +846,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
_window4Flag = 1;
} else {
- state->surf_addr = getFrontBuf();
+ state->surf_addr = (byte *)screen->pixels;
state->surf_pitch = _screenWidth;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -847,7 +866,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
_window4Flag = 1;
} else {
- state->surf_addr = getFrontBuf();
+ state->surf_addr = (byte *)screen->pixels;
state->surf_pitch = _screenWidth;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -861,7 +880,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
xoffs = state->x * 8;
yoffs = state->y;
} else if (_windowNum == 2 || _windowNum == 3) {
- state->surf_addr = getFrontBuf();
+ state->surf_addr = (byte *)screen->pixels;
state->surf_pitch = _screenWidth;
xoffs = (vlut[0] * 2 + state->x) * 8;
@@ -894,6 +913,8 @@ void AGOSEngine::drawImage(VC10_state *state) {
} else {
drawVertImage(state);
}
+
+ _system->unlockScreen();
}
void AGOSEngine::horizontalScroll(VC10_state *state) {
@@ -1008,11 +1029,7 @@ void AGOSEngine::animate(uint16 windowNum, uint16 zoneNum, uint16 vgaSpriteId, i
else
vsp->palette = palette;
vsp->id = vgaSpriteId;
-
- if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP)
- vsp->zoneNum = zoneNum;
- else
- vsp->zoneNum = zoneNum = vgaSpriteId / 100;
+ vsp->zoneNum = zoneNum;
for (;;) {
vpe = &_vgaBufferPointers[zoneNum];
@@ -1255,14 +1272,14 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
_windowNum = updateWindow = mode;
_lockWord |= 0x20;
- VgaTimerEntry *vte = _vgaTimerList;
- while (vte->type != 2)
- vte++;
-
- vte->delay = 2;
-
if (getGameType() == GType_FF || getGameType() == GType_PP) {
vc27_resetSprite();
+ } else {
+ VgaTimerEntry *vte = _vgaTimerList;
+ while (vte->type != ANIMATE_INT)
+ vte++;
+
+ vte->delay = 2;
}
if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) {
@@ -1284,8 +1301,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
setImage(vga_res_id);
if (getGameType() == GType_FF || getGameType() == GType_PP) {
- fillFrontFromBack(0, 0, _screenWidth, _screenHeight);
- fillBackGroundFromBack(_screenHeight);
+ fillBackGroundFromBack();
_syncFlag2 = 1;
} else {
_copyScnFlag = 2;
@@ -1302,6 +1318,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
uint width = _videoWindows[updateWindow * 4 + 2] * 16;
uint height = _videoWindows[updateWindow * 4 + 3];
+ Graphics::Surface *screen = _system->lockScreen();
byte *dst = getBackGround() + xoffs + yoffs * _screenWidth;
byte *src;
uint srcWidth;
@@ -1315,9 +1332,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
src = _window4BackScn;
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow == 3 || updateWindow == 9) {
- src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ src = (byte *)screen->pixels + xoffs + yoffs * _screenWidth;
srcWidth = _screenWidth;
} else {
+ _system->unlockScreen();
_lockWord &= ~0x20;
return;
}
@@ -1329,9 +1347,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
src = _window4BackScn + xoffs + yoffs * 320;
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow == 0) {
- src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ src = (byte *)screen->pixels + xoffs + yoffs * _screenWidth;
srcWidth = _screenWidth;
} else {
+ _system->unlockScreen();
_lockWord &= ~0x20;
return;
}
@@ -1340,9 +1359,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
src = _window4BackScn;
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow == 3 || updateWindow == 9) {
- src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ src = (byte *)screen->pixels + xoffs + yoffs * _screenWidth;
srcWidth = _screenWidth;
} else {
+ _system->unlockScreen();
_lockWord &= ~0x20;
return;
}
@@ -1351,9 +1371,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
src = _window4BackScn;
srcWidth = _videoWindows[18] * 16;
} else if (updateWindow == 3) {
- src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ src = (byte *)screen->pixels + xoffs + yoffs * _screenWidth;
srcWidth = _screenWidth;
} else {
+ _system->unlockScreen();
_lockWord &= ~0x20;
return;
}
@@ -1363,7 +1384,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
src = _window6BackScn;
srcWidth = 48;
} else if (updateWindow == 2 || updateWindow == 3) {
- src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ src = (byte *)screen->pixels + xoffs + yoffs * _screenWidth;
srcWidth = _screenWidth;
} else {
src = _window4BackScn;
@@ -1380,7 +1401,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
}
if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette) {
- dst = getFrontBuf() + 133 * _screenWidth;
+ dst = (byte *)screen->pixels + 133 * _screenWidth;
int size = 67 * _screenWidth;
while (size--) {
@@ -1389,8 +1410,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
}
}
- _syncFlag2 = 1;
- _timer5 = 0;
+ _system->unlockScreen();
}
_lockWord &= ~0x20;
diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp
index 9c8938bb97..3edcedaa8e 100644
--- a/engines/agos/icons.cpp
+++ b/engines/agos/icons.cpp
@@ -25,27 +25,44 @@
#include "common/stdafx.h"
+#include "common/system.h"
+
#include "common/file.h"
+#include "graphics/surface.h"
+
#include "agos/agos.h"
namespace AGOS {
void AGOSEngine::loadIconFile() {
Common::File in;
- uint size;
+ uint32 srcSize;
in.open(getFileName(GAME_ICONFILE));
if (in.isOpen() == false)
error("Can't open icons file '%s'", getFileName(GAME_ICONFILE));
- size = in.size();
+ srcSize = in.size();
- _iconFilePtr = (byte *)malloc(size);
- if (_iconFilePtr == NULL)
- error("Out of icon memory");
+ if (getGameType() == GType_WW && getPlatform() == Common::kPlatformAmiga) {
+ byte *srcBuf = (byte *)malloc(srcSize);
+ in.read(srcBuf, srcSize);
+
+ uint32 dstSize = READ_BE_UINT32(srcBuf + srcSize - 4);
+ _iconFilePtr = (byte *)malloc(dstSize);
+ if (_iconFilePtr == NULL)
+ error("Out of icon memory");
+
+ decrunchFile(srcBuf, _iconFilePtr, srcSize);
+ free(srcBuf);
+ } else {
+ _iconFilePtr = (byte *)malloc(srcSize);
+ if (_iconFilePtr == NULL)
+ error("Out of icon memory");
- in.read(_iconFilePtr, size);
+ in.read(_iconFilePtr, srcSize);
+ }
in.close();
}
@@ -66,15 +83,19 @@ void AGOSEngine::loadIconData() {
// Thanks to Stuart Caie for providing the original
// C conversion upon which this function is based.
static void decompressIconPlanar(byte *dst, byte *src, uint width, uint height, byte base, uint pitch, bool decompress = true) {
- byte icon_pln[288];
- byte *i, *o, *srcPtr, x, y;
+ byte *i, *icon_pln, *o, *srcPtr;
+ byte x, y;
+ icon_pln = 0;
srcPtr = src;
+
if (decompress) {
+ icon_pln = (byte *)calloc(width * height, 1);
+
// Decode RLE planar icon data
i = src;
o = icon_pln;
- while (o < &icon_pln[288]) {
+ while (o < &icon_pln[width * height]) {
x = *i++;
if (x < 128) {
do {
@@ -96,18 +117,20 @@ static void decompressIconPlanar(byte *dst, byte *src, uint width, uint height,
}
// Translate planar data to chunky (very slow method)
- for (y = 0; y < 24; y++) {
- for (x = 0; x < 24; x++) {
+ for (y = 0; y < height * 2; y++) {
+ for (x = 0; x < width; x++) {
byte pixel =
- (srcPtr[(( y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 1 : 0)
- | (srcPtr[((24 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 2 : 0)
- | (srcPtr[((48 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 4 : 0)
- | (srcPtr[((72 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 8 : 0);
+ (srcPtr[((height * 0 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 1 : 0)
+ | (srcPtr[((height * 2 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 2 : 0)
+ | (srcPtr[((height * 4 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 4 : 0)
+ | (srcPtr[((height * 6 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 8 : 0);
if (pixel)
dst[x] = pixel | base;
}
dst += pitch;
}
+
+ free(icon_pln);
}
static void decompressIcon(byte *dst, byte *src, uint width, uint height, byte base, uint pitch) {
@@ -174,20 +197,24 @@ void AGOSEngine_Simon2::drawIcon(WindowBlock *window, uint icon, uint x, uint y)
byte *src;
_lockWord |= 0x8000;
- dst = getFrontBuf();
+
+ Graphics::Surface *screen = _system->lockScreen();
+ dst = (byte *)screen->pixels;
dst += 110;
dst += x;
dst += (y + window->y) * _dxSurfacePitch;
src = _iconFilePtr;
- src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 0]);
+ src += READ_LE_UINT16(src + icon * 4 + 0);
decompressIcon(dst, src, 20, 10, 224, _dxSurfacePitch);
src = _iconFilePtr;
- src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 1]);
+ src += READ_LE_UINT16(src + icon * 4 + 2);
decompressIcon(dst, src, 20, 10, 208, _dxSurfacePitch);
+ _system->unlockScreen();
+
_lockWord &= ~0x8000;
}
@@ -196,22 +223,26 @@ void AGOSEngine_Simon1::drawIcon(WindowBlock *window, uint icon, uint x, uint y)
byte *src;
_lockWord |= 0x8000;
- dst = getFrontBuf();
+
+ Graphics::Surface *screen = _system->lockScreen();
+ dst = (byte *)screen->pixels;
dst += (x + window->x) * 8;
dst += (y * 25 + window->y) * _dxSurfacePitch;
if (getPlatform() == Common::kPlatformAmiga) {
src = _iconFilePtr;
- src += READ_BE_UINT32(&((uint32 *)src)[icon]);
+ src += READ_BE_UINT32(src + icon * 4);
uint8 color = (getFeatures() & GF_32COLOR) ? 16 : 240;
- decompressIconPlanar(dst, src, 24, 24, color, _dxSurfacePitch);
+ decompressIconPlanar(dst, src, 24, 12, color, _dxSurfacePitch);
} else {
src = _iconFilePtr;
- src += READ_LE_UINT16(&((uint16 *)src)[icon]);
+ src += READ_LE_UINT16(src + icon * 2);
decompressIcon(dst, src, 24, 12, 224, _dxSurfacePitch);
}
+ _system->unlockScreen();
+
_lockWord &= ~0x8000;
}
@@ -220,21 +251,26 @@ void AGOSEngine_Waxworks::drawIcon(WindowBlock *window, uint icon, uint x, uint
byte *src;
_lockWord |= 0x8000;
- dst = getFrontBuf();
+
+ Graphics::Surface *screen = _system->lockScreen();
+ dst = (byte *)screen->pixels;
dst += (x + window->x) * 8;
dst += (y * 20 + window->y) * _dxSurfacePitch;
uint8 color = dst[0] & 0xF0;
if (getPlatform() == Common::kPlatformAmiga) {
- // TODO
- return;
+ src = _iconFilePtr;
+ src += READ_BE_UINT32(src + icon * 4);
+ decompressIconPlanar(dst, src, 24, 10, color, _dxSurfacePitch);
} else {
src = _iconFilePtr;
- src += READ_LE_UINT16(&((uint16 *)src)[icon]);
+ src += READ_LE_UINT16(src + icon * 2);
decompressIcon(dst, src, 24, 10, color, _dxSurfacePitch);
}
+ _system->unlockScreen();
+
_lockWord &= ~0x8000;
}
@@ -243,7 +279,9 @@ void AGOSEngine_Elvira2::drawIcon(WindowBlock *window, uint icon, uint x, uint y
byte *src;
_lockWord |= 0x8000;
- dst = getFrontBuf();
+
+ Graphics::Surface *screen = _system->lockScreen();
+ dst = (byte *)screen->pixels;
dst += (x + window->x) * 8;
dst += (y * 8 + window->y) * _dxSurfacePitch;
@@ -251,14 +289,16 @@ void AGOSEngine_Elvira2::drawIcon(WindowBlock *window, uint icon, uint x, uint y
uint color = dst[0] & 0xF0;
if (getFeatures() & GF_PLANAR) {
src = _iconFilePtr;
- src += READ_BE_UINT32(&((uint32 *)src)[icon]);
- decompressIconPlanar(dst, src, 24, 24, color, _dxSurfacePitch);
+ src += READ_BE_UINT32(src + icon * 4);
+ decompressIconPlanar(dst, src, 24, 12, color, _dxSurfacePitch);
} else {
src = _iconFilePtr;
- src += READ_LE_UINT16(&((uint16 *)src)[icon]);
+ src += READ_LE_UINT16(src + icon * 2);
decompressIcon(dst, src, 24, 12, color, _dxSurfacePitch);
}
+ _system->unlockScreen();
+
_lockWord &= ~0x8000;
}
@@ -267,21 +307,25 @@ void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) {
byte *src;
_lockWord |= 0x8000;
- dst = getFrontBuf();
+
+ Graphics::Surface *screen = _system->lockScreen();
+ dst = (byte *)screen->pixels;
dst += (x + window->x) * 8;
dst += (y * 8 + window->y) * _dxSurfacePitch;
if (getFeatures() & GF_PLANAR) {
src = _iconFilePtr;
- src += READ_BE_UINT16(&((uint16 *)src)[icon]);
- decompressIconPlanar(dst, src, 24, 24, 16, _dxSurfacePitch);
+ src += READ_BE_UINT16(src + icon * 2);
+ decompressIconPlanar(dst, src, 24, 12, 16, _dxSurfacePitch);
} else {
src = _iconFilePtr;
src += icon * 288;
- decompressIconPlanar(dst, src, 24, 24, 16, _dxSurfacePitch, false);
+ decompressIconPlanar(dst, src, 24, 12, 16, _dxSurfacePitch, false);
}
+ _system->unlockScreen();
+
_lockWord &= ~0x8000;
}
@@ -384,7 +428,7 @@ l1:; itemRef = derefItem(itemRef->next);
}
/* Plot arrows and add their boxes */
- addArrows(window);
+ addArrows(window, num);
window->iconPtr->upArrow = _scrollUpHitArea;
window->iconPtr->downArrow = _scrollDownHitArea;
}
@@ -486,7 +530,7 @@ void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask)
if (showArrows != 0 || window->iconPtr->line != 0) {
/* Plot arrows and add their boxes */
- addArrows(window);
+ addArrows(window, num);
window->iconPtr->upArrow = _scrollUpHitArea;
window->iconPtr->downArrow = _scrollDownHitArea;
}
@@ -594,7 +638,7 @@ uint AGOSEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y,
return ha - _hitAreas;
}
-void AGOSEngine_Feeble::addArrows(WindowBlock *window) {
+void AGOSEngine_Feeble::addArrows(WindowBlock *window, uint8 num) {
HitArea *ha;
ha = findEmptyHitArea();
@@ -624,7 +668,7 @@ void AGOSEngine_Feeble::addArrows(WindowBlock *window) {
ha->verb = 1;
}
-void AGOSEngine_Simon2::addArrows(WindowBlock *window) {
+void AGOSEngine_Simon2::addArrows(WindowBlock *window, uint8 num) {
HitArea *ha;
ha = findEmptyHitArea();
@@ -654,7 +698,7 @@ void AGOSEngine_Simon2::addArrows(WindowBlock *window) {
ha->verb = 1;
}
-void AGOSEngine_Simon1::addArrows(WindowBlock *window) {
+void AGOSEngine_Simon1::addArrows(WindowBlock *window, uint8 num) {
HitArea *ha;
ha = findEmptyHitArea();
@@ -683,16 +727,24 @@ void AGOSEngine_Simon1::addArrows(WindowBlock *window) {
ha->window = window;
ha->verb = 1;
- if (getFeatures() & GF_32COLOR) {
- // TODO: Manually draws arrows
- } else {
- stopAnimate(128);
- uint8 palette = (getPlatform() == Common::kPlatformAmiga) ? 15: 14;
- animate(0, 1, 128, 0, 0, palette);
- }
+ _lockWord |= 0x8;
+
+ VgaPointersEntry *vpe = &_vgaBufferPointers[1];
+ byte *curVgaFile2Orig = _curVgaFile2;
+ uint16 windowNumOrig = _windowNum;
+ uint8 palette = (getPlatform() == Common::kPlatformAmiga) ? 15 : 14;
+
+ _windowNum = 0;
+ _curVgaFile2 = vpe->vgaFile2;
+ drawImage_init(1, palette, 38, 150, 4);
+
+ _curVgaFile2 = curVgaFile2Orig;
+ _windowNum = windowNumOrig;
+
+ _lockWord &= ~0x8;
}
-void AGOSEngine_Waxworks::addArrows(WindowBlock *window) {
+void AGOSEngine_Waxworks::addArrows(WindowBlock *window, uint8 num) {
HitArea *ha;
ha = findEmptyHitArea();
@@ -724,7 +776,7 @@ void AGOSEngine_Waxworks::addArrows(WindowBlock *window) {
setWindowImageEx(6, 103);
}
-void AGOSEngine_Elvira2::addArrows(WindowBlock *window) {
+void AGOSEngine_Elvira2::addArrows(WindowBlock *window, uint8 num) {
HitArea *ha;
ha = findEmptyHitArea();
@@ -756,8 +808,17 @@ void AGOSEngine_Elvira2::addArrows(WindowBlock *window) {
setWindowImageEx(6, 106);
}
-void AGOSEngine::addArrows(WindowBlock *window) {
+void AGOSEngine::addArrows(WindowBlock *window, uint8 num) {
HitArea *ha;
+ uint16 x, y;
+
+ x = 30;
+ y = 151;
+ if (num != 2) {
+ y = window->height * 4 + window->y - 19;
+ x = window->width + window->x;
+ }
+ drawArrow(x, y, 16);
ha = findEmptyHitArea();
_scrollUpHitArea = ha - _hitAreas;
@@ -772,6 +833,14 @@ void AGOSEngine::addArrows(WindowBlock *window) {
ha->window = window;
ha->verb = 1;
+ x = 30;
+ y = 170;
+ if (num != 2) {
+ y = window->height * 4;
+ x = window->width + window->x;
+ }
+ drawArrow(x, y, -16);
+
ha = findEmptyHitArea();
_scrollDownHitArea = ha - _hitAreas;
@@ -786,21 +855,89 @@ void AGOSEngine::addArrows(WindowBlock *window) {
ha->verb = 1;
}
+static const byte _arrowImage[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x0b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b,
+ 0x0a, 0x0b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0a,
+ 0x0d, 0x0a, 0x0b, 0x0a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0a, 0x0d,
+ 0x03, 0x0d, 0x0a, 0x0b, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0a, 0x0d, 0x03,
+ 0x04, 0x03, 0x0d, 0x0a, 0x0b, 0x0a, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0x0b, 0x0a, 0x0d, 0x03, 0x04,
+ 0x0f, 0x04, 0x03, 0x0d, 0x0a, 0x0b, 0x0a, 0x00,
+ 0x00, 0x0a, 0x0b, 0x0a, 0x0d, 0x0d, 0x0d, 0x03,
+ 0x04, 0x03, 0x0d, 0x0d, 0x0d, 0x0a, 0x0b, 0x0a,
+ 0x00, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x0d,
+ 0x03, 0x0d, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b,
+ 0x00, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0d,
+ 0x0d, 0x0d, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x00, 0x0a, 0x0a, 0x0a, 0x0e, 0x0b, 0x0b, 0x0c,
+ 0x0e, 0x0c, 0x0b, 0x0b, 0x0e, 0x0a, 0x0a, 0x0a,
+ 0x00, 0x00, 0x02, 0x02, 0x0a, 0x0b, 0x0a, 0x0d,
+ 0x0d, 0x0d, 0x0a, 0x0b, 0x0a, 0x02, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x0a, 0x0b, 0x0b, 0x0c,
+ 0x0e, 0x0c, 0x0b, 0x0b, 0x0a, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0a, 0x0d,
+ 0x0d, 0x0d, 0x0a, 0x0b, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0b, 0x0c,
+ 0x0e, 0x0c, 0x0b, 0x0b, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x0a, 0x0a,
+ 0x0e, 0x0a, 0x0a, 0x0e, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00,
+ 0x0a, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+};
+
+void AGOSEngine::drawArrow(uint16 x, uint16 y, int8 dir) {
+ const byte *src;
+ uint8 w, h;
+
+ if (dir < 0) {
+ src = _arrowImage + 288;
+ } else {
+ src = _arrowImage;
+ }
+
+ Graphics::Surface *screen = _system->lockScreen();
+ byte *dst = (byte *)screen->pixels + y * _screenWidth + x * 8;
+
+ for (h = 0; h < 19; h++) {
+ for (w = 0; w < 16; w++) {
+ dst[w] = src[w] + 16;
+ }
+
+ src += dir;
+ dst+= _screenWidth;
+ }
+
+ _system->unlockScreen();
+}
+
void AGOSEngine::removeArrows(WindowBlock *window, uint num) {
if (getGameType() == GType_SIMON1) {
- if (getFeatures() & GF_32COLOR) {
- // TODO: Manually removes arrows
- } else {
- stopAnimate(129);
- uint8 palette = (getPlatform() == Common::kPlatformAmiga) ? 15: 14;
- animate(0, 1, 129, 0, 0, palette);
- }
+ restoreBlock(200, 320, 146, 304);
} else if (getGameType() == GType_WW) {
setBitFlag(22, false);
setWindowImageEx(6, 103);
} else if (getGameType() == GType_ELVIRA2) {
setBitFlag(21, false);
setWindowImageEx(6, 106);
+ } else if (getGameType() == GType_ELVIRA1) {
+ if (num != 2) {
+ uint y = window->height * 4 + window->y - 19;
+ uint x = window->width + window->x;
+ restoreBlock(y + 38, x + 16, y, x);
+ } else {
+ colorBlock(window, 240, 151, 16, 38);
+ }
}
}
diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp
index 3f2efc86b4..ef0791dc10 100644
--- a/engines/agos/input.cpp
+++ b/engines/agos/input.cpp
@@ -25,6 +25,7 @@
#include "common/stdafx.h"
+#include "common/config-manager.h"
#include "common/file.h"
#include "agos/intern.h"
@@ -273,28 +274,28 @@ void AGOSEngine::waitForInput() {
_verbHitArea = 236;
if (ha->id == 98) {
- animate(2, 0, 110, 0, 0, 0);
+ animate(2, 1, 110, 0, 0, 0);
waitForSync(34);
} else if (ha->id == 108) {
- animate(2, 0, 106, 0, 0, 0);
+ animate(2, 1, 106, 0, 0, 0);
waitForSync(34);
} else if (ha->id == 109) {
- animate(2, 0, 107, 0, 0, 0);
+ animate(2, 1, 107, 0, 0, 0);
waitForSync(34);
} else if (ha->id == 115) {
- animate(2, 0, 109, 0, 0, 0);
+ animate(2, 1, 109, 0, 0, 0);
waitForSync(34);
} else if (ha->id == 116) {
- animate(2, 0, 113, 0, 0, 0);
+ animate(2, 1, 113, 0, 0, 0);
waitForSync(34);
} else if (ha->id == 117) {
- animate(2, 0, 112, 0, 0, 0);
+ animate(2, 1, 112, 0, 0, 0);
waitForSync(34);
} else if (ha->id == 118) {
- animate(2, 0, 108, 0, 0, 0);
+ animate(2, 1, 108, 0, 0, 0);
waitForSync(34);
} else if (ha->id == 119) {
- animate(2, 0, 111, 0, 0, 0);
+ animate(2, 1, 111, 0, 0, 0);
waitForSync(34);
}
}
@@ -542,6 +543,14 @@ bool AGOSEngine::processSpecialKeys() {
if (getGameType() == GType_FF)
setBitFlag(73, !getBitFlag(73));
break;
+ case 37: // F12
+ if (getGameType() == GType_PP && getGameId() != GID_DIMP) {
+ if (!getBitFlag(110)) {
+ setBitFlag(107, !getBitFlag(107));
+ _vgaPeriod = (getBitFlag(107) != 0) ? 15 : 30;
+ }
+ }
+ break;
case 'p':
pause();
break;
@@ -558,21 +567,30 @@ bool AGOSEngine::processSpecialKeys() {
_speech ^= 1;
}
case '+':
- _midi.setVolume(_midi.getVolume() + 16);
+ if (_midiEnabled) {
+ _midi.setVolume(_midi.getVolume() + 16);
+ }
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) + 16);
break;
case '-':
- _midi.setVolume(_midi.getVolume() - 16);
+ if (_midiEnabled) {
+ _midi.setVolume(_midi.getVolume() - 16);
+ }
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) - 16);
break;
case 'm':
- _midi.pause(_musicPaused ^= 1);
+ _musicPaused ^= 1;
+ if (_midiEnabled) {
+ _midi.pause(_musicPaused);
+ }
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, (_musicPaused) ? 0 : ConfMan.getInt("music_volume"));
break;
case 's':
- if (getGameId() == GID_SIMON1DOS)
+ if (getGameId() == GID_SIMON1DOS) {
_midi._enable_sfx ^= 1;
- else
+ } else {
_sound->effectsPause(_effectsPaused ^= 1);
+ }
break;
case 'b':
_sound->ambientPause(_ambientPaused ^= 1);
diff --git a/engines/agos/intern.h b/engines/agos/intern.h
index f39ca7d3da..a863dc7c0f 100644
--- a/engines/agos/intern.h
+++ b/engines/agos/intern.h
@@ -131,11 +131,11 @@ struct IconBlock {
struct WindowBlock {
byte mode;
byte flags;
- uint16 x, y;
- uint16 width, height;
- uint16 textColumn, textRow;
+ int16 x, y;
+ int16 width, height;
+ int16 textColumn, textRow;
+ int16 scrollY;
uint16 textColumnOffset, textLength, textMaxLength;
- uint16 scrollY;
uint8 fill_color, text_color;
IconBlock *iconPtr;
WindowBlock() { memset(this, 0, sizeof(*this)); }
diff --git a/engines/agos/items.cpp b/engines/agos/items.cpp
index 165af6f797..a911bee5a5 100644
--- a/engines/agos/items.cpp
+++ b/engines/agos/items.cpp
@@ -391,10 +391,8 @@ int AGOSEngine::wordMatch(Item *item, int16 a, int16 n) {
}
Item *AGOSEngine::derefItem(uint item) {
- if (item >= _itemArraySize) {
- debug(1, "derefItem: invalid item %d", item);
- return 0;
- }
+ if (item >= _itemArraySize)
+ error("derefItem: invalid item %d", item);
return _itemArrayPtr[item];
}
diff --git a/engines/agos/menus.cpp b/engines/agos/menus.cpp
index 802752fad9..6dd1a356d8 100644
--- a/engines/agos/menus.cpp
+++ b/engines/agos/menus.cpp
@@ -26,6 +26,9 @@
#include "common/stdafx.h"
#include "common/file.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
#include "agos/agos.h"
#include "agos/intern.h"
@@ -145,7 +148,8 @@ void AGOSEngine::unlightMenuStrip() {
mouseOff();
- src = getFrontBuf() + 2832;
+ Graphics::Surface *screen = _system->lockScreen();
+ src = (byte *)screen->pixels + 2832;
w = 48;
h = 82;
@@ -160,6 +164,8 @@ void AGOSEngine::unlightMenuStrip() {
for (i = 120; i != 130; i++)
disableBox(i);
+ _system->unlockScreen();
+
mouseOn();
}
@@ -170,7 +176,8 @@ void AGOSEngine::lightMenuBox(uint hitarea) {
mouseOff();
- src = getFrontBuf() + ha->y * _dxSurfacePitch + ha->x;
+ Graphics::Surface *screen = _system->lockScreen();
+ src = (byte *)screen->pixels + ha->y * _dxSurfacePitch + ha->x;
w = ha->width;
h = ha->height;
@@ -182,6 +189,8 @@ void AGOSEngine::lightMenuBox(uint hitarea) {
src += _dxSurfacePitch;
} while (--h);
+ _system->unlockScreen();
+
mouseOn();
}
diff --git a/engines/agos/oracle.cpp b/engines/agos/oracle.cpp
index c38ee8fa6d..787596a966 100644
--- a/engines/agos/oracle.cpp
+++ b/engines/agos/oracle.cpp
@@ -26,6 +26,9 @@
#include "common/stdafx.h"
#include "common/savefile.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
#include "agos/agos.h"
#include "agos/intern.h"
@@ -247,8 +250,8 @@ void AGOSEngine_Feeble::scrollOracleUp() {
byte *src, *dst;
uint16 w, h;
- dst = getFrontBuf() + 103 * _screenWidth + 136;
- src = getFrontBuf() + 106 * _screenWidth + 136;
+ dst = getBackGround() + 103 * _screenWidth + 136;
+ src = getBackGround() + 106 * _screenWidth + 136;
for (h = 0; h < 21; h++) {
for (w = 0; w < 360; w++) {
@@ -276,8 +279,8 @@ void AGOSEngine_Feeble::scrollOracleDown() {
byte *src, *dst;
uint16 w, h;
- src = getFrontBuf() + 203 * _screenWidth + 136;
- dst = getFrontBuf() + 206 * _screenWidth + 136;
+ src = getBackGround() + 203 * _screenWidth + 136;
+ dst = getBackGround() + 206 * _screenWidth + 136;
for (h = 0; h < 77; h++) {
memcpy(dst, src, 360);
@@ -507,7 +510,7 @@ void AGOSEngine_Feeble::windowBackSpace(WindowBlock *window) {
x = window->x + window->textColumn;
y = window->y + window->textRow;
- dst = getFrontBuf() + _dxSurfacePitch * y + x;
+ dst = getBackGround() + _dxSurfacePitch * y + x;
for (h = 0; h < 13; h++) {
for (w = 0; w < 8; w++) {
diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp
index f5936b7d85..394c4956ae 100644
--- a/engines/agos/res.cpp
+++ b/engines/agos/res.cpp
@@ -351,104 +351,130 @@ void AGOSEngine::readItemFromGamePc(Common::SeekableReadStream *in, Item *item)
void AGOSEngine::readItemChildren(Common::SeekableReadStream *in, Item *item, uint type) {
if (type == 1) {
- if (getGameType() == GType_ELVIRA1) {
- SubRoom *subRoom = (SubRoom *)allocateChildBlock(item, 1, sizeof(SubRoom));
- subRoom->roomShort = in->readUint32BE();
- subRoom->roomLong = in->readUint32BE();
- subRoom->flags = in->readUint16BE();
- } else {
- uint fr1 = in->readUint16BE();
- uint fr2 = in->readUint16BE();
- uint i, size;
- uint j, k;
- SubRoom *subRoom;
-
- size = SubRoom_SIZE;
- for (i = 0, j = fr2; i != 6; i++, j >>= 2)
- if (j & 3)
- size += sizeof(subRoom->roomExit[0]);
-
- subRoom = (SubRoom *)allocateChildBlock(item, 1, size);
- subRoom->subroutine_id = fr1;
- subRoom->roomExitStates = fr2;
-
- for (i = k = 0, j = fr2; i != 6; i++, j >>= 2)
- if (j & 3)
- subRoom->roomExit[k++] = (uint16)fileReadItemID(in);
- }
+ SubRoom *subRoom = (SubRoom *)allocateChildBlock(item, 1, sizeof(SubRoom));
+ subRoom->roomShort = in->readUint32BE();
+ subRoom->roomLong = in->readUint32BE();
+ subRoom->flags = in->readUint16BE();
} else if (type == 2) {
- if (getGameType() == GType_ELVIRA1) {
- SubObject *subObject = (SubObject *)allocateChildBlock(item, 2, sizeof(SubObject));
- in->readUint32BE();
- in->readUint32BE();
- in->readUint32BE();
- subObject->objectName = in->readUint32BE();
- subObject->objectSize = in->readUint16BE();
- subObject->objectWeight = in->readUint16BE();
- subObject->objectFlags = in->readUint16BE();
- } else {
- uint32 fr = in->readUint32BE();
- uint i, k, size;
- SubObject *subObject;
+ SubObject *subObject = (SubObject *)allocateChildBlock(item, 2, sizeof(SubObject));
+ in->readUint32BE();
+ in->readUint32BE();
+ in->readUint32BE();
+ subObject->objectName = in->readUint32BE();
+ subObject->objectSize = in->readUint16BE();
+ subObject->objectWeight = in->readUint16BE();
+ subObject->objectFlags = in->readUint16BE();
+ } else if (type == 4) {
+ SubGenExit *genExit = (SubGenExit *)allocateChildBlock(item, 4, sizeof(SubGenExit));
+ genExit->dest[0] = (uint16)fileReadItemID(in);
+ genExit->dest[1] = (uint16)fileReadItemID(in);
+ genExit->dest[2] = (uint16)fileReadItemID(in);
+ genExit->dest[3] = (uint16)fileReadItemID(in);
+ genExit->dest[4] = (uint16)fileReadItemID(in);
+ genExit->dest[5] = (uint16)fileReadItemID(in);
+ fileReadItemID(in);
+ fileReadItemID(in);
+ fileReadItemID(in);
+ fileReadItemID(in);
+ fileReadItemID(in);
+ fileReadItemID(in);
+ } else if (type == 7) {
+ SubContainer *container = (SubContainer *)allocateChildBlock(item, 7, sizeof(SubContainer));
+ container->volume = in->readUint16BE();
+ container->flags = in->readUint16BE();
+ } else if (type == 8) {
+ SubChain *chain = (SubChain *)allocateChildBlock(item, 8, sizeof(SubChain));
+ chain->chChained = (uint16)fileReadItemID(in);
+ } else if (type == 9) {
+ setUserFlag(item, 0, in->readUint16BE());
+ setUserFlag(item, 1, in->readUint16BE());
+ setUserFlag(item, 2, in->readUint16BE());
+ setUserFlag(item, 3, in->readUint16BE());
+ setUserFlag(item, 4, in->readUint16BE());
+ setUserFlag(item, 5, in->readUint16BE());
+ setUserFlag(item, 6, in->readUint16BE());
+ setUserFlag(item, 7, in->readUint16BE());
+ SubUserFlag *subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
+ subUserFlag->userItems[0] = (uint16)fileReadItemID(in);
+ fileReadItemID(in);
+ fileReadItemID(in);
+ fileReadItemID(in);
+ } else if (type == 255) {
+ SubInherit *inherit = (SubInherit *)allocateChildBlock(item, 255, sizeof(SubInherit));
+ inherit->inMaster = (uint16)fileReadItemID(in);
+ } else {
+ error("readItemChildren: invalid type %d", type);
+ }
+}
- size = SubObject_SIZE;
- for (i = 0; i != 16; i++)
- if (fr & (1 << i))
- size += sizeof(subObject->objectFlagValue[0]);
+void AGOSEngine_Elvira2::readItemChildren(Common::SeekableReadStream *in, Item *item, uint type) {
+ if (type == 1) {
+ uint fr1 = in->readUint16BE();
+ uint fr2 = in->readUint16BE();
+ uint i, size;
+ uint j, k;
+ SubRoom *subRoom;
+
+ size = SubRoom_SIZE;
+ for (i = 0, j = fr2; i != 6; i++, j >>= 2)
+ if (j & 3)
+ size += sizeof(subRoom->roomExit[0]);
+
+ subRoom = (SubRoom *)allocateChildBlock(item, 1, size);
+ subRoom->subroutine_id = fr1;
+ subRoom->roomExitStates = fr2;
+
+ for (i = k = 0, j = fr2; i != 6; i++, j >>= 2)
+ if (j & 3)
+ subRoom->roomExit[k++] = (uint16)fileReadItemID(in);
+ } else if (type == 2) {
+ uint32 fr = in->readUint32BE();
+ uint i, k, size;
+ SubObject *subObject;
- subObject = (SubObject *)allocateChildBlock(item, 2, size);
- subObject->objectFlags = fr;
+ size = SubObject_SIZE;
+ for (i = 0; i != 16; i++)
+ if (fr & (1 << i))
+ size += sizeof(subObject->objectFlagValue[0]);
- k = 0;
- if (fr & 1) {
- subObject->objectFlagValue[k++] = (uint16)in->readUint32BE();
- }
- for (i = 1; i != 16; i++)
- if (fr & (1 << i))
- subObject->objectFlagValue[k++] = in->readUint16BE();
+ subObject = (SubObject *)allocateChildBlock(item, 2, size);
+ subObject->objectFlags = fr;
- if (getGameType() != GType_ELVIRA2)
- subObject->objectName = (uint16)in->readUint32BE();
+ k = 0;
+ if (fr & 1) {
+ subObject->objectFlagValue[k++] = (uint16)in->readUint32BE();
}
+ for (i = 1; i != 16; i++)
+ if (fr & (1 << i))
+ subObject->objectFlagValue[k++] = in->readUint16BE();
+
+ if (getGameType() != GType_ELVIRA2)
+ subObject->objectName = (uint16)in->readUint32BE();
} else if (type == 4) {
- if (getGameType() == GType_ELVIRA2) {
- uint i, j, k, size;
- uint id, x, y, z;
- SubSuperRoom *subSuperRoom;
-
- id = in->readUint16BE();
- x = in->readUint16BE();
- y = in->readUint16BE();
- z = in->readUint16BE();
-
- j = x * y * z;
- size = SubSuperRoom_SIZE;
- for (i = 0; i != j; i++)
- size += sizeof(subSuperRoom->roomExitStates[0]);
-
- subSuperRoom = (SubSuperRoom *)allocateChildBlock(item, 4, size);
- subSuperRoom->subroutine_id = id;
- subSuperRoom->roomX = x;
- subSuperRoom->roomY = y;
- subSuperRoom->roomZ = z;
-
- for (i = k = 0; i != j; i++)
- subSuperRoom->roomExitStates[k++] = in->readUint16BE();
- } else if (getGameType() == GType_ELVIRA1) {
- SubGenExit *genExit = (SubGenExit *)allocateChildBlock(item, 4, sizeof(SubGenExit));
- genExit->dest[0] = (uint16)fileReadItemID(in);
- genExit->dest[1] = (uint16)fileReadItemID(in);
- genExit->dest[2] = (uint16)fileReadItemID(in);
- genExit->dest[3] = (uint16)fileReadItemID(in);
- genExit->dest[4] = (uint16)fileReadItemID(in);
- genExit->dest[5] = (uint16)fileReadItemID(in);
- fileReadItemID(in);
- fileReadItemID(in);
- fileReadItemID(in);
- fileReadItemID(in);
- fileReadItemID(in);
- fileReadItemID(in);
- }
+ assert(getGameType() == GType_ELVIRA2);
+
+ uint i, j, k, size;
+ uint id, x, y, z;
+ SubSuperRoom *subSuperRoom;
+
+ id = in->readUint16BE();
+ x = in->readUint16BE();
+ y = in->readUint16BE();
+ z = in->readUint16BE();
+
+ j = x * y * z;
+ size = SubSuperRoom_SIZE;
+ for (i = 0; i != j; i++)
+ size += sizeof(subSuperRoom->roomExitStates[0]);
+
+ subSuperRoom = (SubSuperRoom *)allocateChildBlock(item, 4, size);
+ subSuperRoom->subroutine_id = id;
+ subSuperRoom->roomX = x;
+ subSuperRoom->roomY = y;
+ subSuperRoom->roomZ = z;
+
+ for (i = k = 0; i != j; i++)
+ subSuperRoom->roomExitStates[k++] = in->readUint16BE();
} else if (type == 7) {
SubContainer *container = (SubContainer *)allocateChildBlock(item, 7, sizeof(SubContainer));
container->volume = in->readUint16BE();
@@ -461,17 +487,6 @@ void AGOSEngine::readItemChildren(Common::SeekableReadStream *in, Item *item, ui
setUserFlag(item, 1, in->readUint16BE());
setUserFlag(item, 2, in->readUint16BE());
setUserFlag(item, 3, in->readUint16BE());
- if (getGameType() == GType_ELVIRA1) {
- setUserFlag(item, 4, in->readUint16BE());
- setUserFlag(item, 5, in->readUint16BE());
- setUserFlag(item, 6, in->readUint16BE());
- setUserFlag(item, 7, in->readUint16BE());
- SubUserFlag *subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
- subUserFlag->userItems[0] = (uint16)fileReadItemID(in);
- fileReadItemID(in);
- fileReadItemID(in);
- fileReadItemID(in);
- }
} else if (type == 255) {
SubInherit *inherit = (SubInherit *)allocateChildBlock(item, 255, sizeof(SubInherit));
inherit->inMaster = (uint16)fileReadItemID(in);
@@ -629,7 +644,7 @@ bool AGOSEngine::decrunchFile(byte *src, byte *dst, uint32 size) {
#undef SD_TYPE_LITERAL
#undef SD_TYPE_MATCH
-void AGOSEngine::loadVGABeardFile(uint id) {
+void AGOSEngine::loadVGABeardFile(uint16 id) {
uint32 offs, size;
if (getFeatures() & GF_OLD_BUNDLE) {
@@ -673,7 +688,7 @@ void AGOSEngine::loadVGABeardFile(uint id) {
}
}
-void AGOSEngine::loadVGAVideoFile(uint id, uint type) {
+void AGOSEngine::loadVGAVideoFile(uint16 id, uint8 type) {
File in;
char filename[15];
byte *dst;
diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp
index cc5ba2a793..779ed67e58 100644
--- a/engines/agos/res_snd.cpp
+++ b/engines/agos/res_snd.cpp
@@ -41,59 +41,59 @@ using Common::File;
namespace AGOS {
-void AGOSEngine::playSpeech(uint speech_id, uint vgaSpriteId) {
- if (getGameType() == GType_SIMON1) {
- if (speech_id == 9999) {
- if (_subtitles)
- return;
- if (!getBitFlag(14) && !getBitFlag(28)) {
- setBitFlag(14, true);
- _variableArray[100] = 15;
- animate(4, 1, 130, 0, 0, 0);
- waitForSync(130);
- }
- _skipVgaWait = true;
- } else {
- if (_subtitles && _scriptVar2) {
- animate(4, 2, 204, 0, 0, 0);
- waitForSync(204);
- stopAnimate(204);
- }
- if (vgaSpriteId < 100)
- stopAnimate(vgaSpriteId + 201);
+void AGOSEngine_Simon1::playSpeech(uint16 speech_id, uint16 vgaSpriteId) {
+ if (speech_id == 9999) {
+ if (_subtitles)
+ return;
+ if (!getBitFlag(14) && !getBitFlag(28)) {
+ setBitFlag(14, true);
+ _variableArray[100] = 15;
+ animate(4, 1, 130, 0, 0, 0);
+ waitForSync(130);
+ }
+ _skipVgaWait = true;
+ } else {
+ if (_subtitles && _scriptVar2) {
+ animate(4, 2, 204, 0, 0, 0);
+ waitForSync(204);
+ stopAnimate(204);
+ }
+ if (vgaSpriteId < 100)
+ stopAnimate(201 + vgaSpriteId);
- loadVoice(speech_id);
+ loadVoice(speech_id);
- if (vgaSpriteId < 100)
- animate(4, 2, vgaSpriteId + 201, 0, 0, 0);
+ if (vgaSpriteId < 100)
+ animate(4, 2, 201 + vgaSpriteId, 0, 0, 0);
+ }
+}
+
+void AGOSEngine_Simon2::playSpeech(uint16 speech_id, uint16 vgaSpriteId) {
+ if (speech_id == 0xFFFF) {
+ if (_subtitles)
+ return;
+ if (!getBitFlag(14) && !getBitFlag(28)) {
+ setBitFlag(14, true);
+ _variableArray[100] = 5;
+ animate(4, 1, 30, 0, 0, 0);
+ waitForSync(130);
}
+ _skipVgaWait = true;
} else {
- if (speech_id == 0xFFFF) {
- if (_subtitles)
- return;
- if (!getBitFlag(14) && !getBitFlag(28)) {
- setBitFlag(14, true);
- _variableArray[100] = 5;
- animate(4, 1, 30, 0, 0, 0);
- waitForSync(130);
- }
- _skipVgaWait = true;
- } else {
- if (getGameType() == GType_SIMON2 && _subtitles && _language != Common::HB_ISR) {
- loadVoice(speech_id);
- return;
- }
-
- if (_subtitles && _scriptVar2) {
- animate(4, 2, 5, 0, 0, 0);
- waitForSync(205);
- stopAnimateSimon2(2,5);
- }
-
- stopAnimateSimon2(2, vgaSpriteId + 2);
+ if (getGameType() == GType_SIMON2 && _subtitles && _language != Common::HB_ISR) {
loadVoice(speech_id);
- animate(4, 2, vgaSpriteId + 2, 0, 0, 0);
+ return;
+ }
+
+ if (_subtitles && _scriptVar2) {
+ animate(4, 2, 5, 0, 0, 0);
+ waitForSync(205);
+ stopAnimateSimon2(2,5);
}
+
+ stopAnimateSimon2(2, vgaSpriteId + 2);
+ loadVoice(speech_id);
+ animate(4, 2, vgaSpriteId + 2, 0, 0, 0);
}
}
@@ -120,9 +120,26 @@ void AGOSEngine::skipSpeech() {
}
}
-void AGOSEngine::loadModule(uint music) {
- _mixer->stopHandle(_modHandle);
+void AGOSEngine::loadMusic(uint16 music) {
+ char buf[4];
+
+ stopMusic();
+
+ _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET);
+ _gameFile->read(buf, 4);
+ if (!memcmp(buf, "FORM", 4)) {
+ _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET);
+ _midi.loadXMIDI(_gameFile);
+ } else {
+ _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET);
+ _midi.loadMultipleSMF(_gameFile);
+ }
+ _lastMusicPlayed = music;
+ _nextMusicToPlay = -1;
+}
+
+void AGOSEngine::playModule(uint16 music) {
char filename[15];
File f;
@@ -135,7 +152,7 @@ void AGOSEngine::loadModule(uint music) {
f.open(filename);
if (f.isOpen() == false) {
- error("loadModule: Can't load module from '%s'", filename);
+ error("playModule: Can't load module from '%s'", filename);
}
Audio::AudioStream *audioStream;
@@ -145,7 +162,7 @@ void AGOSEngine::loadModule(uint music) {
uint srcSize = f.size();
byte *srcBuf = (byte *)malloc(srcSize);
if (f.read(srcBuf, srcSize) != srcSize)
- error("loadModule: Read failed");
+ error("playModule: Read failed");
uint dstSize = READ_BE_UINT32(srcBuf + srcSize - 4);
byte *dstBuf = (byte *)malloc(dstSize);
@@ -162,93 +179,93 @@ void AGOSEngine::loadModule(uint music) {
_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_modHandle, audioStream);
}
-void AGOSEngine::loadMusic(uint music) {
- char buf[4];
+void AGOSEngine_Simon1::playMusic(uint16 music, uint16 track) {
+ stopMusic();
- if (getGameType() == GType_SIMON2) {
- _midi.stop();
- _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET);
+ // Support for compressed music from the ScummVM Music Enhancement Project
+ AudioCD.stop();
+ AudioCD.play(music + 1, -1, 0, 0);
+ if (AudioCD.isPlaying())
+ return;
+
+ if (getGameId() == GID_SIMON1ACORN) {
+ // TODO: Add support for Desktop Tracker format
+ } else if (getPlatform() == Common::kPlatformAmiga) {
+ playModule(music);
+ } else if (getFeatures() & GF_TALKIE) {
+ char buf[4];
+
+ // WORKAROUND: For a script bug in the CD versions
+ // We skip this music resource, as it was replaced by
+ // a sound effect, and the script was never updated.
+ if (music == 35)
+ return;
+
+ _midi.setLoop(true); // Must do this BEFORE loading music. (GMF may have its own override.)
+
+ _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET);
_gameFile->read(buf, 4);
- if (!memcmp(buf, "FORM", 4)) {
- _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET);
- _midi.loadXMIDI(_gameFile);
+ if (!memcmp(buf, "GMF\x1", 4)) {
+ _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET);
+ _midi.loadSMF(_gameFile, music);
} else {
- _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music - 1], SEEK_SET);
+ _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET);
_midi.loadMultipleSMF(_gameFile);
}
- _lastMusicPlayed = music;
- _nextMusicToPlay = -1;
- } else if (getGameType() == GType_SIMON1) {
- _midi.stop();
+ _midi.startTrack(0);
+ _midi.startTrack(track);
+ } else {
+ char filename[15];
+ File f;
+ sprintf(filename, "MOD%d.MUS", music);
+ f.open(filename);
+ if (f.isOpen() == false)
+ error("playMusic: Can't load music from '%s'", filename);
+
_midi.setLoop(true); // Must do this BEFORE loading music. (GMF may have its own override.)
- // Support for compressed music from the ScummVM Music Enhancement Project
- AudioCD.stop();
- AudioCD.play(music + 1, -1, 0, 0);
- if (AudioCD.isPlaying())
- return;
+ if (getFeatures() & GF_DEMO)
+ _midi.loadS1D(&f);
+ else
+ _midi.loadSMF(&f, music);
- if (getGameId() == GID_SIMON1ACORN) {
- // TODO: Add support for Desktop Tracker format
- } else if (getPlatform() == Common::kPlatformAmiga) {
- loadModule(music);
- } else if (getFeatures() & GF_TALKIE) {
- // WORKAROUND: For a script bug in the CD versions
- // We skip this music resource, as it was replaced by
- // a sound effect, and the script was never updated.
- if (music == 35)
- return;
+ _midi.startTrack(0);
+ _midi.startTrack(track);
+ }
+}
- _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET);
- _gameFile->read(buf, 4);
- if (!memcmp(buf, "GMF\x1", 4)) {
- _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET);
- _midi.loadSMF(_gameFile, music);
- } else {
- _gameFile->seek(_gameOffsetsPtr[_musicIndexBase + music], SEEK_SET);
- _midi.loadMultipleSMF(_gameFile);
- }
-
- _midi.startTrack(0);
- } else {
- char filename[15];
- File f;
- sprintf(filename, "MOD%d.MUS", music);
- f.open(filename);
- if (f.isOpen() == false)
- error("loadMusic: Can't load music from '%s'", filename);
-
- if (getFeatures() & GF_DEMO)
- _midi.loadS1D(&f);
- else
- _midi.loadSMF(&f, music);
+void AGOSEngine::playMusic(uint16 music, uint16 track) {
+ stopMusic();
- _midi.startTrack(0);
- }
+ if (getPlatform() == Common::kPlatformAmiga) {
+ playModule(music);
+ } else if (getPlatform() == Common::kPlatformAtariST) {
+ // TODO: Add support for music formats used
} else {
- if (getPlatform() == Common::kPlatformAmiga) {
- loadModule(music);
- } else if (getPlatform() == Common::kPlatformAtariST) {
- // TODO: Add support for music formats used
- } else {
- _midi.stop();
- _midi.setLoop(true); // Must do this BEFORE loading music.
+ _midi.setLoop(true); // Must do this BEFORE loading music.
- char filename[15];
- File f;
- sprintf(filename, "MOD%d.MUS", music);
- f.open(filename);
- if (f.isOpen() == false)
- error("loadMusic: Can't load music from '%s'", filename);
-
- _midi.loadS1D(&f);
- _midi.startTrack(0);
- }
+ char filename[15];
+ File f;
+ sprintf(filename, "MOD%d.MUS", music);
+ f.open(filename);
+ if (f.isOpen() == false)
+ error("playMusic: Can't load music from '%s'", filename);
+
+ _midi.loadS1D(&f);
+ _midi.startTrack(0);
+ _midi.startTrack(track);
}
}
-void AGOSEngine::playSting(uint a) {
+void AGOSEngine::stopMusic() {
+ if (_midiEnabled) {
+ _midi.stop();
+ }
+ _mixer->stopHandle(_modHandle);
+}
+
+void AGOSEngine::playSting(uint16 soundId) {
if (!_midi._enable_sfx)
return;
@@ -262,13 +279,13 @@ void AGOSEngine::playSting(uint a) {
if (!mus_file.isOpen())
error("playSting: Can't load sound effect from '%s'", filename);
- mus_file.seek(a * 2, SEEK_SET);
+ mus_file.seek(soundId * 2, SEEK_SET);
mus_offset = mus_file.readUint16LE();
if (mus_file.ioFailed())
- error("playSting: Can't read sting %d offset", a);
+ error("playSting: Can't read sting %d offset", soundId);
mus_file.seek(mus_offset, SEEK_SET);
- _midi.loadSMF(&mus_file, a, true);
+ _midi.loadSMF(&mus_file, soundId, true);
_midi.startTrack(0);
}
@@ -284,7 +301,7 @@ static const byte elvira1_soundTable[100] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
-bool AGOSEngine::loadVGASoundFile(uint id, uint type) {
+bool AGOSEngine::loadVGASoundFile(uint16 id, uint8 type) {
File in;
char filename[15];
byte *dst;
diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp
index f7c0254c4f..af1bd0fe93 100644
--- a/engines/agos/rooms.cpp
+++ b/engines/agos/rooms.cpp
@@ -351,7 +351,7 @@ void AGOSEngine_Elvira2::setSRExit(Item *i, int n, int d, uint16 s) {
}
// Waxworks specific
-bool AGOSEngine::loadRoomItems(uint item) {
+bool AGOSEngine::loadRoomItems(uint16 item) {
byte *p;
uint i, min_num, max_num;
char filename[30];
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 1267e27daa..eb2266550a 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -109,7 +109,7 @@ void AGOSEngine::quickLoadOrSave() {
setBitFlag(7, false);
sub = getSubroutineByID(19);
startSubroutine(sub);
- //oe2_printStats();
+ printStats();
sub = getSubroutineByID(28);
startSubroutine(sub);
setBitFlag(17, false);
@@ -146,7 +146,171 @@ void AGOSEngine::quickLoadOrSave() {
_saveLoadType = 0;
}
-void AGOSEngine::listSaveGames(char *dst) {
+bool AGOSEngine::confirmOverWrite(WindowBlock *window) {
+ if (getGameType() == GType_WW) {
+ Subroutine *sub = getSubroutineByID(80);
+ if (sub != NULL)
+ startSubroutineEx(sub);
+
+ if (_variableArray[253] == 0)
+ return true;
+ } else if (getGameType() == GType_ELVIRA2) {
+ // Original verison never confirmed
+ return true;
+ } else if (getGameType() == GType_ELVIRA1) {
+ const char *message1, *message2, *message3;
+
+ switch (_language) {
+ case Common::FR_FRA:
+ message1 = "\rFichier d/j; existant.\r\r";
+ message2 = " Ecrire pardessus ?\r\r";
+ message3 = " Oui Non";
+ break;
+ case Common::DE_DEU:
+ message1 = "\rDatei existiert bereits.\r\r";
+ message2 = " berschreiben ?\r\r";
+ message3 = " Ja Nein";
+ break;
+ default:
+ message1 = "\r File already exists.\r\r";
+ message2 = " Overwrite it ?\r\r";
+ message3 = " Yes No";
+ break;
+ }
+
+ printScroll();
+ window->textColumn = 0;
+ window->textRow = 0;
+ window->textColumnOffset = 0;
+ window->textLength = 0; // Difference
+
+ for (; *message1; message1++)
+ windowPutChar(window, *message1);
+ for (; *message2; message2++)
+ windowPutChar(window, *message2);
+ for (; *message3; message3++)
+ windowPutChar(window, *message3);
+
+ if (confirmYesOrNo(120, 78) == 0x7FFF)
+ return true;
+ }
+
+ return false;
+}
+
+int16 AGOSEngine::matchSaveGame(const char *name, uint16 max) {
+ Common::InSaveFile *in;
+ char dst[8];
+ uint16 slot;
+
+ for (slot = 0; slot < max; slot++) {
+ if ((in = _saveFileMan->openForLoading(genSaveName(slot)))) {
+ in->read(dst, 8);
+ delete in;
+
+ if (!scumm_stricmp(name, dst)) {
+ return slot;
+ }
+ }
+ }
+
+ return -1;
+}
+
+void AGOSEngine::userGame(bool load) {
+ WindowBlock *window = _windowArray[4];
+ const char *message1;
+ int i, numSaveGames;
+ char *name;
+ char buf[8];
+
+ numSaveGames = countSaveGames();
+
+ time_t saveTime = time(NULL);
+ haltAnimation();
+
+restart:
+ printScroll();
+ window->textColumn = 0;
+ window->textRow = 0;
+ window->textColumnOffset = 0;
+ window->textLength = 0; // Difference
+
+ switch (_language) {
+ case Common::FR_FRA:
+ message1 = "\rIns/rez disquette de\rsauvegarde de jeux &\rentrez nom de fichier:\r\r ";
+ break;
+ case Common::DE_DEU:
+ message1 = "\rLege Spielstandsdiskette ein. Dateinamen eingeben:\r\r ";
+ break;
+ default:
+ message1 = "\r Insert savegame data disk & enter filename:\r\r ";
+ break;
+ }
+
+ for (; *message1; message1++)
+ windowPutChar(window, *message1);
+
+ memset(buf, 0, 8);
+ name = buf;
+ _saveGameNameLen = 0;
+
+ for (;;) {
+ windowPutChar(window, 128);
+ _keyPressed = 0;
+
+ for (;;) {
+ delay(10);
+ if (_keyPressed && _keyPressed < 128) {
+ i = _keyPressed;
+ break;
+ }
+ }
+
+ userGameBackSpace(_windowArray[4], 8);
+ if (i == 10 || i == 13) {
+ break;
+ } else if (i == 8) {
+ // do_backspace
+ if (_saveGameNameLen) {
+ _saveGameNameLen--;
+ name[_saveGameNameLen] = 0;
+ userGameBackSpace(_windowArray[4], 8);
+ }
+ } else if (i >= 32 && _saveGameNameLen != 8) {
+ name[_saveGameNameLen++] = i;
+ windowPutChar(_windowArray[4], i);
+ }
+ }
+
+ if (_saveGameNameLen != 0) {
+ int16 slot = matchSaveGame(name, numSaveGames);
+ if (!load) {
+ if (slot >= 0 && !confirmOverWrite(window))
+ goto restart;
+
+ if (slot < 0)
+ slot = numSaveGames;
+
+ if (!saveGame(slot, name))
+ fileError(_windowArray[4], true);
+ } else {
+ if (slot < 0) {
+ fileError(_windowArray[4], false);
+ } else {
+ if (!loadGame(genSaveName(slot)))
+ fileError(_windowArray[4], false);
+ }
+ }
+
+ printStats();
+ }
+
+ restartAnimation();
+ _gameStoppedClock = time(NULL) - saveTime + _gameStoppedClock;
+}
+
+void AGOSEngine_Elvira2::listSaveGames(char *dst) {
Common::InSaveFile *in;
uint y, slot;
@@ -166,7 +330,7 @@ void AGOSEngine::listSaveGames(char *dst) {
slot = _saveLoadRowCurPos;
for (y = 0; y < 8; y++) {
window->textColumn = 0;
- window->textColumnOffset = 4;
+ window->textColumnOffset = (getGameType() == GType_ELVIRA2) ? 4 : 0;
window->textLength = 0;
if ((in = _saveFileMan->openForLoading(genSaveName(slot++)))) {
in->read(dst, 8);
@@ -180,8 +344,13 @@ void AGOSEngine::listSaveGames(char *dst) {
}
dst+= 8;
- window->textColumn = 7;
- window->textColumnOffset = 4;
+ if (getGameType() == GType_WW) {
+ window->textColumn = 7;
+ window->textColumnOffset = 4;
+ } else if (getGameType() == GType_ELVIRA2) {
+ window->textColumn = 8;
+ window->textColumnOffset = 0;
+ }
window->textLength = 0;
if ((in = _saveFileMan->openForLoading(genSaveName(slot++)))) {
in->read(dst, 8);
@@ -196,7 +365,7 @@ void AGOSEngine::listSaveGames(char *dst) {
dst+= 8;
window->textColumn = 15;
- window->textColumnOffset = 4;
+ window->textColumnOffset = (getGameType() == GType_ELVIRA2) ? 4 : 0;
window->textLength = 0;
if ((in = _saveFileMan->openForLoading(genSaveName(slot++)))) {
in->read(dst, 8);
@@ -221,7 +390,7 @@ void AGOSEngine::listSaveGames(char *dst) {
_saveGameNameLen = 0;
}
-void AGOSEngine::userGame(bool load) {
+void AGOSEngine_Elvira2::userGame(bool load) {
time_t saveTime;
int i, numSaveGames;
char *name;
@@ -246,6 +415,8 @@ void AGOSEngine::userGame(bool load) {
if (!load) {
WindowBlock *window = _windowArray[num];
+ int16 slot = -1;
+
name = buf + 192;
for (;;) {
@@ -256,15 +427,9 @@ void AGOSEngine::userGame(bool load) {
i = userGameGetKey(&b, buf, 128);
if (b) {
if (i <= 223) {
- if (getGameType() == GType_WW) {
- Subroutine *sub = getSubroutineByID(80);
- if (sub != NULL)
- startSubroutineEx(sub);
-
- if (_variableArray[253] != 0) {
- listSaveGames(buf);
- continue;
- }
+ if (!confirmOverWrite(window)) {
+ listSaveGames(buf);
+ continue;
}
if (!saveGame(_saveLoadRowCurPos + i, buf + i * 8))
@@ -275,9 +440,16 @@ void AGOSEngine::userGame(bool load) {
}
userGameBackSpace(_windowArray[num], 8);
- if (i == 10 || i == 13)
+ if (i == 10 || i == 13) {
+ slot = matchSaveGame(name, numSaveGames);
+ if (slot >= 0) {
+ if (!confirmOverWrite(window)) {
+ listSaveGames(buf);
+ continue;
+ }
+ }
break;
- if (i == 8) {
+ } else if (i == 8) {
// do_backspace
if (_saveGameNameLen) {
_saveGameNameLen--;
@@ -290,8 +462,13 @@ void AGOSEngine::userGame(bool load) {
}
}
- if (!saveGame(numSaveGames, buf + 192))
- fileError(_windowArray[num], true);
+ if (_saveGameNameLen != 0) {
+ if (slot < 0)
+ slot = numSaveGames;
+
+ if (!saveGame(slot, buf + 192))
+ fileError(_windowArray[num], true);
+ }
} else {
i = userGameGetKey(&b, buf, 128);
if (i != 225) {
@@ -309,7 +486,7 @@ get_out:;
restartAnimation();
}
-int AGOSEngine::userGameGetKey(bool *b, char *buf, uint maxChar) {
+int AGOSEngine_Elvira2::userGameGetKey(bool *b, char *buf, uint maxChar) {
HitArea *ha;
*b = true;
@@ -359,26 +536,29 @@ void AGOSEngine_Simon1::listSaveGames(char *dst) {
if (!(in = _saveFileMan->openForLoading(genSaveName(slot))))
break;
- in->read(dst, 8);
+ in->read(dst, 18);
delete in;
lastSlot = slot;
if (slot < 10) {
showMessageFormat(" ");
+ } else if (_language == Common::HB_ISR) {
+ lastSlot = (slot % 10) * 10;
+ lastSlot += slot / 10;
}
+ showMessageFormat("%d", lastSlot);
if (_language == Common::HB_ISR && !(slot % 10))
showMessageFormat("0");
- showMessageFormat("%d", lastSlot);
showMessageFormat(".%s\n", dst);
dst += 18;
slot++;
}
if (!_saveOrLoad) {
- if (_saveLoadRowCurPos + 6 == slot)
+ if (_saveLoadRowCurPos + 6 == slot) {
slot++;
- else {
+ } else {
if (slot < 10)
showMessageFormat(" ");
showMessageFormat("%d.\n", slot);
@@ -532,9 +712,9 @@ restart:;
}
userGameBackSpace(_windowArray[5], 8);
- if (i == 10 || i == 13)
+ if (i == 10 || i == 13) {
break;
- if (i == 8) {
+ } else if (i == 8) {
// do_backspace
if (_saveGameNameLen) {
byte m, x;
@@ -732,7 +912,16 @@ void AGOSEngine::fileError(WindowBlock *window, bool save_error) {
}
}
- windowPutChar(window, 0xC);
+ if (getGameType() == GType_ELVIRA1) {
+ printScroll();
+ window->textColumn = 0;
+ window->textRow = 0;
+ window->textColumnOffset = 0;
+ window->textLength = 0; // Difference
+ } else {
+ windowPutChar(window, 12);
+ }
+
for (; *message1; message1++)
windowPutChar(window, *message1);
for (; *message2; message2++)
@@ -954,7 +1143,9 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
return false;
}
- if (getGameType() == GType_FF) {
+ if (getGameType() == GType_PP) {
+ // No caption
+ } else if (getGameType() == GType_FF) {
f->read(ident, 100);
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
f->read(ident, 18);
@@ -1104,7 +1295,9 @@ bool AGOSEngine_Elvira2::saveGame(uint slot, const char *caption) {
return false;
}
- if (getGameType() == GType_FF) {
+ if (getGameType() == GType_PP) {
+ // No caption
+ } else if (getGameType() == GType_FF) {
f->write(caption, 100);
curTime = time(NULL);
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
diff --git a/engines/agos/script.cpp b/engines/agos/script.cpp
index 8a4457faf2..c5cf6c5872 100644
--- a/engines/agos/script.cpp
+++ b/engines/agos/script.cpp
@@ -156,7 +156,7 @@ void AGOSEngine::o_gtf() {
void AGOSEngine::o_chance() {
// 23: chance
- uint a = getVarOrWord();
+ int16 a = getVarOrWord();
if (a == 0) {
setScriptCondition(false);
@@ -173,7 +173,7 @@ void AGOSEngine::o_chance() {
if (a <= 0) {
_chanceModifier = 0;
setScriptCondition(false);
- } else if ((uint)_rnd.getRandomNumber(99) < a) {
+ } else if ((int16)_rnd.getRandomNumber(99) < a) {
if (_chanceModifier <= 0)
_chanceModifier -= 5;
else
@@ -410,7 +410,7 @@ void AGOSEngine::o_process() {
void AGOSEngine::o_when() {
// 76: add timeout
- uint timeout = getVarOrWord();
+ uint16 timeout = getVarOrWord();
addTimeEvent(timeout, getVarOrWord());
}
@@ -453,7 +453,7 @@ void AGOSEngine::o_haltAnimation() {
if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
VgaTimerEntry *vte = _vgaTimerList;
while (vte->delay) {
- if (vte->type == 0)
+ if (vte->type == ANIMATE_EVENT)
vte->delay += 10;
vte++;
}
@@ -508,7 +508,14 @@ void AGOSEngine::o_picture() {
return;
}
- _picture8600 = (vga_res == 8600);
+ if (getGameType() == GType_PP && getGameId() != GID_DIMP) {
+ if (vga_res == 8700 && getBitFlag(107)) {
+ _vgaPeriod = 30;
+ }
+
+ _picture8600 = (vga_res == 8600);
+ }
+
setWindowImageEx(mode, vga_res);
}
@@ -722,13 +729,12 @@ void AGOSEngine::o_doClassIcons() {
void AGOSEngine::o_playTune() {
// 127: play tune
- int music = getVarOrWord();
- int track = getVarOrWord();
+ uint16 music = getVarOrWord();
+ uint16 track = getVarOrWord();
if (music != _lastMusicPlayed) {
_lastMusicPlayed = music;
- loadMusic(music);
- _midi.startTrack(track);
+ playMusic(music, track);
}
}
@@ -746,16 +752,32 @@ void AGOSEngine::o_setAdjNoun() {
void AGOSEngine::o_saveUserGame() {
// 132: save user game
- _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
- userGame(false);
- _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+ if (getGameId() == GID_SIMON1CD32) {
+ // The Amiga CD32 version of Simon the Sorcerer 1uses a single slot
+ if (!saveGame(0, "Default Saved Game")) {
+ vc33_setMouseOn();
+ fileError(_windowArray[5], true);
+ }
+ } else {
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+ userGame(false);
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+ }
}
void AGOSEngine::o_loadUserGame() {
// 133: load user game
- _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
- userGame(true);
- _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+ if (getGameId() == GID_SIMON1CD32) {
+ // The Amiga CD32 version of Simon the Sorcerer 1 uses a single slot
+ if (!loadGame(genSaveName(0))) {
+ vc33_setMouseOn();
+ fileError(_windowArray[5], false);
+ }
+ } else {
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
+ userGame(true);
+ _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
+ }
}
void AGOSEngine::o_copysf() {
@@ -872,7 +894,7 @@ uint AGOSEngine::getNextVarContents() {
return (uint16)readVariable(getVarWrapper());
}
-uint AGOSEngine::readVariable(uint variable) {
+uint AGOSEngine::readVariable(uint16 variable) {
if (variable >= _numVars)
error("readVariable: Variable %d out of range", variable);
@@ -892,7 +914,7 @@ void AGOSEngine::writeNextVarContents(uint16 contents) {
writeVariable(getVarWrapper(), contents);
}
-void AGOSEngine::writeVariable(uint variable, uint16 contents) {
+void AGOSEngine::writeVariable(uint16 variable, uint16 contents) {
if (variable >= _numVars)
error("writeVariable: Variable %d out of range", variable);
@@ -978,7 +1000,7 @@ void AGOSEngine::sendSync(uint a) {
_lockWord &= ~0x8000;
}
-void AGOSEngine::stopAnimate(uint a) {
+void AGOSEngine::stopAnimate(uint16 a) {
uint16 b = to16Wrapper(a);
_lockWord |= 0x8000;
_vcPtr = (byte *)&b;
@@ -987,7 +1009,7 @@ void AGOSEngine::stopAnimate(uint a) {
}
void AGOSEngine::waitForSync(uint a) {
- const uint maxCount = (getGameType() == GType_SIMON1) ? 500 : 1000;
+ const uint maxCount = (getGameType() == GType_SIMON1) ? 1000 : 2500;
if (getGameType() == GType_SIMON1 && (getFeatures() & GF_TALKIE)) {
if (a != 200) {
diff --git a/engines/agos/script_e1.cpp b/engines/agos/script_e1.cpp
index 06c347f391..b003a7262f 100644
--- a/engines/agos/script_e1.cpp
+++ b/engines/agos/script_e1.cpp
@@ -370,8 +370,8 @@ void AGOSEngine_Elvira1::setupOpcodes() {
OPCODE(o_setAdjNoun),
OPCODE(oe1_zoneDisk),
/* 268 */
- OPCODE(oe1_saveUserGame),
- OPCODE(oe1_loadUserGame),
+ OPCODE(o_saveUserGame),
+ OPCODE(o_loadUserGame),
OPCODE(oe1_printStats),
OPCODE(oe1_stopTune),
/* 272 */
@@ -707,8 +707,8 @@ void AGOSEngine_Elvira1::oe1_loadGame() {
uint16 stringId = getNextStringID();
debug(0, "oe1_loadGame: stub (%s)", (const char *)getStringPtrByID(stringId));
- if (!scumm_stricmp(getFileName(GAME_RESTFILE), (const char *)getStringPtrByID(stringId))) {
- loadGame(getFileName(GAME_RESTFILE), true);
+ if (!scumm_stricmp("START", (const char *)getStringPtrByID(stringId))) {
+ loadGame("START", true);
} else {
loadGame((const char *)getStringPtrByID(stringId));
}
@@ -843,20 +843,16 @@ void AGOSEngine_Elvira1::oe1_ifTime() {
void AGOSEngine_Elvira1::oe1_playTune() {
// 264: play tune
- int music = getVarOrWord();
- int track = getVarOrWord();
+ uint16 music = getVarOrWord();
+ uint16 track = getVarOrWord();
if (music != _lastMusicPlayed) {
_lastMusicPlayed = music;
// No tune under water
if (music == 4) {
- if (getPlatform() == Common::kPlatformAmiga)
- _mixer->stopHandle(_modHandle);
- else
- _midi.stop();
+ stopMusic();
} else {
- loadMusic(music);
- _midi.startTrack(track);
+ playMusic(music, track);
}
}
}
@@ -867,72 +863,9 @@ void AGOSEngine_Elvira1::oe1_zoneDisk() {
getVarOrWord();
}
-void AGOSEngine_Elvira1::oe1_saveUserGame() {
- // TODO
-}
-
-void AGOSEngine_Elvira1::oe1_loadUserGame() {
- // TODO
-}
-
void AGOSEngine_Elvira1::oe1_printStats() {
// 270: print stats
- WindowBlock *window = _dummyWindow;
- int val;
-
- window->flags = 1;
-
- mouseOff();
-
- // Strength
- val = _variableArray[0];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 5, 133, 6, val);
-
- // Resolution
- val = _variableArray[1];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 11, 133, 6, val);
-
- // Dexterity
- val = _variableArray[2];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 18, 133, 0, val);
-
- // Skill
- val = _variableArray[3];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 24, 133, 0, val);
-
- // Life
- val = _variableArray[5];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 30, 133, 2, val);
-
- // Experience
- val = _variableArray[6];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 36, 133, 4, val);
-
- mouseOn();
+ printStats();
}
void AGOSEngine_Elvira1::oe1_stopTune() {
@@ -1021,7 +954,7 @@ restart:
for (; *message2; message2++)
windowPutChar(window, *message2);
- if (confirmQuit() == 0x7FFF) {
+ if (confirmYesOrNo(120, 62) == 0x7FFF) {
shutdown();
} else {
goto restart;
@@ -1108,12 +1041,12 @@ l1: i = derefItem(i->next);
}
}
-uint AGOSEngine::confirmQuit() {
+uint AGOSEngine::confirmYesOrNo(uint16 x, uint16 y) {
HitArea *ha;
ha = findEmptyHitArea();
- ha->x = 120;
- ha->y = 62;
+ ha->x = x;
+ ha->y = y;
ha->width = 30;
ha->height = 12;
ha->flags = kBFBoxInUse;
@@ -1122,8 +1055,8 @@ uint AGOSEngine::confirmQuit() {
ha->window = 0;
ha = findEmptyHitArea();
- ha->x = 180;
- ha->y = 62;
+ ha->x = x + 60;
+ ha->y = y;
ha->width = 24;
ha->height = 12;
ha->flags = kBFBoxInUse;
@@ -1207,25 +1140,73 @@ uint AGOSEngine::continueOrQuit() {
}
void AGOSEngine::printScroll() {
- VC10_state state;
VgaPointersEntry *vpe = &_vgaBufferPointers[1];
+ byte *curVgaFile2Orig = _curVgaFile2;
+
+ _windowNum = 3;
+ _curVgaFile2 = vpe->vgaFile2;
+ drawImage_init(9, 0, 10, 32, 0);
+
+ _curVgaFile2 = curVgaFile2Orig;
+}
+
+void AGOSEngine::printStats() {
+ WindowBlock *window = _dummyWindow;
+ int val;
+
+ window->flags = 1;
+
+ mouseOff();
+
+ // Strength
+ val = _variableArray[0];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 5, 133, 6, val);
+
+ // Resolution
+ val = _variableArray[1];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 11, 133, 6, val);
- state.srcPtr = vpe->vgaFile2 + READ_BE_UINT32(vpe->vgaFile2 + 9 * 8);
+ // Dexterity
+ val = _variableArray[2];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 18, 133, 0, val);
+
+ // Skill
+ val = _variableArray[3];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 24, 133, 0, val);
- state.palette = 0;
- state.paletteMod = 0;
- state.x = 10;
- state.y = 32;
- state.width = state.draw_width = 10;
- state.height = state.draw_height = 72;
- state.flags = kDFCompressed;
- _windowNum = 3;
+ // Life
+ val = _variableArray[5];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 30, 133, 2, val);
- state.depack_cont = -0x80;
- state.x_skip = 0;
- state.y_skip = 0;
+ // Experience
+ val = _variableArray[6];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 36, 133, 4, val);
- drawImage(&state);
+ mouseOn();
}
} // End of namespace AGOS
diff --git a/engines/agos/script_e2.cpp b/engines/agos/script_e2.cpp
index 13cb15a8b9..00f0848ed9 100644
--- a/engines/agos/script_e2.cpp
+++ b/engines/agos/script_e2.cpp
@@ -145,7 +145,7 @@ void AGOSEngine_Elvira2::setupOpcodes() {
OPCODE(o_comment),
/* 88 */
OPCODE(o_invalid),
- OPCODE(oe1_loadGame),
+ OPCODE(oe2_loadGame),
OPCODE(o_getParent),
OPCODE(o_getNext),
/* 92 */
@@ -315,6 +315,17 @@ void AGOSEngine_Elvira2::oe2_pObj() {
showMessageFormat("%s\n", (const char *)getStringPtrByID(subObject->objectFlagValue[0])); // Difference
}
+void AGOSEngine_Elvira2::oe2_loadGame() {
+ // 89: load game
+ uint16 stringId = getNextStringID();
+
+ if (!scumm_stricmp(getFileName(GAME_RESTFILE), (const char *)getStringPtrByID(stringId))) {
+ loadGame(getFileName(GAME_RESTFILE), true);
+ } else {
+ loadGame((const char *)getStringPtrByID(stringId));
+ }
+}
+
void AGOSEngine_Elvira2::oe2_drawItem() {
// 113: draw item
Item *i = getNextItemPtr();
@@ -498,48 +509,7 @@ void AGOSEngine_Elvira2::oe2_ink() {
void AGOSEngine_Elvira2::oe2_printStats() {
// 161: print stats
- WindowBlock *window = _dummyWindow;
- int val;
- const uint8 y = (getPlatform() == Common::kPlatformAtariST) ? 131 : 134;
-
- window->flags = 1;
-
- mouseOff();
-
- // Level
- val = _variableArray[20];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 10, y, 0, val);
-
- // PP
- val = _variableArray[22];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 16, y, 6, val);
-
- // HP
- val = _variableArray[23];
- if (val < -99)
- val = -99;
- if (val > 99)
- val = 99;
- writeChar(window, 23, y, 4, val);
-
- // Experience
- val = _variableArray[21];
- if (val < -99)
- val = -99;
- if (val > 9999)
- val = 9999;
- writeChar(window, 30, y, 6, val / 100);
- writeChar(window, 32, y, 2, val / 10);
-
- mouseOn();
+ printStats();
}
void AGOSEngine_Elvira2::oe2_setSuperRoom() {
@@ -697,4 +667,49 @@ void AGOSEngine_Elvira2::oe2_b2NotZero() {
setScriptCondition((_bitArrayTwo[bit / 16] & (1 << (bit & 15))) != 0);
}
+void AGOSEngine_Elvira2::printStats() {
+ WindowBlock *window = _dummyWindow;
+ int val;
+ const uint8 y = (getPlatform() == Common::kPlatformAtariST) ? 131 : 134;
+
+ window->flags = 1;
+
+ mouseOff();
+
+ // Level
+ val = _variableArray[20];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 10, y, 0, val);
+
+ // PP
+ val = _variableArray[22];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 16, y, 6, val);
+
+ // HP
+ val = _variableArray[23];
+ if (val < -99)
+ val = -99;
+ if (val > 99)
+ val = 99;
+ writeChar(window, 23, y, 4, val);
+
+ // Experience
+ val = _variableArray[21];
+ if (val < -99)
+ val = -99;
+ if (val > 9999)
+ val = 9999;
+ writeChar(window, 30, y, 6, val / 100);
+ writeChar(window, 32, y, 2, val / 10);
+
+ mouseOn();
+}
+
} // End of namespace AGOS
diff --git a/engines/agos/script_ff.cpp b/engines/agos/script_ff.cpp
index db36d6f736..c3e6dc5192 100644
--- a/engines/agos/script_ff.cpp
+++ b/engines/agos/script_ff.cpp
@@ -303,7 +303,7 @@ void AGOSEngine_Feeble::executeOpcode(int opcode) {
void AGOSEngine_Feeble::off_chance() {
// 23
- uint a = getVarOrWord();
+ uint16 a = getVarOrWord();
if (a == 0) {
setScriptCondition(false);
@@ -315,7 +315,7 @@ void AGOSEngine_Feeble::off_chance() {
return;
}
- if ((uint)_rnd.getRandomNumber(99) < a)
+ if (_rnd.getRandomNumber(99) < a)
setScriptCondition(true);
else
setScriptCondition(false);
@@ -439,7 +439,7 @@ void AGOSEngine_Feeble::off_listSaveGames() {
void AGOSEngine_Feeble::off_checkCD() {
// 135: switch CD
- uint disc = readVariable(97);
+ uint16 disc = readVariable(97);
if (!strcmp(getExtra(), "4CD")) {
_sound->switchVoiceFile(gss, disc);
@@ -624,10 +624,10 @@ void AGOSEngine_Feeble::off_restartClock() {
void AGOSEngine_Feeble::off_setColour() {
// 195: set palette colour
- uint c = getVarOrByte() * 4;
- uint r = getVarOrByte();
- uint g = getVarOrByte();
- uint b = getVarOrByte();
+ uint16 c = getVarOrByte() * 4;
+ uint8 r = getVarOrByte();
+ uint8 g = getVarOrByte();
+ uint8 b = getVarOrByte();
_displayPalette[c + 0] = r;
_displayPalette[c + 1] = g;
@@ -638,25 +638,25 @@ void AGOSEngine_Feeble::off_setColour() {
void AGOSEngine_Feeble::off_b3Set() {
// 196: set bit3
- uint bit = getVarOrByte();
+ uint8 bit = getVarOrByte();
_bitArrayThree[bit / 16] |= (1 << (bit & 15));
}
void AGOSEngine_Feeble::off_b3Clear() {
// 197: clear bit3
- uint bit = getVarOrByte();
+ uint8 bit = getVarOrByte();
_bitArrayThree[bit / 16] &= ~(1 << (bit & 15));
}
void AGOSEngine_Feeble::off_b3Zero() {
// 198: is bit3 clear
- uint bit = getVarOrByte();
+ uint8 bit = getVarOrByte();
setScriptCondition((_bitArrayThree[bit / 16] & (1 << (bit & 15))) == 0);
}
void AGOSEngine_Feeble::off_b3NotZero() {
// 199: is bit3 set
- uint bit = getVarOrByte();
+ uint8 bit = getVarOrByte();
setScriptCondition((_bitArrayThree[bit / 16] & (1 << (bit & 15))) != 0);
}
diff --git a/engines/agos/script_pp.cpp b/engines/agos/script_pp.cpp
index fd8ef9b859..a7bda53e48 100644
--- a/engines/agos/script_pp.cpp
+++ b/engines/agos/script_pp.cpp
@@ -72,8 +72,8 @@ void AGOSEngine_PuzzlePack::setupOpcodes() {
OPCODE(o_state),
/* 28 */
OPCODE(o_oflag),
- OPCODE(opp_iconifyWindow),
OPCODE(o_invalid),
+ OPCODE(opp_iconifyWindow),
OPCODE(o_destroy),
/* 32 */
OPCODE(opp_restoreOopsPosition),
@@ -238,7 +238,7 @@ void AGOSEngine_PuzzlePack::setupOpcodes() {
/* 160 */
OPCODE(oe2_ink),
OPCODE(off_screenTextBox),
- OPCODE(os1_screenTextMsg),
+ OPCODE(opp_playTune),
OPCODE(o_invalid),
/* 164 */
OPCODE(oe2_getDollar2),
@@ -297,7 +297,7 @@ void AGOSEngine_PuzzlePack::executeOpcode(int opcode) {
void AGOSEngine_PuzzlePack::opp_iconifyWindow() {
// 30
- getNextItemPtr();
+ getNextWord();
if (_clockStopped != 0)
_gameTime += time(NULL) - _clockStopped;
_clockStopped = 0;
@@ -308,7 +308,7 @@ void AGOSEngine_PuzzlePack::opp_restoreOopsPosition() {
// 32: restore oops position
uint i;
- getNextItemPtr();
+ getNextWord();
if (_oopsValid) {
for (i = 0; i < _numVars; i++) {
@@ -328,7 +328,7 @@ void AGOSEngine_PuzzlePack::opp_restoreOopsPosition() {
void AGOSEngine_PuzzlePack::opp_loadMouseImage() {
// 38: load mouse image
- getNextItemPtr();
+ getNextWord();
getVarOrByte();
loadMouseImage();
}
@@ -405,6 +405,19 @@ void AGOSEngine_PuzzlePack::opp_loadUserGame() {
loadGame(genSaveName(1));
}
+void AGOSEngine_PuzzlePack::opp_playTune() {
+ // 162: play tune
+ getVarOrByte();
+ getVarOrByte();
+ getNextWord();
+
+ uint16 music = (uint16)getVarOrWord();
+ if (music != _lastMusicPlayed) {
+ _lastMusicPlayed = music;
+ playSpeech(music, 1);
+ }
+}
+
void AGOSEngine_PuzzlePack::opp_saveOopsPosition() {
// 173: save oops position
if (!isVgaQueueEmpty()) {
diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp
index e104013cae..93b907e688 100644
--- a/engines/agos/script_s1.cpp
+++ b/engines/agos/script_s1.cpp
@@ -374,12 +374,12 @@ void AGOSEngine_Simon1::os1_screenTextMsg() {
uint vgaSpriteId = getVarOrByte();
uint color = getVarOrByte();
uint stringId = getNextStringID();
- const byte *string_ptr = NULL;
+ const byte *stringPtr = NULL;
uint speechId = 0;
TextLocation *tl;
if (stringId != 0xFFFF)
- string_ptr = getStringPtrByID(stringId);
+ stringPtr = getStringPtrByID(stringId);
if (getFeatures() & GF_TALKIE) {
if (getGameType() == GType_FF || getGameType() == GType_PP)
@@ -399,14 +399,14 @@ void AGOSEngine_Simon1::os1_screenTextMsg() {
stopAnimateSimon2(2, vgaSpriteId + 2);
}
- if (string_ptr != NULL && (speechId == 0 || _subtitles))
- printScreenText(vgaSpriteId, color, (const char *)string_ptr, tl->x, tl->y, tl->width);
+ if (stringPtr != NULL && stringPtr[0] != 0 && (speechId == 0 || _subtitles))
+ printScreenText(vgaSpriteId, color, (const char *)stringPtr, tl->x, tl->y, tl->width);
}
void AGOSEngine_Simon1::os1_playEffect() {
// 163: play sound
- uint soundId = getVarOrWord();
+ uint16 soundId = getVarOrWord();
if (getGameId() == GID_SIMON1DOS)
playSting(soundId);
@@ -450,7 +450,7 @@ void AGOSEngine_Simon1::os1_screenTextPObj() {
}
stringPtr = buf;
}
- if (stringPtr != NULL)
+ if (stringPtr != NULL && stringPtr[0] != 0)
printScreenText(vgaSpriteId, color, stringPtr, tl->x, tl->y, tl->width);
}
}
@@ -512,7 +512,7 @@ void AGOSEngine_Simon1::os1_scnTxtLongText() {
uint speechId = 0;
TextLocation *tl;
- const char *string_ptr = (const char *)getStringPtrByID(_longText[stringId]);
+ const char *stringPtr = (const char *)getStringPtrByID(_longText[stringId]);
if (getFeatures() & GF_TALKIE)
speechId = _longSound[stringId];
@@ -522,8 +522,8 @@ void AGOSEngine_Simon1::os1_scnTxtLongText() {
if (_speech && speechId != 0)
playSpeech(speechId, vgaSpriteId);
- if (string_ptr != NULL && _subtitles)
- printScreenText(vgaSpriteId, color, string_ptr, tl->x, tl->y, tl->width);
+ if (stringPtr != NULL && stringPtr[0] != 0 && _subtitles)
+ printScreenText(vgaSpriteId, color, stringPtr, tl->x, tl->y, tl->width);
}
void AGOSEngine_Simon1::os1_mouseOn() {
diff --git a/engines/agos/script_s2.cpp b/engines/agos/script_s2.cpp
index 9041a99662..dfc1200d7c 100644
--- a/engines/agos/script_s2.cpp
+++ b/engines/agos/script_s2.cpp
@@ -323,8 +323,8 @@ void AGOSEngine_Simon2::os2_animate() {
void AGOSEngine_Simon2::os2_stopAnimate() {
// 99: kill sprite
- uint a = getVarOrWord();
- uint b = getVarOrWord();
+ uint16 a = getVarOrWord();
+ uint16 b = getVarOrWord();
stopAnimateSimon2(a, b);
}
@@ -469,7 +469,7 @@ void AGOSEngine_Simon2::os2_waitMark() {
waitForMark(i);
}
-void AGOSEngine::stopAnimateSimon2(uint a, uint b) {
+void AGOSEngine::stopAnimateSimon2(uint16 a, uint16 b) {
uint16 items[2];
items[0] = to16Wrapper(a);
diff --git a/engines/agos/script_ww.cpp b/engines/agos/script_ww.cpp
index 690a717acf..377b49ae3f 100644
--- a/engines/agos/script_ww.cpp
+++ b/engines/agos/script_ww.cpp
@@ -147,7 +147,7 @@ void AGOSEngine_Waxworks::setupOpcodes() {
OPCODE(o_comment),
/* 88 */
OPCODE(o_invalid),
- OPCODE(oe1_loadGame),
+ OPCODE(oe2_loadGame),
OPCODE(o_getParent),
OPCODE(o_getNext),
/* 92 */
diff --git a/engines/agos/sound.cpp b/engines/agos/sound.cpp
index a4de624ec0..7165e3cbff 100644
--- a/engines/agos/sound.cpp
+++ b/engines/agos/sound.cpp
@@ -34,6 +34,7 @@
#include "sound/adpcm.h"
#include "sound/audiostream.h"
#include "sound/flac.h"
+#include "sound/mixer.h"
#include "sound/mp3.h"
#include "sound/voc.h"
#include "sound/vorbis.h"
@@ -55,11 +56,11 @@ protected:
public:
BaseSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false);
BaseSound(Audio::Mixer *mixer, File *file, uint32 *offsets, bool bigEndian = false);
- void playSound(uint sound, Audio::SoundHandle *handle, byte flags, int vol = 0) {
- playSound(sound, sound, handle, flags, vol);
+ void playSound(uint sound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol = 0) {
+ playSound(sound, sound, type, handle, flags, vol);
}
virtual ~BaseSound();
- virtual void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0) = 0;
+ virtual void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol = 0) = 0;
virtual Audio::AudioStream *makeAudioStream(uint sound) { return NULL; }
};
@@ -72,6 +73,7 @@ private:
uint _loopSound;
public:
LoopingAudioStream(BaseSound *parent, uint sound, uint loopSound, bool loop);
+ ~LoopingAudioStream();
int readBuffer(int16 *buffer, const int numSamples);
bool isStereo() const { return _stream ? _stream->isStereo() : 0; }
bool endOfData() const;
@@ -87,6 +89,10 @@ LoopingAudioStream::LoopingAudioStream(BaseSound *parent, uint sound, uint loopS
_stream = _parent->makeAudioStream(sound);
}
+LoopingAudioStream::~LoopingAudioStream() {
+ delete _stream;
+}
+
int LoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) {
if (!_loop) {
return _stream->readBuffer(buffer, numSamples);
@@ -121,19 +127,19 @@ public:
WavSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {}
WavSound(Audio::Mixer *mixer, File *file, uint32 *offsets) : BaseSound(mixer, file, offsets) {}
Audio::AudioStream *makeAudioStream(uint sound);
- void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0);
+ void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol = 0);
};
class VocSound : public BaseSound {
public:
VocSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {}
- void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0);
+ void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol = 0);
};
class RawSound : public BaseSound {
public:
RawSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {}
- void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0);
+ void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol = 0);
};
BaseSound::BaseSound(Audio::Mixer *mixer, File *file, uint32 base, bool bigEndian) {
@@ -236,12 +242,12 @@ Audio::AudioStream *WavSound::makeAudioStream(uint sound) {
return Audio::makeWAVStream(*_file);
}
-void WavSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol) {
+void WavSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol) {
convertVolume(vol);
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, new LoopingAudioStream(this, sound, loopSound, (flags & Audio::Mixer::FLAG_LOOP) != 0), sound, vol);
+ _mixer->playInputStream(type, handle, new LoopingAudioStream(this, sound, loopSound, (flags & Audio::Mixer::FLAG_LOOP) != 0), -1, vol);
}
-void VocSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol) {
+void VocSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol) {
if (_offsets == NULL)
return;
@@ -250,10 +256,10 @@ void VocSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle,
int size, rate;
byte *buffer = Audio::loadVOCFromStream(*_file, size, rate);
assert(buffer);
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer, size, rate, flags | Audio::Mixer::FLAG_AUTOFREE, sound);
+ _mixer->playRaw(type, handle, buffer, size, rate, flags | Audio::Mixer::FLAG_AUTOFREE);
}
-void RawSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol) {
+void RawSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol) {
if (_offsets == NULL)
return;
@@ -263,7 +269,7 @@ void RawSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle,
byte *buffer = (byte *)malloc(size);
assert(buffer);
_file->read(buffer, size);
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer, size, 22050, flags | Audio::Mixer::FLAG_AUTOFREE, sound);
+ _mixer->playRaw(type, handle, buffer, size, 22050, flags | Audio::Mixer::FLAG_AUTOFREE);
}
#ifdef USE_MAD
@@ -271,7 +277,7 @@ class MP3Sound : public BaseSound {
public:
MP3Sound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}
Audio::AudioStream *makeAudioStream(uint sound);
- void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0);
+ void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol = 0);
};
Audio::AudioStream *MP3Sound::makeAudioStream(uint sound) {
@@ -289,9 +295,9 @@ Audio::AudioStream *MP3Sound::makeAudioStream(uint sound) {
return Audio::makeMP3Stream(_file, size);
}
-void MP3Sound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol) {
+void MP3Sound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol) {
convertVolume(vol);
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, new LoopingAudioStream(this, sound, loopSound, (flags & Audio::Mixer::FLAG_LOOP) != 0), sound, vol);
+ _mixer->playInputStream(type, handle, new LoopingAudioStream(this, sound, loopSound, (flags & Audio::Mixer::FLAG_LOOP) != 0), -1, vol);
}
#endif
@@ -300,7 +306,7 @@ class VorbisSound : public BaseSound {
public:
VorbisSound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}
Audio::AudioStream *makeAudioStream(uint sound);
- void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0);
+ void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol = 0);
};
Audio::AudioStream *VorbisSound::makeAudioStream(uint sound) {
@@ -318,9 +324,9 @@ Audio::AudioStream *VorbisSound::makeAudioStream(uint sound) {
return Audio::makeVorbisStream(_file, size);
}
-void VorbisSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol) {
+void VorbisSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol) {
convertVolume(vol);
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, new LoopingAudioStream(this, sound, loopSound, (flags & Audio::Mixer::FLAG_LOOP) != 0), sound, vol);
+ _mixer->playInputStream(type, handle, new LoopingAudioStream(this, sound, loopSound, (flags & Audio::Mixer::FLAG_LOOP) != 0), -1, vol);
}
#endif
@@ -329,7 +335,7 @@ class FlacSound : public BaseSound {
public:
FlacSound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}
Audio::AudioStream *makeAudioStream(uint sound);
- void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0);
+ void playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol = 0);
};
Audio::AudioStream *FlacSound::makeAudioStream(uint sound) {
@@ -347,9 +353,9 @@ Audio::AudioStream *FlacSound::makeAudioStream(uint sound) {
return Audio::makeFlacStream(_file, size);
}
-void FlacSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol) {
+void FlacSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, byte flags, int vol) {
convertVolume(vol);
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, new LoopingAudioStream(this, sound, loopSound, (flags & Audio::Mixer::FLAG_LOOP) != 0), sound, vol);
+ _mixer->playInputStream(type, handle, new LoopingAudioStream(this, sound, loopSound, (flags & Audio::Mixer::FLAG_LOOP) != 0), -1, vol);
}
#endif
@@ -584,19 +590,16 @@ void Sound::playVoice(uint sound) {
if (!_voice)
return;
- if (_mixer->getSoundID(_voiceHandle) == (int)sound)
- return;
-
_mixer->stopHandle(_voiceHandle);
if (_vm->getGameType() == GType_PP) {
if (sound < 11)
- _voice->playSound(sound, sound + 1, &_voiceHandle, Audio::Mixer::FLAG_LOOP, -1500);
+ _voice->playSound(sound, sound + 1, Audio::Mixer::kMusicSoundType, &_voiceHandle, Audio::Mixer::FLAG_LOOP, -1500);
else
- _voice->playSound(sound, sound, &_voiceHandle, Audio::Mixer::FLAG_LOOP);
+ _voice->playSound(sound, sound, Audio::Mixer::kMusicSoundType, &_voiceHandle, Audio::Mixer::FLAG_LOOP);
} else if (_vm->getGameType() == GType_FF || _vm->getGameId() == GID_SIMON1CD32) {
- _voice->playSound(sound, &_voiceHandle, 0);
+ _voice->playSound(sound, Audio::Mixer::kSpeechSoundType, &_voiceHandle, 0);
} else {
- _voice->playSound(sound, &_voiceHandle, Audio::Mixer::FLAG_UNSIGNED);
+ _voice->playSound(sound, Audio::Mixer::kSpeechSoundType, &_voiceHandle, Audio::Mixer::FLAG_UNSIGNED);
}
}
@@ -607,7 +610,7 @@ void Sound::playEffects(uint sound) {
if (_effectsPaused)
return;
- _effects->playSound(sound, &_effectsHandle, (_vm->getGameId() == GID_SIMON1CD32) ? 0 : Audio::Mixer::FLAG_UNSIGNED);
+ _effects->playSound(sound, Audio::Mixer::kSFXSoundType, &_effectsHandle, (_vm->getGameId() == GID_SIMON1CD32) ? 0 : Audio::Mixer::FLAG_UNSIGNED);
}
void Sound::playAmbient(uint sound) {
@@ -623,7 +626,7 @@ void Sound::playAmbient(uint sound) {
return;
_mixer->stopHandle(_ambientHandle);
- _effects->playSound(sound, &_ambientHandle, Audio::Mixer::FLAG_LOOP | Audio::Mixer::FLAG_UNSIGNED);
+ _effects->playSound(sound, Audio::Mixer::kSFXSoundType, &_ambientHandle, Audio::Mixer::FLAG_LOOP | Audio::Mixer::FLAG_UNSIGNED);
}
bool Sound::hasVoice() const {
@@ -669,13 +672,16 @@ void Sound::ambientPause(bool b) {
// Elvira 1/2 and Waxworks specific
void Sound::playRawData(byte *soundData, uint sound, uint size) {
+ if (_effectsPaused)
+ return;
+
byte *buffer = (byte *)malloc(size);
memcpy(buffer, soundData, size);
if (_vm->getPlatform() == Common::kPlatformPC)
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, &_effectsHandle, buffer, size, 8000, Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE, sound);
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, &_effectsHandle, buffer, size, 8000, Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE);
else
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, &_effectsHandle, buffer, size, 8000, Audio::Mixer::FLAG_AUTOFREE, sound);
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, &_effectsHandle, buffer, size, 8000, Audio::Mixer::FLAG_AUTOFREE);
}
// Feeble Files specific
@@ -739,7 +745,7 @@ void Sound::playSoundData(Audio::SoundHandle *handle, byte *soundData, uint soun
memcpy(buffer, soundData + stream.pos(), size);
}
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer, size, rate, flags | Audio::Mixer::FLAG_AUTOFREE, sound, vol, pan);
+ _mixer->playRaw(Audio::Mixer::kSFXSoundType, handle, buffer, size, rate, flags | Audio::Mixer::FLAG_AUTOFREE, -1, vol, pan);
}
void Sound::stopSfx5() {
diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp
index 8c5e911c39..483f101889 100644
--- a/engines/agos/string.cpp
+++ b/engines/agos/string.cpp
@@ -32,7 +32,7 @@ using Common::File;
namespace AGOS {
-const byte *AGOSEngine::getStringPtrByID(uint stringId) {
+const byte *AGOSEngine::getStringPtrByID(uint16 stringId) {
const byte *string_ptr;
byte *dst;
@@ -49,7 +49,7 @@ const byte *AGOSEngine::getStringPtrByID(uint stringId) {
return dst;
}
-const byte *AGOSEngine::getLocalStringByID(uint stringId) {
+const byte *AGOSEngine::getLocalStringByID(uint16 stringId) {
if (stringId < _stringIdLocalMin || stringId >= _stringIdLocalMax) {
loadTextIntoMem(stringId);
}
@@ -140,7 +140,7 @@ uint AGOSEngine::loadTextFile_gme(const char *filename, byte *dst) {
return size;
}
-void AGOSEngine::loadTextIntoMem(uint stringId) {
+void AGOSEngine::loadTextIntoMem(uint16 stringId) {
byte *p;
char filename[30];
int i;
@@ -304,7 +304,7 @@ void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *strin
lettersPerRowJustified = stringLength / (stringLength / lettersPerRow + 1) + 1;
talkDelay = (stringLength + 3) / 3;
- if ((getGameType() == GType_SIMON1) && (getFeatures() & GF_TALKIE)) {
+ if (getGameType() == GType_SIMON1 && (getFeatures() & GF_TALKIE)) {
if (_variableArray[141] == 0)
_variableArray[141] = 9;
_variableArray[85] = _variableArray[141] * talkDelay;
@@ -364,16 +364,16 @@ void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *strin
renderString(vgaSpriteId, color, width, height, convertedString);
}
- int b = (!getBitFlag(133)) ? 3 : 4;
+ uint16 windowNum = (!getBitFlag(133)) ? 3 : 4;
x /= 8;
if (y < 2)
y = 2;
if (getGameType() == GType_SIMON1)
- animate(b, 2, vgaSpriteId + 199, x, y, 12);
+ animate(windowNum, 2, 199 + vgaSpriteId, x, y, 12);
else
- animate(b, 2, vgaSpriteId, x, y, 12);
+ animate(windowNum, 2, vgaSpriteId, x, y, 12);
}
// The Feeble Files specific
diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp
index a92f01db2b..f4a6ba3266 100644
--- a/engines/agos/subroutine.cpp
+++ b/engines/agos/subroutine.cpp
@@ -288,7 +288,7 @@ File *AGOSEngine::openTablesFile_gme(const char *filename) {
return _gameFile;
}
-bool AGOSEngine::loadTablesIntoMem(uint subr_id) {
+bool AGOSEngine::loadTablesIntoMem(uint16 subr_id) {
byte *p;
uint16 min_num, max_num, file_num;
File *in;
@@ -337,7 +337,7 @@ bool AGOSEngine::loadTablesIntoMem(uint subr_id) {
return 0;
}
-bool AGOSEngine_Waxworks::loadTablesIntoMem(uint subr_id) {
+bool AGOSEngine_Waxworks::loadTablesIntoMem(uint16 subr_id) {
byte *p;
int i;
uint min_num, max_num;
@@ -399,7 +399,7 @@ bool AGOSEngine_Waxworks::loadTablesIntoMem(uint subr_id) {
return 0;
}
-bool AGOSEngine::loadXTablesIntoMem(uint subr_id) {
+bool AGOSEngine::loadXTablesIntoMem(uint16 subr_id) {
byte *p;
int i;
uint min_num, max_num;
@@ -461,7 +461,7 @@ void AGOSEngine::closeTablesFile(File *in) {
}
}
-Subroutine *AGOSEngine::createSubroutine(uint id) {
+Subroutine *AGOSEngine::createSubroutine(uint16 id) {
Subroutine *sub;
alignTableMem();
@@ -681,7 +681,7 @@ void AGOSEngine::readSubroutineLine(Common::SeekableReadStream *in, SubroutineLi
byte *AGOSEngine::readSingleOpcode(Common::SeekableReadStream *in, byte *ptr) {
int i, l;
const char *string_ptr;
- uint opcode, val;
+ uint16 opcode, val;
const char *const *table;
diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp
index ddb7398312..f99d6db591 100644
--- a/engines/agos/verb.cpp
+++ b/engines/agos/verb.cpp
@@ -26,6 +26,10 @@
// Verb and hitarea handling
#include "common/stdafx.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
@@ -296,6 +300,10 @@ void AGOSEngine::showActionString(const byte *string) {
window->textColumn = x / 8;
window->textColumnOffset = x & 7;
+ if (_language == Common::HB_ISR && window->textColumnOffset != 0) {
+ window->textColumnOffset = 8 - window->textColumnOffset;
+ window->textColumn++;
+ }
for (; *string; string++)
windowPutChar(window, *string);
@@ -391,13 +399,15 @@ HitArea *AGOSEngine::findBox(uint hitarea_id) {
HitArea *AGOSEngine::findEmptyHitArea() {
HitArea *ha = _hitAreas;
- uint count = ARRAYSIZE(_hitAreas);
+ uint count = ARRAYSIZE(_hitAreas) - 1;
do {
if (ha->flags == 0)
return ha;
} while (ha++, --count);
- return NULL;
+
+ // The last box is overwritten, if too many boxes are allocated.
+ return ha;
}
void AGOSEngine::freeBox(uint index) {
@@ -674,21 +684,21 @@ void AGOSEngine::boxController(uint x, uint y, uint mode) {
if (mode != 0) {
if (mode == 3) {
- if (getGameType() == GType_ELVIRA1) {
+ if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) {
if (best_ha->verb & 0x4000) {
- if (_variableArray[500] == 0) {
+ if (getGameType() == GType_ELVIRA1 && _variableArray[500] == 0) {
_variableArray[500] = best_ha->verb & 0xBFFF;
}
- }
- if (_clickOnly != 0 && best_ha->id < 8) {
- uint id = best_ha->id;
- if (id >= 4)
- id -= 4;
+ if (_clickOnly != 0 && best_ha->id < 8) {
+ uint id = best_ha->id;
+ if (id >= 4)
+ id -= 4;
- invertBox(findBox(id), 0, 0, 0, 0);
- _clickOnly = 0;
- return;
+ invertBox(findBox(id), 0, 0, 0, 0);
+ _clickOnly = 0;
+ return;
+ }
}
}
@@ -826,7 +836,14 @@ void AGOSEngine::invertBox(HitArea * ha, byte a, byte b, byte c, byte d) {
int w, h, i;
_lockWord |= 0x8000;
- src = getFrontBuf() + ha->y * _dxSurfacePitch + (ha->x - _scrollX * 8);
+
+ Graphics::Surface *screen = _system->lockScreen();
+ src = (byte *)screen->pixels + ha->y * _dxSurfacePitch + ha->x;
+
+ // WORKAROUND: Hitareas for saved game names aren't adjusted for scrolling locations
+ if (getGameType() == GType_SIMON2 && ha->id >= 208 && ha->id <= 213) {
+ src -= _scrollX * 8;
+ }
_litBoxFlag = true;
@@ -864,6 +881,8 @@ void AGOSEngine::invertBox(HitArea * ha, byte a, byte b, byte c, byte d) {
src += _dxSurfacePitch;
} while (--h);
+ _system->unlockScreen();
+
_lockWord &= ~0x8000;
}
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp
index 1d2c280246..2b8f6d3a09 100644
--- a/engines/agos/vga.cpp
+++ b/engines/agos/vga.cpp
@@ -32,6 +32,8 @@
#include "common/system.h"
+#include "graphics/surface.h"
+
namespace AGOS {
// Opcode tables
@@ -215,8 +217,8 @@ bool AGOSEngine::vc_maybe_skip_proc_1(uint16 a, int16 b) {
void AGOSEngine::dirtyBackGround() {
AnimTable *animTable = _screenAnim1;
while (animTable->srcPtr) {
- if (animTable->id == _vgaCurSpriteId) {
- animTable->window |= 0x8000;
+ if (animTable->id == _vgaCurSpriteId && animTable->zoneNum == _vgaCurZoneNum) {
+ animTable->windowNum |= 0x8000;
break;
}
animTable++;
@@ -226,13 +228,8 @@ void AGOSEngine::dirtyBackGround() {
VgaSprite *AGOSEngine::findCurSprite() {
VgaSprite *vsp = _vgaSprites;
while (vsp->id) {
- if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) {
- if (vsp->id == _vgaCurSpriteId && vsp->zoneNum == _vgaCurZoneNum)
- break;
- } else {
- if (vsp->id == _vgaCurSpriteId)
- break;
- }
+ if (vsp->id == _vgaCurSpriteId && vsp->zoneNum == _vgaCurZoneNum)
+ break;
vsp++;
}
return vsp;
@@ -241,13 +238,8 @@ VgaSprite *AGOSEngine::findCurSprite() {
bool AGOSEngine::isSpriteLoaded(uint16 id, uint16 zoneNum) {
VgaSprite *vsp = _vgaSprites;
while (vsp->id) {
- if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) {
- if (vsp->id == id && vsp->zoneNum == zoneNum)
- return true;
- } else {
- if (vsp->id == id)
- return true;
- }
+ if (vsp->id == id && vsp->zoneNum == zoneNum)
+ return true;
vsp++;
}
return false;
@@ -708,12 +700,6 @@ void AGOSEngine::drawImage_init(int16 image, uint16 palette, int16 x, int16 y, u
}
}
- state.surf2_addr = getFrontBuf();
- state.surf2_pitch = _dxSurfacePitch;
-
- state.surf_addr = getBackBuf();
- state.surf_pitch = _dxSurfacePitch;
-
drawImage(&state);
}
@@ -804,16 +790,19 @@ void AGOSEngine::checkWaitEndTable() {
}
void AGOSEngine::vc17_waitEnd() {
+ uint16 id = vcReadNextWord();
+
VgaSleepStruct *vfs = _waitEndTable;
while (vfs->ident)
vfs++;
- vfs->ident = vcReadNextWord();
- vfs->code_ptr = _vcPtr;
- vfs->sprite_id = _vgaCurSpriteId;
- vfs->cur_vga_file = _vgaCurZoneNum;
-
- _vcPtr = (byte *)&_vc_get_out_of_code;
+ if (isSpriteLoaded(id, id / 100)) {
+ vfs->ident = id;
+ vfs->code_ptr = _vcPtr;
+ vfs->sprite_id = _vgaCurSpriteId;
+ vfs->cur_vga_file = _vgaCurZoneNum;
+ _vcPtr = (byte *)&_vc_get_out_of_code;
+ }
}
void AGOSEngine::vc18_jump() {
@@ -843,10 +832,7 @@ void AGOSEngine::vc19_loop() {
}
void AGOSEngine::vc20_setRepeat() {
- /* FIXME: This opcode is somewhat strange: it first reads a BE word from
- * the script (advancing the script pointer in doing so); then it writes
- * back the same word, this time as LE, into the script.
- */
+ // Sets counter used by the endRepeat opcode below.
uint16 a = vcReadNextWord();
WRITE_LE_UINT16(const_cast<byte *>(_vcPtr), a);
_vcPtr += 2;
@@ -1042,7 +1028,7 @@ void AGOSEngine::vc27_resetSprite() {
vte = _vgaTimerList;
while (vte->delay) {
// Skip the animateSprites event in earlier games
- if (vte->type == 2) {
+ if (vte->type == ANIMATE_INT) {
vte++;
// For animated heart in Elvira 2
} else if (getGameType() == GType_ELVIRA2 && vte->sprite_id == 100) {
@@ -1125,6 +1111,7 @@ void AGOSEngine::vc33_setMouseOn() {
_displayPalette[65 * 4 + 1] = 48 * 4;
_displayPalette[65 * 4 + 2] = 40 * 4;
_displayPalette[65 * 4 + 3] = 0;
+ _paletteFlag = 1;
}
mouseOn();
}
@@ -1136,9 +1123,7 @@ void AGOSEngine::vc34_setMouseOff() {
_leftButtonDown = 0;
}
-void AGOSEngine::clearVideoBackGround(uint num, uint color) {
- debug(0, "clearVideoBackGround: num %d color %d", num, color);
-
+void AGOSEngine::clearVideoBackGround(uint16 num, uint16 color) {
const uint16 *vlut = &_videoWindows[num * 4];
byte *dst = getBackGround() + vlut[0] * 16 + (vlut[1] * (vlut[2] * 16));
@@ -1148,7 +1133,7 @@ void AGOSEngine::clearVideoBackGround(uint num, uint color) {
}
}
-void AGOSEngine::clearVideoWindow(uint num, uint color) {
+void AGOSEngine::clearVideoWindow(uint16 num, uint16 color) {
if (getGameType() == GType_ELVIRA1) {
if (num == 2 || num == 6)
return;
@@ -1160,13 +1145,11 @@ void AGOSEngine::clearVideoWindow(uint num, uint color) {
return;
}
- debug(0, "clearVideoWindow: num %d color %d", num, color);
-
if (getGameType() == GType_SIMON2) {
const uint16 *vlut = &_videoWindows[num * 4];
- uint xoffs = vlut[0] * 16;
- uint yoffs = vlut[1];
- uint dstWidth = _videoWindows[18] * 16;
+ uint16 xoffs = vlut[0] * 16;
+ uint16 yoffs = vlut[1];
+ uint16 dstWidth = _videoWindows[18] * 16;
byte *dst = _window4BackScn + xoffs + yoffs * dstWidth;
setMoveRect(0, 0, vlut[2] * 16, vlut[3]);
@@ -1179,12 +1162,14 @@ void AGOSEngine::clearVideoWindow(uint num, uint color) {
_window4Flag = 1;
} else {
if (getGameType() == GType_ELVIRA1 && num == 3) {
- memset(getFrontBuf(), color, _screenWidth * _screenHeight);
+ Graphics::Surface *screen = _system->lockScreen();
+ memset((byte *)screen->pixels, color, _screenWidth * _screenHeight);
+ _system->unlockScreen();
} else if (num == 4) {
const uint16 *vlut = &_videoWindows[num * 4];
- uint xoffs = (vlut[0] - _videoWindows[16]) * 16;
- uint yoffs = (vlut[1] - _videoWindows[17]);
- uint dstWidth = _videoWindows[18] * 16;
+ uint16 xoffs = (vlut[0] - _videoWindows[16]) * 16;
+ uint16 yoffs = (vlut[1] - _videoWindows[17]);
+ uint16 dstWidth = _videoWindows[18] * 16;
byte *dst = _window4BackScn + xoffs + yoffs * dstWidth;
setMoveRect(0, 0, vlut[2] * 16, vlut[3]);
@@ -1228,7 +1213,7 @@ void AGOSEngine::vc36_setWindowImage() {
uint16 windowNum = vcReadNextWord();
if (getGameType() == GType_FF || getGameType() == GType_PP) {
- _copyPartialMode = 2;
+ fillBackGroundFromFront();
} else {
setWindowImage(windowNum, vga_res);
}
diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp
index ca1a3a4469..a4925de842 100644
--- a/engines/agos/vga_e2.cpp
+++ b/engines/agos/vga_e2.cpp
@@ -31,6 +31,8 @@
#include "common/system.h"
+#include "graphics/surface.h"
+
namespace AGOS {
void AGOSEngine_Elvira2::setupVideoOpcodes(VgaOpcodeProc *op) {
@@ -67,44 +69,49 @@ void AGOSEngine::vc44_ifBitClear() {
}
void AGOSEngine::vc45_setWindowPalette() {
- uint num = vcReadNextWord();
- uint color = vcReadNextWord();
+ uint16 num = vcReadNextWord();
+ uint16 color = vcReadNextWord();
+
+ const uint16 *vlut = &_videoWindows[num * 4];
+ uint8 width = vlut[2] * 8;
+ uint8 height = vlut[3];
if (num == 4) {
- const uint16 *vlut = &_videoWindows[num * 4];
- uint16 *dst = (uint16 *)_window4BackScn;
- uint width = vlut[2] * 16 / 2;
- uint height = vlut[3];
-
- for (uint h = 0; h < height; h++) {
- for (uint w = 0; w < width; w++) {
- dst[w] &= 0xF0F;
- dst[w] |= color * 16;
+ byte *dst = _window4BackScn;
+
+ for (uint8 h = 0; h < height; h++) {
+ for (uint8 w = 0; w < width; w++) {
+ uint16 val = READ_LE_UINT16(dst + w * 2);
+ val &= 0xF0F;
+ val |= color * 16;
+ WRITE_LE_UINT16(dst + w * 2, val);
}
- dst += width;
+ dst += width * 2;
}
} else {
- const uint16 *vlut = &_videoWindows[num * 4];
- uint16 *dst = (uint16 *)getFrontBuf() + vlut[0] * 8 + vlut[1] * _dxSurfacePitch / 2;
- uint width = vlut[2] * 16 / 2;
- uint height = vlut[3];
+ Graphics::Surface *screen = _system->lockScreen();
+ byte *dst = (byte *)screen->pixels + vlut[0] * 16 + vlut[1] * _dxSurfacePitch;
if (getGameType() == GType_ELVIRA2 && num == 7) {
- dst -= 4;
+ dst -= 8;
width += 4;
}
- for (uint h = 0; h < height; h++) {
- for (uint w = 0; w < width; w++) {
- dst[w] &= 0xF0F;
- dst[w] |= color * 16;
+ for (uint8 h = 0; h < height; h++) {
+ for (uint8 w = 0; w < width; w++) {
+ uint16 val = READ_LE_UINT16(dst + w * 2);
+ val &= 0xF0F;
+ val |= color * 16;
+ WRITE_LE_UINT16(dst + w * 2, val);
}
- dst += _dxSurfacePitch / 2;
+ dst += _dxSurfacePitch;
}
+
+ _system->unlockScreen();
}
}
-void AGOSEngine::setPaletteSlot(uint srcOffs, uint dstOffs) {
+void AGOSEngine::setPaletteSlot(uint16 srcOffs, uint8 dstOffs) {
byte *offs, *palptr, *src;
uint16 num;
@@ -128,17 +135,17 @@ void AGOSEngine::setPaletteSlot(uint srcOffs, uint dstOffs) {
}
void AGOSEngine::vc46_setPaletteSlot1() {
- uint srcOffs = vcReadNextWord();
+ uint16 srcOffs = vcReadNextWord();
setPaletteSlot(srcOffs, 1);
}
void AGOSEngine::vc47_setPaletteSlot2() {
- uint srcOffs = vcReadNextWord();
+ uint16 srcOffs = vcReadNextWord();
setPaletteSlot(srcOffs, 2);
}
void AGOSEngine::vc48_setPaletteSlot3() {
- uint srcOffs = vcReadNextWord();
+ uint16 srcOffs = vcReadNextWord();
setPaletteSlot(srcOffs, 3);
}
@@ -211,10 +218,13 @@ void AGOSEngine::vc53_dissolveIn() {
int16 xoffs = _videoWindows[num * 4 + 0] * 16;
int16 yoffs = _videoWindows[num * 4 + 1];
- byte *dstPtr = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ int16 offs = xoffs + yoffs * _screenWidth;
uint16 count = dissolveCheck * 2;
while (count--) {
+ Graphics::Surface *screen = _system->lockScreen();
+ byte *dstPtr = (byte *)screen->pixels + offs;
+
yoffs = _rnd.getRandomNumber(dissolveY);
dst = dstPtr + yoffs * _screenWidth;
src = _window4BackScn + yoffs * 224;
@@ -253,15 +263,15 @@ void AGOSEngine::vc53_dissolveIn() {
*dst &= color;
*dst |= *src & 0xF;
+ _system->unlockScreen();
+
dissolveCount--;
if (!dissolveCount) {
if (count >= dissolveCheck)
dissolveDelay++;
dissolveCount = dissolveDelay;
- _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
- _system->updateScreen();
- delay(0);
+ delay(1);
}
}
}
@@ -281,11 +291,14 @@ void AGOSEngine::vc54_dissolveOut() {
int16 xoffs = _videoWindows[num * 4 + 0] * 16;
int16 yoffs = _videoWindows[num * 4 + 1];
- byte *dstPtr = getFrontBuf() + xoffs + yoffs * _screenWidth;
- color |= dstPtr[0] & 0xF0;
+ int16 offs = xoffs + yoffs * _screenWidth;
uint16 count = dissolveCheck * 2;
while (count--) {
+ Graphics::Surface *screen = _system->lockScreen();
+ byte *dstPtr = (byte *)screen->pixels + offs;
+ color |= dstPtr[0] & 0xF0;
+
yoffs = _rnd.getRandomNumber(dissolveY);
xoffs = _rnd.getRandomNumber(dissolveX);
dst = dstPtr + xoffs + yoffs * _screenWidth;
@@ -304,15 +317,15 @@ void AGOSEngine::vc54_dissolveOut() {
dst += xoffs;
*dst = color;
+ _system->unlockScreen();
+
dissolveCount--;
if (!dissolveCount) {
if (count >= dissolveCheck)
dissolveDelay++;
dissolveCount = dissolveDelay;
- _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
- _system->updateScreen();
- delay(0);
+ delay(1);
}
}
}
@@ -339,11 +352,15 @@ void AGOSEngine::vc55_moveBox() {
}
void AGOSEngine::vc56_fullScreen() {
+ Graphics::Surface *screen = _system->lockScreen();
+
+ byte *dst = (byte *)screen->pixels;
byte *src = _curVgaFile2 + 32;
- byte *dst = getFrontBuf();
memcpy(dst, src + 768, _screenHeight * _screenWidth);
+ _system->unlockScreen();
+
//fullFade();
uint8 palette[1024];
diff --git a/engines/agos/vga_ff.cpp b/engines/agos/vga_ff.cpp
index e1ee56002e..29b05e1e3c 100644
--- a/engines/agos/vga_ff.cpp
+++ b/engines/agos/vga_ff.cpp
@@ -217,7 +217,7 @@ void AGOSEngine::checkScrollX(int16 x, int16 xpos) {
if (_scrollXMax == 0 || x == 0)
return;
- if ((getGameType() == GType_FF) && (getBitFlag(80) || getBitFlag(82)))
+ if (getGameType() == GType_FF && (getBitFlag(80) || getBitFlag(82)))
return;
int16 tmp;
diff --git a/engines/agos/vga_s2.cpp b/engines/agos/vga_s2.cpp
index 9e482e95f4..9c05bc1100 100644
--- a/engines/agos/vga_s2.cpp
+++ b/engines/agos/vga_s2.cpp
@@ -52,6 +52,14 @@ void AGOSEngine_Simon2::setupVideoOpcodes(VgaOpcodeProc *op) {
void AGOSEngine::vc56_delayLong() {
uint16 num = vcReadVarOrWord() * _frameCount;
+ if (getGameType() == GType_FF && _currentTable) {
+ // WORKAROUND: When the repair man comes to fix the car, the game doesn't
+ // wait long enough for the screen to completely scroll to the left side.
+ if (_currentTable->id == 20438 && _vgaCurSpriteId == 13 && _vgaCurZoneNum == 2) {
+ num *= 2;
+ }
+ }
+
addVgaEvent(num + _vgaBaseDelay, ANIMATE_EVENT, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum);
_vcPtr = (byte *)&_vc_get_out_of_code;
}
@@ -194,7 +202,7 @@ void AGOSEngine::vc72_segue() {
int16 loop = vcReadNextWord();
if (track == -1 || track == 999) {
- _midi.stop();
+ stopMusic();
} else {
_midi.setLoop(loop != 0);
_midi.startTrack(track);
diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp
index 60aeeaeebe..c24a115e71 100644
--- a/engines/agos/vga_ww.cpp
+++ b/engines/agos/vga_ww.cpp
@@ -31,6 +31,8 @@
#include "common/system.h"
+#include "graphics/surface.h"
+
namespace AGOS {
void AGOSEngine_Waxworks::setupVideoOpcodes(VgaOpcodeProc *op) {
@@ -43,23 +45,55 @@ void AGOSEngine_Waxworks::setupVideoOpcodes(VgaOpcodeProc *op) {
op[63] = &AGOSEngine::vc63_fastFadeIn;
}
-void AGOSEngine::vcStopAnimation(uint file, uint sprite) {
- uint16 old_sprite_id, old_cur_file_id;
+void AGOSEngine::vcStopAnimation(uint16 zone, uint16 sprite) {
+ uint16 oldCurSpriteId, oldCurZoneNum;
+ VgaSprite *vsp;
+ VgaTimerEntry *vte;
+ const byte *vcPtrOrg;
+
+ oldCurSpriteId = _vgaCurSpriteId;
+ oldCurZoneNum = _vgaCurZoneNum;
+ vcPtrOrg = _vcPtr;
+
+ _vgaCurZoneNum = zone;
+ _vgaCurSpriteId = sprite;
+
+ vsp = findCurSprite();
+ if (vsp->id) {
+ vc25_halt_sprite();
+
+ vte = _vgaTimerList;
+ while (vte->delay) {
+ if (vte->sprite_id == _vgaCurSpriteId && vte->cur_vga_file == _vgaCurZoneNum) {
+ deleteVgaEvent(vte);
+ break;
+ }
+ vte++;
+ }
+ }
+
+ _vgaCurZoneNum = oldCurZoneNum;
+ _vgaCurSpriteId = oldCurSpriteId;
+ _vcPtr = vcPtrOrg;
+}
+
+void AGOSEngine_Simon1::vcStopAnimation(uint16 zone, uint16 sprite) {
+ uint16 oldCurSpriteId, oldCurZoneNum;
VgaSleepStruct *vfs;
VgaSprite *vsp;
VgaTimerEntry *vte;
const byte *vcPtrOrg;
- old_sprite_id = _vgaCurSpriteId;
- old_cur_file_id = _vgaCurZoneNum;
+ oldCurSpriteId = _vgaCurSpriteId;
+ oldCurZoneNum = _vgaCurZoneNum;
vcPtrOrg = _vcPtr;
- _vgaCurZoneNum = file;
+ _vgaCurZoneNum = zone;
_vgaCurSpriteId = sprite;
vfs = _waitSyncTable;
while (vfs->ident != 0) {
- if (vfs->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vfs->cur_vga_file == _vgaCurZoneNum)) {
+ if (vfs->sprite_id == _vgaCurSpriteId && vfs->cur_vga_file == _vgaCurZoneNum) {
while (vfs->ident != 0) {
memcpy(vfs, vfs + 1, sizeof(VgaSleepStruct));
vfs++;
@@ -75,7 +109,7 @@ void AGOSEngine::vcStopAnimation(uint file, uint sprite) {
vte = _vgaTimerList;
while (vte->delay) {
- if (vte->sprite_id == _vgaCurSpriteId && (getGameType() == GType_SIMON1 || vte->cur_vga_file == _vgaCurZoneNum)) {
+ if (vte->sprite_id == _vgaCurSpriteId && vte->cur_vga_file == _vgaCurZoneNum) {
deleteVgaEvent(vte);
break;
}
@@ -83,8 +117,8 @@ void AGOSEngine::vcStopAnimation(uint file, uint sprite) {
}
}
- _vgaCurZoneNum = old_cur_file_id;
- _vgaCurSpriteId = old_sprite_id;
+ _vgaCurZoneNum = oldCurZoneNum;
+ _vgaCurSpriteId = oldCurSpriteId;
_vcPtr = vcPtrOrg;
}
@@ -98,8 +132,8 @@ void AGOSEngine::vc60_stopAnimation() {
zoneNum = vcReadNextWord();
sprite = vcReadNextWord();
} else {
- zoneNum = _vgaCurZoneNum;
sprite = vcReadNextWord();
+ zoneNum = sprite / 100;
}
vcStopAnimation(zoneNum, sprite);
@@ -110,13 +144,15 @@ void AGOSEngine::vc61() {
byte *src, *dst, *dstPtr;
uint h, tmp;
+ Graphics::Surface *screen = _system->lockScreen();
+
if (a == 6) {
src = _curVgaFile2 + 800;
- dstPtr = getFrontBuf();
+ dstPtr = (byte *)screen->pixels;
memcpy(dstPtr, src, 64000);
tmp = 4 - 1;
} else {
- dstPtr = getFrontBuf();
+ dstPtr = (byte *)screen->pixels;
tmp = a - 1;
}
@@ -135,8 +171,10 @@ void AGOSEngine::vc61() {
dst += _screenWidth;
}
- if (a != 6)
+ if (a != 6) {
+ _system->unlockScreen();
return;
+ }
src = _curVgaFile2 + 9984 * 16 + 15344;
}
@@ -148,6 +186,8 @@ void AGOSEngine::vc61() {
dst += _screenWidth;
}
+ _system->unlockScreen();
+
if (a == 6) {
//fullFade();
src = _curVgaFile2 + 32;
@@ -197,13 +237,11 @@ void AGOSEngine::vc62_fastFadeOut() {
delay(5);
}
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- clearSurfaces(_screenHeight);
- } else if (getGameType() == GType_WW) {
- memset(getFrontBuf(), 0, _screenWidth * _screenHeight);
+ if (getGameType() == GType_WW || getGameType() == GType_FF || getGameType() == GType_PP) {
+ clearSurfaces();
} else {
if (_windowNum != 4) {
- memset(getFrontBuf(), 0, _screenWidth * _screenHeight);
+ clearSurfaces();
}
}
}
diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp
index 94436b0560..d4eb7ba3fc 100644
--- a/engines/agos/window.cpp
+++ b/engines/agos/window.cpp
@@ -25,6 +25,10 @@
#include "common/stdafx.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
@@ -60,11 +64,16 @@ WindowBlock *AGOSEngine::openWindow(uint x, uint y, uint w, uint h, uint flags,
window->fill_color = fillColor;
window->text_color = textColor;
window->textColumn = 0;
- window->textRow = 0;
window->textColumnOffset = 0;
- window->textMaxLength = window->width * 8 / 6; // characters are 6 pixels
+ window->textRow = 0;
window->scrollY = 0;
+ // Characters are 6 pixels
+ if (getGameType() == GType_ELVIRA2)
+ window->textMaxLength = (window->width * 8 - 4) / 6;
+ else
+ window->textMaxLength = window->width * 8 / 6;
+
if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
clearWindow(window);
@@ -103,59 +112,73 @@ void AGOSEngine::clearWindow(WindowBlock *window) {
window->textColumn = 0;
window->textRow = 0;
- window->textColumnOffset = 0;
+ window->textColumnOffset = (getGameType() == GType_ELVIRA2) ? 4 : 0;
window->textLength = 0;
window->scrollY = 0;
}
-void AGOSEngine::colorWindow(WindowBlock *window) {
+void AGOSEngine_Feeble::colorWindow(WindowBlock *window) {
byte *dst;
- uint h, w;
+ uint16 h, w;
_lockWord |= 0x8000;
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- dst = getFrontBuf() + _dxSurfacePitch * window->y + window->x;
+ dst = getBackGround() + _dxSurfacePitch * window->y + window->x;
- for (h = 0; h < window->height; h++) {
- for (w = 0; w < window->width; w++) {
- if (dst[w] == 113 || dst[w] == 116 || dst[w] == 252)
- dst[w] = window->fill_color;
- }
- dst += _screenWidth;
+ for (h = 0; h < window->height; h++) {
+ for (w = 0; w < window->width; w++) {
+ if (dst[w] == 113 || dst[w] == 116 || dst[w] == 252)
+ dst[w] = window->fill_color;
}
- } else {
- dst = getFrontBuf() + _dxSurfacePitch * (window->y) + window->x * 8;
- h = window->height * 8;
- w = window->width * 8;
-
- if (getGameType() == GType_ELVIRA2 && window->y == 146) {
- if (window->fill_color == 1) {
- _displayPalette[33 * 4 + 0] = 48 * 4;
- _displayPalette[33 * 4 + 1] = 40 * 4;
- _displayPalette[33 * 4 + 2] = 32 * 4;
- } else {
- _displayPalette[33 * 4 + 0] = 56 * 4;
- _displayPalette[33 * 4 + 1] = 56 * 4;
- _displayPalette[33 * 4 + 2] = 40 * 4;
- }
+ dst += _screenWidth;
+ }
- dst -= _dxSurfacePitch;
- h += 2;
+ _lockWord &= ~0x8000;
+}
- _paletteFlag = 1;
+void AGOSEngine::colorWindow(WindowBlock *window) {
+ uint16 y, h;
+
+ y = window->y;
+ h = window->height * 8;
+
+ if (getGameType() == GType_ELVIRA2 && window->y == 146) {
+ if (window->fill_color == 1) {
+ _displayPalette[33 * 4 + 0] = 48 * 4;
+ _displayPalette[33 * 4 + 1] = 40 * 4;
+ _displayPalette[33 * 4 + 2] = 32 * 4;
+ } else {
+ _displayPalette[33 * 4 + 0] = 56 * 4;
+ _displayPalette[33 * 4 + 1] = 56 * 4;
+ _displayPalette[33 * 4 + 2] = 40 * 4;
}
- uint8 color = window->fill_color;
- if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
- color += dst[0] & 0xF0;
+ y--;
+ h += 2;
- do {
- memset(dst, color, w);
- dst += _dxSurfacePitch;
- } while (--h);
+ _paletteFlag = 1;
}
+ colorBlock(window, window->x * 8, y, window->width * 8, h);
+}
+
+void AGOSEngine::colorBlock(WindowBlock *window, uint16 x, uint16 y, uint16 w, uint16 h) {
+ _lockWord |= 0x8000;
+
+ Graphics::Surface *screen = _system->lockScreen();
+ byte *dst = (byte *)screen->pixels + y * _screenWidth + x;
+
+ uint8 color = window->fill_color;
+ if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
+ color += dst[0] & 0xF0;
+
+ do {
+ memset(dst, color, w);
+ dst += _screenWidth;
+ } while (--h);
+
+ _system->unlockScreen();
+
_lockWord &= ~0x8000;
}
@@ -180,29 +203,50 @@ void AGOSEngine::restoreWindow(WindowBlock *window) {
} else if (getGameType() == GType_SIMON1) {
restoreBlock(window->y + window->height * 8 + ((window == _windowArray[2]) ? 1 : 0), (window->x + window->width) * 8, window->y, window->x * 8);
} else {
- restoreBlock(window->y + window->height * 8, (window->x + window->width) * 8, window->y, window->x * 8);
+ uint16 x = window->x;
+ uint16 w = window->width;
+
+ if (getGameType() == GType_ELVIRA1) {
+ // Adjustments to remove inventory arrows
+ if (x & 1) {
+ x--;
+ w++;
+ }
+ if (w & 1) {
+ w++;
+ }
+ }
+
+ restoreBlock(window->y + window->height * 8, (x + w) * 8, window->y, x * 8);
}
_lockWord &= ~0x8000;
}
-void AGOSEngine::restoreBlock(uint h, uint w, uint y, uint x) {
+void AGOSEngine::restoreBlock(uint16 h, uint16 w, uint16 y, uint16 x) {
byte *dst, *src;
uint i;
- dst = getFrontBuf();
+ Graphics::Surface *screen = _system->lockScreen();
+ dst = (byte *)screen->pixels;
src = getBackGround();
dst += y * _dxSurfacePitch;
src += y * _dxSurfacePitch;
+ uint8 paletteMod = 0;
+ if (getGameType() == GType_ELVIRA1 && !(getFeatures() & GF_DEMO) && y >= 133)
+ paletteMod = 16;
+
while (y < h) {
for (i = x; i < w; i++)
- dst[i] = src[i];
+ dst[i] = src[i] + paletteMod;
y++;
dst += _dxSurfacePitch;
src += _dxSurfacePitch;
}
+
+ _system->unlockScreen();
}
void AGOSEngine::setTextColor(uint color) {
diff --git a/engines/agos/zones.cpp b/engines/agos/zones.cpp
index 05643a6e89..a1de03e66c 100644
--- a/engines/agos/zones.cpp
+++ b/engines/agos/zones.cpp
@@ -44,7 +44,7 @@ void AGOSEngine::unfreezeBottom() {
_vgaFrozenBase = _vgaRealBase;
}
-void AGOSEngine::loadZone(uint zoneNum) {
+void AGOSEngine::loadZone(uint16 zoneNum) {
VgaPointersEntry *vpe;
CHECK_BOUNDS(zoneNum, _vgaBufferPointers);