[Scummvm-cvs-logs] scummvm master -> 2613e7f5879c8c3ca7663dfcea8d5b91c499c107
wjp
wjp at usecode.org
Sun Nov 20 22:52:57 CET 2011
This automated email contains information about 158 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
7c2835313e TOLTECS: Initial checkin
f4e156b3b3 TOLTECS: Fixed tabs and formatting.
0c3f2ab5d5 TOLTECS: Some cleanup of the pathfinding code.
21f6dad09a TOLTECS: - Renamed some variables & functions
dd5567613f TOLTECS: - Renamed stuff and cleanups
51214a461a TOLTECS: Saving/loading is working; it still needs work but will suffice to make debugging somewhat easier.
03cae51129 TOLTECS: - Made game "quittable"
d561cb7ae3 TOLTECS: Fixed tabs.
f0c9e489fe TOLTECS: Minor cleanup.
98ac7885ac TOLTECS: Merged drawChar and drawChar2
5660ff5148 TOLTECS: Implemented buildColorTransTable (still TODO) and shadow sprite drawing.
74c05f6aa8 TOLTECS: - Merged input.cpp with toltecs.cpp
32d958508b TOLTECS: Deleted obsolete files.
c82349c1b8 TOLTECS: Finished sprite clipping.
59bbad2ac8 TOLTECS: Fixed clipping (the clipping of the right border with flipped sprites was buggy)
e2b3a35486 TOLTECS: Corrected debug output.
2930003864 TOLTECS: Fixed a script bug (compare opcodes work on unsigned values). So far this caused one error I noticed when climb
b287588149 TOLTECS: Clear the text duration first in updateTalkText before adding text lines (else the durations add up and the tex
bbf882016a TOLTECS: Fixed text command parsing in updateVerbLine
3c326b5c40 TOLTECS: Fixed bug in anim frame displaying.
367be5b345 TOLTECS: Merged text drawing routines into drawString
6a83d7d851 TOLTECS: Cancel all talkText items when camera position is changed (fixes some crashes and odd behaviour)
a94503765d TOLTECS: - Fixed setDeltaPalette (sprites at night now look correct)
be69bb986f TOLTECS: Added TODO/NOTES/BUGS text
3eb449f236 TOLTECS: Add Russian version detection which works great.
aaded0f546 TOLTECS: Added Screen::getTextWidth
398d0daac0 TOLTECS: Adjust y position of talk text lines.
20d60e6286 TOLTECS: Renamed some functions.
d09fbbabe6 TOLTECS: - Added menu system prototype (may change later)
3b89304dd9 TOLTECS: Forgot script.cpp.
3c47914648 TOLTECS: Removed _tempString etc. and replaced it with GuiTextWrapState
ca49ded9b3 TOLTECS: More changes to wrapGuiText
ade8eec8cf TOLTECS: Moved sprite drawing code to sprite.cpp
150e555953 TOLTECS: Renamed ybottom to priority
d299bbba01 TOLTECS: Changed how screen masks are handled.
8f3e598f85 TOLTECS: Cleanup.
37a5f9e9ef TOLTECS: Switched quicksave key from F6 to F5.
7b97e8cd93 TOLTECS: A lot of changes in the graphics code:
3acd787145 TOLTECS: Updated TODO.txt
02e2b78e5c TOLTECS: Added sound to the movie player (finally). Still TODO: Ability to abort movies.
beab4e3ca5 TOLTECS: Correct initialization for graphics. Since the game is 640x480, it should be
f77960e81b TOLTECS: Removed unused functions.
4b13982116 TOLTECS: Implemented preliminary sound playback; some stuff is still missing (correct volumes etc.)
47ae908589 TOLTECS: - Fixed Screen::updateTalkText (text x position was read incorrectly and font color wasn't nibble-swapped)
9e78b5d393 TOLTECS: - Listing savestates via command line or Launcher
ec6f0d23a7 TOLTECS: Very very minor cleanup.
1f4764ad1c TOLTECS: - Implemented RTL
46257f7bb4 TOLTECS: Silenced MSVC warnings
2eb6482b06 TOLTECS: - Fixed compilation after Fingolfin's latest series of commits
2156fecf53 TOLTECS: Added German version
edefa37a45 TOLTECS: Fixed compilation
b9de8beb6e TOLTECS: Fixed compilation
5c481dd116 TOLTECS: - Removed TODO, external resources aren't explicitly used (the original game extracts resources from WESTERN to
170b66b2cb TOLTECS: Updated TODO (nothing new, just syncing local copy with the repo)
041fe21417 TOLTECS: - Added enum for sound channel type
eab360f3e7 TOLTECS: - Moved script functions out of the switch statement and into an array
af7e1c1683 TOLTECS: - Fixed sound playing
ce7febcd70 TOLTECS: Reworked the ArchiveReader and ResourceCache classes.
9a84c13bef TOLTECS: - Implemented playSoundAtPos and fixed sound panning (0 is center, not 64 like in the original)
22db6b1558 TOLTECS: - Fixed clipping bugs (in 256-color sprites and scaled sprites)
d6edbe97c9 TOLTECS: Oops, forgot to disable the debug path drawing.
3c49d36d5f TOLTECS: Fix compilation.
eb04f85673 TOLTECS: - Added detection entry for the German demo version
d93bd3c01c TOLTECS: Silenced some warnings
284c358f7c TOLTECS: Started implementing the menu from scratch
3d0775bd89 TOLTECS: More work on the menu
28c74ff3b4 TOLTECS: More work on the menu; started with the saveload menu page and fixed some early bugs
d80cc85347 TOLTECS: More work on the menu; started the savegame page and implemented editing of the savegame description
145a696fe0 TOLTECS: Implemented scrolling in the savegame list
54cb86950c TOLTECS: Fixed odd bug in drawChar (I subtracted 2 from the font height before, though I don't recall why exactly I did
4c7cef996a TOLTECS: Misc fixes in the menu system
b038d2e4f2 TOLTECS: Added GUI options to detection entries
cb5c0e6986 TOLTECS: Sync with ScummVM rev. 46379
a0432fd546 TOLTECS: Fixed compilation
ac97b441ec TOLTECS: Silenced warning
5948672be5 TOLTECS: Fixed compilation with the latest sound changes in the trunk
69f35c8709 TOLTECS: Fixed compilation
baf4218b05 TOLTECS: Fixed compilation with the latest trunk changes
16baa44a2f TOLTECS: Fixed compilation with the latest trunk
89a5208a58 TOLTECS: Fixed compilation with the latest trunk changes.
e8ec5148a2 TOLTECS: Fixed compilation
0d1a9148f3 TOLTECS: Fix bug caused by most recent revision (don't free the audio data in makeRawStream)
34eb899b25 TOLTECS: Fixed compilation
7f78f62467 TOLTECS: Fixed compilation with current SVN changes
fc324073d5 TOLTECS: Rename savegame version define
d885aedd48 TOLTECS: Fix compilation with trunk
2e06f4b088 TOLTECS: Added detection entries for French and Spanish versions
39b8bda921 TOLTECS: Fix warning
8ea6831825 TOLTECS: Fix warning
2acf1bf6f5 TOLTECS: - Hopefully fixed a bug in findRectAtPoint which causes the game to crash before the first scene
99bd410cb3 TOLTECS: Sync with the latest ScummVM changes (renamed skipThumbnailHeader to skipThumbnail)
6034e4ffb4 TOLTECS: - Don't add test entries to the save/loadgame menu
8f3b287db1 TOLTECS: Update todo (no real fixes, though)
9c3a4bc055 TOLTECS: - Implement kSupportsLoadingDuringStartup
5e154f634a TOLTECS: Fixed compilation
ce7f9a088c TOLTECS: - Work on the menu system (use strings from resources instead of hardcoded ones)
9698127c5d TOLTECS: - Undef menu test code (oops)
1cb95f36e7 TOLTECS: - More work on the menu system, saving and loading from there is now possible
661ce95478 TOLTECS: - Fix regression in movie player (use drawScreen instead of updateScreen)
8203563c69 TOLTECS: - New constant kMaxChannels instead of number for clarity
dde75d709e TOLTECS: Fix compilation
d3811422f8 TOLTECS: Fixed compilation and reduced header dependencies a bit
c52aa31a18 TOLTECS: Added some FIXME comments
febda31f50 TOLTECS: Reduced header dependencies
e9dc055089 TOLTECS: Reduced header dependencies
a9f7094a68 TOLTECS: Reduced header dependencies
7746fbc543 TOLTECS: Reduced header dependencies
26a7bf4eb5 TOLTECS: Reduced header dependencies
e1f795fb6d TOLTECS: Added ScummVM headers
4cc5934d84 TOLTECS: Reduced header dependencies
e1abe47fbe TOLTECS: Reduced header dependencies and removed a TODO
75842b031f TOLTECS: Added comments on main game loop, and added a FIXME
3f78e1c8d9 TOLTECS: Rewrote ArchiveReader::dump() to use Common::DumpFile()
581f0ba8b5 TOLTECS: Use CursorMan instead of OSystem for showMouse
02514db64f TOLTECS: Sync with the latest changes in trunk
e4005ae927 TOLTECS: Fix compilation after sound->audio directory rename.
e1fefefff2 TOLTECS: Updated For OSystem Palette RGBA->RGB Change.
acd4d4098f TOLTECS: Fix bugs
a3007d6e2a TOLTECS: Fix Compilation After Base Code Header Changes.
9f3cc261c2 TOLTECS: Fix Compilation After Graphics::Surface PixelFormat changes.
ae4437aea4 TOLTECS: Fix compilation
ddaf38bdcd TOLTECS: Fix Compilation After Common::RandomSource Changes in Latest master.
8a34de2c45 TOLTECS: Replace snprintf() usage with Common::String::format()
3967da03ef TOLTECS: Fix Compilation With Latest Git Master.
eb0b7c957f TOLTECS: Update AdvancedMetaEngine For Removal of ADParams.
4ba1f78dc5 TOLTECS: Fix Detection For ADParams Removal From AdvancedMetaEngine.
c545a8b176 TOLTECS: Fix saveGameState signature to match Engine's virtual method.
9b885d0c50 TOLTECS: Removed now uneeded c_str() call.
86e6ec89ef TOLTECS: Fix Compilation due to Graphics::loadThumbnail() API change.
9b487e917d TOLTECS: Switch to initGraphics() call, rather than separate calls.
522c1ca32b TOLTECS: Bugfixes for the game menu
1eed5caff5 TOLTECS: Some cleanup of the menu code
84e6ceafbf TOLTECS: Initialize mouse cursor when loading a saved game from the launcher
4a03bb3e43 TOLTECS: Disabled some leftover unnecessary debug output
48e0238ed0 TOLTECS: Updated the TODO, after talking with johndoe
6fc40c7c24 TOLTECS: Updated TODO
2b29dfe0c7 TOLTECS: Added the ability to skip the current dialog line with the escape key
5298859cba TOLTECS: The resource cache is now purged when changing rooms
9f8ceaace2 TOLTECS: Implemented Quit game functionality in the menu
8940d7348a TOLTECS: Add finalize() calls to file output code
360bd6edd3 TOLTECS: Initial implementation for music
9841ce6b9f TOLTECS: Code cleanup
5c3c9f4e6c TOLTECS: Added a hack to fix a crash when smoking the peace pipe
14cbfd4607 TOLTECS: Fixed typo
1bddee1e73 TOLTECS: Fixed music looping
b6c3232ea3 TOLTECS: Updated TODO
fee561c039 TOLTECS: Updated TODO
f3fdcad214 TOLTECS: Updated TODO
a8112121b2 TOLTECS: Cleanup
8b4c082f6d TOLTECS: Stop all sounds when exiting
94f5b8b190 TOLTECS: Always hide the game interface when showing a movie
c119cbda90 TOLTECS: Slight cleanup of the audio code
8b503f558e TOLTECS: Fixed compilation after the latest changes to GUI options
e4d5320e7f TOLTECS: Fixed typo in logic
579c47b717 TOLTECS: Removed duplicate assignment
4c60382604 TOLTECS: integrate engine
b592d73e62 TOLTECS: silence a couple gcc warnings
2613e7f587 TOLTECS: Merge toltecs engine
Commit: 7c2835313ee3c68e6ac753782b63a9dd485b0a60
https://github.com/scummvm/scummvm/commit/7c2835313ee3c68e6ac753782b63a9dd485b0a60
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Initial checkin
Changed paths:
A engines/toltecs/animation.cpp
A engines/toltecs/animation.h
A engines/toltecs/detection.cpp
A engines/toltecs/input.cpp
A engines/toltecs/input.h
A engines/toltecs/module.mk
A engines/toltecs/palette.cpp
A engines/toltecs/palette.h
A engines/toltecs/resource.cpp
A engines/toltecs/resource.h
A engines/toltecs/screen.cpp
A engines/toltecs/screen.h
A engines/toltecs/script.cpp
A engines/toltecs/script.h
A engines/toltecs/segmap.cpp
A engines/toltecs/segmap.h
A engines/toltecs/toltecs.cpp
A engines/toltecs/toltecs.h
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
new file mode 100644
index 0000000..2dbffbd
--- /dev/null
+++ b/engines/toltecs/animation.cpp
@@ -0,0 +1,139 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/animation.h"
+#include "toltecs/screen.h"
+
+namespace Toltecs {
+
+AnimationPlayer::AnimationPlayer(ToltecsEngine *vm) : _vm(vm) {
+ _animBuffer = new byte[262144];
+}
+
+AnimationPlayer::~AnimationPlayer() {
+ delete[] _animBuffer;
+}
+
+void AnimationPlayer::start(uint resIndex) {
+ debug(1, "AnimationPlayer::start(%d)", resIndex);
+
+ _resIndex = resIndex;
+
+ _vm->_arc->openResource(_resIndex);
+ _height = _vm->_arc->readUint16LE();
+ _width = _vm->_arc->readUint16LE();
+ _frameCount = _vm->_arc->readUint16LE();
+ _vm->_arc->read(_palette, 768);
+ _curFrameSize = _vm->_arc->readUint32LE();
+ _nextFrameOffset = _curFrameSize + 782;
+ _vm->_arc->read(_animBuffer, _curFrameSize);
+ _nextFrameSize = _vm->_arc->readUint32LE();
+ _vm->_arc->closeResource();
+
+ debug(1, "AnimationPlayer::start() width = %d; height = %d; frameCount = %d", _width, _height, _frameCount);
+
+ unpackFrame();
+
+ _keepFrameCounter = 0;
+ _frameNumber = 0;
+ // TODO mov screenFlag01, 0FFFFh
+ // TODO mov animDrawFrameFlag, 0FFFFh
+
+ _firstNextFrameOffset = _nextFrameOffset;
+ _firstCurFrameSize = _curFrameSize;
+ _firstNextFrameSize = _nextFrameSize;
+
+}
+
+void AnimationPlayer::nextFrame() {
+ debug(1, "AnimationPlayer::nextFrame()");
+
+ if (_frameNumber == _frameCount) {
+ _nextFrameOffset = _firstNextFrameOffset;
+ _curFrameSize = _firstCurFrameSize;
+ _nextFrameSize = _firstNextFrameSize;
+ _frameNumber = 1;
+ } else {
+ _frameNumber++;
+ }
+
+ debug(1, "AnimationPlayer::nextFrame() frameNumber = %d", _frameNumber);
+
+ if (_keepFrameCounter > 0) {
+ _keepFrameCounter--;
+ return;
+ }
+
+ _vm->_arc->openResource(_resIndex);
+ _vm->_arc->seek(_nextFrameOffset, SEEK_CUR);
+ _curFrameSize = _nextFrameSize;
+
+ if (_curFrameSize == 0)
+ _curFrameSize = 1;
+
+ _vm->_arc->read(_animBuffer, _curFrameSize);
+ _nextFrameSize = _vm->_arc->readUint32LE();
+ _nextFrameOffset += _curFrameSize + 4;
+
+ if (_curFrameSize > 1) {
+ unpackFrame();
+ // TODO mov animDrawFrameFlag, 0FFFFh
+ } else {
+ _keepFrameCounter = _animBuffer[0] - 1;
+ // TODO mov animDrawFrameFlag, 0
+ }
+
+ _vm->_arc->closeResource();
+
+
+}
+
+int16 AnimationPlayer::getStatus() {
+ debug(1, "AnimationPlayer::getStatus()");
+ int16 status = -1;
+ if (_frameNumber == _frameCount)
+ status = 0;
+ else if (_frameNumber == _frameCount - 1)
+ status = 1;
+ debug(1, "AnimationPlayer::getStatus() status = %d", status);
+ return status;
+}
+
+void AnimationPlayer::unpackFrame() {
+ _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_frontScreen, _width, _height);
+ _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_backScreen, _width, _height);
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/animation.h b/engines/toltecs/animation.h
new file mode 100644
index 0000000..dc48421
--- /dev/null
+++ b/engines/toltecs/animation.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_ANIMATION_H
+#define TOLTECS_ANIMATION_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+class AnimationPlayer {
+public:
+ AnimationPlayer(ToltecsEngine *vm);
+ ~AnimationPlayer();
+
+ void start(uint resIndex);
+ void nextFrame();
+ int16 getStatus();
+ uint16 getFrameNumber() const { return _frameNumber; }
+
+//protected:
+public:
+ ToltecsEngine *_vm;
+
+ // 262144
+ byte *_animBuffer;
+
+ uint _resIndex;
+ byte _palette[768];
+
+ uint16 _width, _height;
+ uint16 _frameNumber, _frameCount;
+ uint32 _keepFrameCounter;
+
+ uint32 _curFrameSize;
+ uint32 _nextFrameSize, _nextFrameOffset;
+
+ uint32 _firstNextFrameOffset, _firstCurFrameSize, _firstNextFrameSize;
+
+ void unpackFrame();
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_ANIMATION_H */
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
new file mode 100644
index 0000000..37c1ec4
--- /dev/null
+++ b/engines/toltecs/detection.cpp
@@ -0,0 +1,121 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "base/plugins.h"
+
+#include "common/advancedDetector.h"
+#include "common/file.h"
+
+#include "toltecs/toltecs.h"
+
+
+namespace Toltecs {
+
+struct ToltecsGameDescription {
+ Common::ADGameDescription desc;
+};
+
+uint32 ToltecsEngine::getFeatures() const {
+ return _gameDescription->desc.flags;
+}
+
+Common::Language ToltecsEngine::getLanguage() const {
+ return _gameDescription->desc.language;
+}
+
+}
+
+static const PlainGameDescriptor toltecsGames[] = {
+ {"toltecs", "3 Skulls of the Toltecs"},
+ {0, 0}
+};
+
+
+namespace Toltecs {
+
+static const ToltecsGameDescription gameDescriptions[] = {
+
+ {
+ // Toltecs English version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "05472037e9cfde146e953c434e74f0f4", 337643527),
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ Common::ADGF_NO_FLAGS
+ },
+ },
+
+ { AD_TABLE_END_MARKER }
+};
+
+} // End of namespace Toltecs
+
+static const Common::ADParams detectionParams = {
+ // Pointer to ADGameDescription or its superset structure
+ (const byte *)Toltecs::gameDescriptions,
+ // Size of that superset structure
+ sizeof(Toltecs::ToltecsGameDescription),
+ // Number of bytes to compute MD5 sum for
+ 5000,
+ // List of all engine targets
+ toltecsGames,
+ // Structure for autoupgrading obsolete targets
+ 0,
+ // Name of single gameid (optional)
+ "toltecs",
+ // List of files for file-based fallback detection (optional)
+ 0,
+ // Flags
+ 0
+};
+
+class ToltecsMetaEngine : public Common::AdvancedMetaEngine {
+public:
+ ToltecsMetaEngine() : Common::AdvancedMetaEngine(detectionParams) {}
+
+ virtual const char *getName() const {
+ return "Toltecs Engine";
+ }
+
+ virtual const char *getCopyright() const {
+ return "Toltecs Engine (C) 1996";
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+};
+
+bool ToltecsMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
+ const Toltecs::ToltecsGameDescription *gd = (const Toltecs::ToltecsGameDescription *)desc;
+ if (gd) {
+ *engine = new Toltecs::ToltecsEngine(syst, gd);
+ }
+ return gd != 0;
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(TOLTECS)
+ REGISTER_PLUGIN_DYNAMIC(TOLTECS, PLUGIN_TYPE_ENGINE, ToltecsMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(TOLTECS, PLUGIN_TYPE_ENGINE, ToltecsMetaEngine);
+#endif
diff --git a/engines/toltecs/input.cpp b/engines/toltecs/input.cpp
new file mode 100644
index 0000000..50e9129
--- /dev/null
+++ b/engines/toltecs/input.cpp
@@ -0,0 +1,133 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/input.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+Input::Input(ToltecsEngine *vm) : _vm(vm) {
+
+ _mouseX = 0;
+ _mouseY = 0;
+ _mousePosDelta = 0;
+ _mouseCounter = 0;
+ _mouseButtonPressedFlag = false;
+ _mouseButton = 0;
+ _mouseDisabled = 0;
+
+ _leftButtonDown = false;
+ _rightButtonDown = false;
+
+}
+
+Input::~Input() {
+}
+
+void Input::update() {
+
+ Common::Event event;
+ Common::EventManager *eventMan = _vm->_system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ case Common::EVENT_QUIT:
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _leftButtonDown = true;
+ break;
+ case Common::EVENT_LBUTTONUP:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _leftButtonDown = false;
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _rightButtonDown = true;
+ break;
+ case Common::EVENT_RBUTTONUP:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _rightButtonDown = false;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (_mouseDisabled == 0) {
+ _mousePosDelta = _mousePosDelta + _mouseY - _mouseX;
+
+ if (_mouseCounter > 0)
+ _mouseCounter--;
+
+ byte mouseButtons = 0;
+ if (_leftButtonDown)
+ mouseButtons |= 1;
+ if (_rightButtonDown)
+ mouseButtons |= 2;
+
+ if (mouseButtons != 0) {
+ if (!_mouseButtonPressedFlag) {
+ _mouseButton = mouseButtons;
+ if (_mouseCounter != 0)
+ _mouseButton |= 0x80;
+ _mouseCounter = 30; // maybe TODO
+ _mouseButtonPressedFlag = true;
+ } else {
+ _mouseButton = 0;
+ }
+ } else {
+ _mouseButtonPressedFlag = false;
+ _mouseButton = 0;
+ }
+
+ }
+
+}
+
+int16 Input::getMouseDeltaStuff(int16 divisor) {
+ return ABS(_mousePosDelta % divisor);
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/input.h b/engines/toltecs/input.h
new file mode 100644
index 0000000..c82dd78
--- /dev/null
+++ b/engines/toltecs/input.h
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_INPUT_H
+#define TOLTECS_INPUT_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+class Input {
+public:
+ Input(ToltecsEngine *vm);
+ ~Input();
+
+ void update();
+
+ void enableMouse();
+ void disableMouse();
+
+ int16 getMouseDeltaStuff(int16 divisor);
+
+//protected:
+public:
+ ToltecsEngine *_vm;
+
+ int16 _mouseX, _mouseY;
+ int16 _mousePosDelta;
+ int16 _mouseCounter;
+ bool _mouseButtonPressedFlag;
+ byte _mouseButton;
+ int16 _mouseDisabled;
+
+ bool _leftButtonDown, _rightButtonDown;
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_INPUT_H */
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
new file mode 100644
index 0000000..63a8043
--- /dev/null
+++ b/engines/toltecs/module.mk
@@ -0,0 +1,21 @@
+MODULE := engines/toltecs
+
+MODULE_OBJS = \
+ animation.o \
+ detection.o \
+ input.o \
+ palette.o \
+ toltecs.o \
+ resource.o \
+ screen.o \
+ script.o \
+ segmap.o
+
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_TOLTECS), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
new file mode 100644
index 0000000..6ff20ff
--- /dev/null
+++ b/engines/toltecs/palette.cpp
@@ -0,0 +1,157 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+Palette::Palette(ToltecsEngine *vm) : _vm(vm) {
+
+ clearFragments();
+
+}
+
+Palette::~Palette() {
+}
+
+void Palette::setFullPalette(byte *palette) {
+ byte colors[1024];
+ for (int i = 0; i < 256; i++) {
+ colors[i * 4 + 0] = palette[i * 3 + 0] << 2;
+ colors[i * 4 + 1] = palette[i * 3 + 1] << 2;
+ colors[i * 4 + 2] = palette[i * 3 + 2] << 2;
+ colors[i * 4 + 3] = 255;
+ }
+ _vm->_system->setPalette((const byte *)colors, 0, 256);
+ _vm->_system->updateScreen();
+}
+
+void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex) {
+
+ byte colors[1024];
+
+ byte *palPtr = palette + startIndex * 3;
+ int16 index = startIndex, colorCount = count;
+ byte rgb;
+
+ count++;
+
+ mask &= 7;
+
+ _vm->_system->grabPalette(colors, 0, 256);
+
+ if (deltaValue < 0) {
+ deltaValue = -deltaValue;
+ while (count--) {
+ rgb = *palPtr++;
+ if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ rgb = *palPtr++;
+ if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ rgb = *palPtr++;
+ if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ index++;
+ }
+ } else {
+ while (count--) {
+ rgb = *palPtr++;
+ if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
+ rgb = *palPtr++;
+ if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
+ rgb = *palPtr++;
+ if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
+ index++;
+ }
+ }
+
+ debug(0, "startIndex = %d; colorCount = %d", startIndex, colorCount);
+
+ _vm->_system->setPalette((const byte *)colors, 0, 256);
+
+}
+
+void Palette::loadAddPalette(uint resIndex, byte startIndex) {
+ byte *data = _vm->_res->load(resIndex);
+ memcpy(&_mainPalette[startIndex * 3], data, _vm->_res->getCurItemSize());
+}
+
+void Palette::loadAddPaletteFrom(byte *source, byte startIndex, byte count) {
+ memcpy(&_mainPalette[startIndex * 3], source, count * 3);
+}
+
+void Palette::addFragment(uint resIndex, int16 id) {
+ debug(0, "Palette::addFragment(%d, %d)", resIndex, id);
+
+ byte *fragmentData = _vm->_res->load(resIndex);
+ byte count = _vm->_res->getCurItemSize() / 3;
+
+ memcpy(&_mainPalette[_fragmentIndex * 3], fragmentData, count * 3);
+
+ PaletteFragment fragment;
+ fragment.id = id;
+ fragment.index = _fragmentIndex;
+ fragment.count = count;
+ _fragments.push_back(fragment);
+
+ debug(0, "Palette::addFragment() index = %02X; count = %02X", fragment.index, fragment.count);
+
+ _fragmentIndex += count;
+
+}
+
+uint16 Palette::findFragment(int16 id) {
+ debug(0, "Palette::findFragment(%d)", id);
+
+ uint16 result = 0;
+ for (PaletteFragmentArray::iterator iter = _fragments.begin(); iter != _fragments.end(); iter++) {
+ PaletteFragment fragment = *iter;
+ if (fragment.id == id) {
+ result = (fragment.count << 8) | fragment.index;
+ break;
+ }
+ }
+
+ debug(0, "Palette::findFragment() result = %04X", result);
+
+ return result;
+}
+
+void Palette::clearFragments() {
+ debug(0, "Palette::clearFragments()");
+ _fragmentIndex = 128;
+ _fragments.clear();
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h
new file mode 100644
index 0000000..b550b80
--- /dev/null
+++ b/engines/toltecs/palette.h
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_PALETTE_H
+#define TOLTECS_PALETTE_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+//#define ROT(index) (((index << 4) & 0xF0) | ((index >> 4) & 0x0F))
+//#define ROT(index) (index)
+
+class Palette {
+public:
+ Palette(ToltecsEngine *vm);
+ ~Palette();
+
+ void setFullPalette(byte *palette);
+ void setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex);
+
+ void loadAddPalette(uint resIndex, byte startIndex);
+ void loadAddPaletteFrom(byte *source, byte startIndex, byte count);
+
+ void addFragment(uint resIndex, int16 id);
+ uint16 findFragment(int16 id);
+ void clearFragments();
+
+ byte *getMainPalette() { return _mainPalette; }
+
+protected:
+
+ struct PaletteFragment {
+ int16 id;
+ byte index, count;
+ };
+
+ typedef Common::Array<PaletteFragment> PaletteFragmentArray;
+
+ ToltecsEngine *_vm;
+
+ byte _mainPalette[768];
+
+ PaletteFragmentArray _fragments;
+ byte _fragmentIndex;
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_PALETTE_H */
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
new file mode 100644
index 0000000..0280467
--- /dev/null
+++ b/engines/toltecs/resource.cpp
@@ -0,0 +1,161 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+
+/* ArchiveReader */
+
+ArchiveReader::ArchiveReader() {
+}
+
+ArchiveReader::~ArchiveReader() {
+}
+
+void ArchiveReader::openArchive(const char *filename) {
+ open(filename);
+ for (uint i = 0; i < 10000; i++)
+ _offsets[i] = readUint32LE();
+}
+
+uint32 ArchiveReader::openResource(uint resIndex) {
+ uint32 resourceSize = getResourceSize(resIndex);
+ seek(_offsets[resIndex]);
+ return resourceSize;
+}
+
+void ArchiveReader::closeResource() {
+}
+
+
+uint32 ArchiveReader::getResourceSize(uint resIndex) {
+ return _offsets[resIndex + 1] - _offsets[resIndex];
+}
+
+void ArchiveReader::dump(uint resIndex, const char *prefix) {
+ int32 resourceSize = getResourceSize(resIndex);
+ byte *data = new byte[resourceSize];
+
+ char fn[256];
+
+ if (prefix)
+ snprintf(fn, 256, "%s_%04X.0", prefix, resIndex);
+ else
+ snprintf(fn, 256, "%04X.0", resIndex);
+
+ openResource(resIndex);
+ read(data, resourceSize);
+ closeResource();
+
+ FILE *o = fopen(fn, "wb");
+ fwrite(data, resourceSize, 1, o);
+ fclose(o);
+
+ delete[] data;
+}
+
+/* ResourceCache */
+
+ResourceCache::ResourceCache(ToltecsEngine *vm) : _vm(vm) {
+
+ _base = new byte[kMaxCacheSize];
+ _bytesUsed = 0;
+
+ memset(_cache, 0, sizeof(_cache));
+ _cacheCount = 0;
+
+ _curItemOffset = 0;
+ _curItemSize = 0;
+
+}
+
+ResourceCache::~ResourceCache() {
+ delete[] _base;
+}
+
+byte *ResourceCache::load(uint resIndex) {
+ byte *data = NULL;
+ if (existsItem(resIndex)) {
+ debug(1, "ResourceCache::load(%d) From cache", resIndex);
+ data = _base + _curItemOffset;
+ } else {
+ debug(1, "ResourceCache::load(%d) From disk", resIndex);
+ uint32 size = _vm->_arc->openResource(resIndex);
+ data = addItem(resIndex, size);
+ _vm->_arc->read(data, size);
+ _vm->_arc->closeResource();
+ }
+ return data;
+}
+
+bool ResourceCache::existsItem(uint resIndex) {
+ for (uint i = 0; i < _cacheCount; i++) {
+ if (_cache[i].resIndex == resIndex) {
+ _curItemOffset = _cache[i].offset;
+ _curItemSize = _cache[i].size;
+ return true;
+ }
+ }
+ return false;
+}
+
+byte *ResourceCache::addItem(uint resIndex, uint32 size) {
+
+ checkCapacity(size);
+
+ _curItemOffset = _bytesUsed;
+ _curItemSize = size;
+
+ _cache[_cacheCount].resIndex = resIndex;
+ _cache[_cacheCount].offset = _curItemOffset;
+ _cache[_cacheCount].size = _curItemSize;
+ _cacheCount++;
+
+ _bytesUsed += size;
+
+ return _base + _curItemOffset;
+
+}
+
+void ResourceCache::checkCapacity(uint32 size) {
+ if (_cacheCount > kMaxCacheItems || _bytesUsed + size > kMaxCacheSize) {
+ _cacheCount = 0;
+ _bytesUsed = 0;
+ }
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h
new file mode 100644
index 0000000..c15918b
--- /dev/null
+++ b/engines/toltecs/resource.h
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_RESOURCE_H
+#define TOLTECS_RESOURCE_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+/*
+ TODO:
+
+ ArchiveReader:
+ - Add support for external resources; and check if they're used
+
+*/
+
+const uint kMaxCacheItems = 1024;
+const uint kMaxCacheSize = 8 * 1024 * 1024; // 8 MB
+
+
+class ArchiveReader : public Common::File {
+public:
+ ArchiveReader();
+ ~ArchiveReader();
+
+ void openArchive(const char *filename);
+
+ // Returns the size of the opened resource
+ uint32 openResource(uint resIndex);
+ // Closes the resource
+ void closeResource();
+ // Returns the size of the resource
+ uint32 getResourceSize(uint resIndex);
+
+ void dump(uint resIndex, const char *prefix = NULL);
+
+protected:
+ uint32 _offsets[10000];
+
+};
+
+class ResourceCache {
+public:
+ ResourceCache(ToltecsEngine *vm);
+ ~ResourceCache();
+
+ byte *load(uint resIndex);
+ uint32 getCurItemSize() const { return _curItemSize; }
+
+protected:
+
+ struct CacheItem {
+ uint resIndex;
+ //int value; // what is this?
+ int32 offset; // offset into _base
+ uint32 size; // size of the item
+ };
+
+ ToltecsEngine *_vm;
+
+ byte *_base;
+ uint32 _bytesUsed;
+ uint32 _curItemOffset, _curItemSize;
+
+ CacheItem _cache[kMaxCacheItems];
+ uint _cacheCount;
+
+ bool existsItem(uint resIndex);
+ byte *addItem(uint resIndex, uint32 size);
+ void checkCapacity(uint32 size);
+
+};
+
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_H */
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
new file mode 100644
index 0000000..69d2966
--- /dev/null
+++ b/engines/toltecs/screen.cpp
@@ -0,0 +1,971 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "graphics/cursorman.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+#include "toltecs/script.h"
+#include "toltecs/segmap.h"
+
+namespace Toltecs {
+
+Screen::Screen(ToltecsEngine *vm) : _vm(vm) {
+
+ _frontScreen = new byte[268800];
+ _backScreen = new byte[870400];
+
+ memset(_fontResIndexArray, 0, sizeof(_fontResIndexArray));
+ _fontColor1 = 0;
+ _fontColor2 = 0;
+
+ // Screen shaking
+ _shakeActive = false;
+ _shakeCounterInit = 0;
+ _shakeCounter = 0;
+ _shakePos = 0;
+
+ // Verb line
+ _verbLineNum = 0;
+ memset(_verbLineItems, 0, sizeof(_verbLineItems));
+ _verbLineX = 160;
+ _verbLineY = 2;
+ _verbLineWidth = 20;
+ _verbLineCount = 0;
+
+ // Talk text
+ _talkTextItemNum = 0;
+ memset(_talkTextItems, 0, sizeof(_talkTextItems));
+ _talkTextX = 0;//TODO correct init values
+ _talkTextY = 0;
+ _talkTextFontColor = 0;
+ _talkTextMaxWidth = 520;
+
+}
+
+Screen::~Screen() {
+
+ delete[] _frontScreen;
+ delete[] _backScreen;
+
+}
+
+void Screen::unpackRle(byte *source, byte *dest, uint16 width, uint16 height) {
+ int32 size = width * height;
+ while (size > 0) {
+ byte a = *source++;
+ byte b = *source++;
+ if (a == 0) {
+ dest += b;
+ size -= b;
+ } else {
+ b = ((b << 4) & 0xF0) | ((b >> 4) & 0x0F);
+ memset(dest, b, a);
+ dest += a;
+ size -= a;
+ }
+ }
+}
+
+void Screen::loadMouseCursor(uint resIndex) {
+ byte mouseCursor[16 * 16], *mouseCursorP = mouseCursor;
+ byte *cursorData = _vm->_res->load(resIndex);
+ for (int i = 0; i < 32; i++) {
+ byte pixel;
+ byte mask1 = *cursorData++;
+ byte mask2 = *cursorData++;
+ for (int j = 0; j < 8; j++) {
+ pixel = 0xE5;
+ if ((mask2 & 0x80) == 0)
+ pixel = 0xE0;
+ mask2 <<= 1;
+ if ((mask1 & 0x80) == 0)
+ pixel = 0;
+ mask1 <<= 1;
+ *mouseCursorP++ = pixel;
+ }
+ }
+ //CursorMan.replaceCursor((const byte*)mouseCursor, 16, 16, 0, 0, 0);
+ // FIXME: Where's the cursor hotspot? Using 8, 8 seems good enough for now.
+ CursorMan.replaceCursor((const byte*)mouseCursor, 16, 16, 8, 8, 0);
+}
+
+void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
+
+ byte *imageData = _vm->_res->load(resIndex);
+ int16 headerSize = READ_LE_UINT16(imageData);
+ int16 width = imageData[2];
+ int16 height = imageData[3];
+ int16 workWidth = width, workHeight = height;
+ imageData += headerSize;
+
+ byte *dest = _frontScreen + x + (y + _vm->_cameraHeight) * 640;
+
+ debug(0, "Screen::drawGuiImage() x = %d; y = %d; w = %d; h = %d; resIndex = %d", x, y, width, height, resIndex);
+
+ //_vm->_arc->dump(resIndex, "gui");
+
+ while (workHeight > 0) {
+ int count = 1;
+ byte pixel = *imageData++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ count = *imageData++;
+ count += 2;
+ }
+ pixel = pixel + 0xE0;
+ while (count-- && workHeight > 0) {
+ *dest++ = pixel;
+ workWidth--;
+ if (workWidth == 0) {
+ workHeight--;
+ dest += 640 - width;
+ workWidth = width;
+ }
+ }
+ }
+
+}
+
+void Screen::startShakeScreen(int16 shakeCounter) {
+ _shakeActive = true;
+ _shakeCounterInit = shakeCounter;
+ _shakeCounter = shakeCounter;
+ _shakePos = 0;
+}
+
+void Screen::stopShakeScreen() {
+ _shakeActive = false;
+ _vm->_system->setShakePos(0);
+}
+
+void Screen::updateShakeScreen() {
+ if (_shakeActive) {
+ _shakeCounter--;
+ if (_shakeCounter == 0) {
+ _shakeCounter = _shakeCounterInit;
+ _shakePos ^= 8;
+ _vm->_system->setShakePos(_shakePos);
+ }
+ }
+}
+
+void Screen::addStaticSprite(byte *spriteItem) {
+
+ DrawRequest drawRequest;
+ memset(&drawRequest, 0, sizeof(drawRequest));
+
+ drawRequest.y = READ_LE_UINT16(spriteItem + 0);
+ drawRequest.x = READ_LE_UINT16(spriteItem + 2);
+ int16 fragmentId = READ_LE_UINT16(spriteItem + 4);
+ drawRequest.baseColor = _vm->_palette->findFragment(fragmentId) & 0xFF;
+ drawRequest.resIndex = READ_LE_UINT16(spriteItem + 6);
+ drawRequest.flags = READ_LE_UINT16(spriteItem + 8);
+ drawRequest.scaling = 0;
+
+ debug(0, "Screen::addStaticSprite() x = %d; y = %d; baseColor = %d; resIndex = %d; flags = %04X", drawRequest.x, drawRequest.y, drawRequest.baseColor, drawRequest.resIndex, drawRequest.flags);
+
+ addDrawRequest(drawRequest);
+
+}
+
+void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, int16 *spriteArray, bool loop, int mode) {
+
+ debug(0, "Screen::addAnimatedSprite(%d, %d, %d)", x, y, fragmentId);
+
+ DrawRequest drawRequest;
+ memset(&drawRequest, 0, sizeof(drawRequest));
+
+ drawRequest.x = x;
+ drawRequest.y = y;
+ drawRequest.baseColor = _vm->_palette->findFragment(fragmentId) & 0xFF;
+
+ if (mode == 1) {
+ drawRequest.scaling = _vm->_segmap->getScalingAtPoint(drawRequest.x, drawRequest.y);
+ } else if (mode == 2) {
+ drawRequest.scaling = 0;
+ }
+
+ int16 count = spriteArray[0];
+
+ debug(0, "count = %d", count);
+
+ for (int16 index = 1; index <= count; index++) {
+
+ byte *spriteItem = data + spriteArray[index];
+
+ uint16 loopNum = READ_LE_UINT16(spriteItem + 0) & 0x7FFF;
+ uint16 loopCount = READ_LE_UINT16(spriteItem + 2);
+ uint16 frameNum = READ_LE_UINT16(spriteItem + 4);
+ uint16 frameCount = READ_LE_UINT16(spriteItem + 6);
+ drawRequest.resIndex = READ_LE_UINT16(spriteItem + 8);
+ drawRequest.flags = READ_LE_UINT16(spriteItem + 10 + loopNum * 2);
+
+ debug(0, "Screen::addAnimatedSprite(%d of %d) loopNum = %d; loopCount = %d; frameNum = %d; frameCount = %d; resIndex = %d; flags = %04X, mode = %d",
+ index, count, loopNum, loopCount, frameNum, frameCount, drawRequest.resIndex, drawRequest.flags, mode);
+
+ addDrawRequest(drawRequest);
+
+ frameNum++;
+ if (frameNum == frameCount) {
+ frameNum = 0;
+ loopNum++;
+ if (loopNum == loopCount) {
+ if (loop) {
+ loopNum = 0;
+ } else {
+ loopNum--;
+ }
+ }
+ } else {
+ loopNum |= 0x8000;
+ }
+
+ WRITE_LE_UINT16(spriteItem + 0, loopNum);
+ WRITE_LE_UINT16(spriteItem + 4, frameNum);
+
+ }
+
+}
+
+void Screen::clearSprites() {
+
+ _spriteDrawList.clear();
+ // TODO
+
+}
+
+void Screen::addDrawRequest(const DrawRequest &drawRequest) {
+
+ int16 scaleValueX, scaleValueY;
+ int16 spriteDraw_X, spriteDraw_Y;
+ byte *spriteData;
+ int16 frameNum;
+
+ SpriteDrawItem sprite;
+ memset(&sprite, 0, sizeof(SpriteDrawItem));
+
+ if (drawRequest.flags == 0xFFFF)
+ return;
+
+ sprite.flags = 0;
+ sprite.baseColor = drawRequest.baseColor;
+ sprite.x = drawRequest.x;
+ sprite.y = drawRequest.y;
+ sprite.ybottom = drawRequest.y;
+ sprite.resIndex = drawRequest.resIndex;
+
+ spriteData = _vm->_res->load(drawRequest.resIndex);
+
+ if (drawRequest.flags & 0x2000) {
+ sprite.flags |= 0x10;
+ }
+
+ if (drawRequest.flags & 0x4000) {
+ sprite.flags |= 0x40;
+ }
+
+ frameNum = drawRequest.flags & 0x0FFF;
+
+ // First initialize the sprite item with the values from the sprite resource
+
+ SpriteFrameEntry spriteFrameEntry(spriteData + frameNum * 12);
+
+ if (spriteFrameEntry.w == 0 || spriteFrameEntry.h == 0)
+ return;
+
+ sprite.offset = spriteFrameEntry.offset;
+
+ sprite.width = spriteFrameEntry.w;
+ sprite.height = spriteFrameEntry.h;
+
+ sprite.origWidth = spriteFrameEntry.w;
+ sprite.origHeight = spriteFrameEntry.h;
+
+ if (drawRequest.flags & 0x1000) {
+ spriteDraw_X = spriteFrameEntry.w - spriteFrameEntry.x;
+ } else {
+ spriteDraw_X = spriteFrameEntry.x;
+ }
+
+ spriteDraw_Y = spriteFrameEntry.y;
+
+ // If the sprite should be scaled we need to initialize some values now
+
+ if (drawRequest.scaling != 0) {
+
+ byte scaleValue = ABS(drawRequest.scaling);
+
+ scaleValueX = scaleValue * sprite.origWidth;
+ sprite.xdelta = (10000 * sprite.origWidth) / scaleValueX;
+ scaleValueX /= 100;
+
+ scaleValueY = scaleValue * sprite.origHeight;
+ sprite.ydelta = (10000 * sprite.origHeight) / scaleValueY;
+ scaleValueY /= 100;
+
+ if (drawRequest.scaling > 0) {
+ sprite.flags |= 2;
+ sprite.width = sprite.origWidth + scaleValueX;
+ sprite.height = sprite.origHeight + scaleValueY;
+ spriteDraw_X += (spriteDraw_X * scaleValue) / 100;
+ spriteDraw_Y += (spriteDraw_Y * scaleValue) / 100;
+ } else {
+ sprite.flags |= 1;
+ sprite.width = sprite.origWidth - scaleValueX;
+ sprite.height = sprite.origHeight - 1 - scaleValueY;
+ if (sprite.width <= 0 || sprite.height <= 0)
+ return;
+ spriteDraw_X -= (spriteDraw_X * scaleValue) / 100;
+ spriteDraw_Y -= (spriteDraw_Y * scaleValue) / 100;
+ }
+
+ }
+
+ sprite.x -= spriteDraw_X;
+ sprite.y -= spriteDraw_Y;
+
+ sprite.yerror = sprite.ydelta;
+
+ // Now we check if the sprite needs to be clipped
+
+ // Clip Y
+ if (sprite.y - _vm->_cameraY < 0) {
+
+ int16 clipHeight = ABS(sprite.y - _vm->_cameraY);
+ int16 chopHeight, skipHeight, lineWidth;
+ byte *spriteFrameData;
+
+ sprite.height -= clipHeight;
+ if (sprite.height <= 0)
+ return;
+
+ sprite.y = _vm->_cameraY;
+
+ // If the sprite is scaled
+ if (sprite.flags & 3) {
+ chopHeight = sprite.ydelta;
+ skipHeight = clipHeight;
+ if ((sprite.flags & 2) == 0) {
+ do {
+ chopHeight -= 100;
+ if (chopHeight <= 0) {
+ skipHeight++;
+ chopHeight += sprite.ydelta;
+ } else {
+ clipHeight--;
+ }
+ } while (clipHeight > 0);
+ } else {
+ do {
+ chopHeight -= 100;
+ if (chopHeight < 0) {
+ skipHeight--;
+ chopHeight += sprite.ydelta + 100;
+ }
+ clipHeight--;
+ } while (clipHeight > 0);
+ }
+ sprite.yerror = chopHeight;
+ }
+
+ spriteFrameData = spriteData + sprite.offset;
+
+ // Now the sprite's offset is adjusted to point to the starting line
+ if ((sprite.flags & 0x10) == 0) {
+ while (clipHeight--) {
+ lineWidth = 0;
+ while (lineWidth </*CHECKME was != */ sprite.origWidth) {
+ sprite.offset++;
+ lineWidth += (*spriteFrameData++) & 0x0F;
+ }
+ }
+ } else {
+ lineWidth = 0;
+ while (clipHeight--) {
+ while (lineWidth < sprite.origWidth) {
+ sprite.offset += 2;
+ spriteFrameData++;
+ lineWidth += *spriteFrameData++;
+ }
+ }
+ }
+
+ }
+
+ if (sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight > 0)
+ sprite.height -= sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight;
+ if (sprite.height <= 0)
+ return;
+
+ sprite.value1 = 0;
+
+ if (drawRequest.flags & 0x1000) {
+ // Left border
+ sprite.flags |= 4;
+ if (sprite.x - _vm->_cameraX < 0) {
+ sprite.width -= ABS(sprite.x - _vm->_cameraX);
+ if (sprite.width <= 0)
+ return;
+ sprite.x = _vm->_cameraX;
+ }
+ // Right border
+ if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
+ sprite.flags |= 8;
+ sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
+ if (sprite.width <= 0)
+ return;
+ sprite.value1 = sprite.x + sprite.width - _vm->_cameraX - 640;
+ }
+ } else {
+ // Left border
+ if (sprite.x - _vm->_cameraX < 0) {
+ sprite.flags |= 8;
+ sprite.width -= ABS(sprite.x - _vm->_cameraX);
+ if (sprite.width <= 0)
+ return;
+ sprite.value1 = ABS(sprite.x - _vm->_cameraX);
+ sprite.x = _vm->_cameraX;
+ }
+ // Right border
+ if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
+ sprite.flags |= 8;
+ sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
+ if (sprite.width <= 0)
+ return;
+ }
+ }
+
+ // Add sprite sorted by priority
+ Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin();
+ while (iter != _spriteDrawList.end() && (*iter).ybottom <= sprite.ybottom) {
+ iter++;
+ }
+ _spriteDrawList.insert(iter, sprite);
+
+}
+
+void Screen::drawSprite(SpriteDrawItem *sprite) {
+
+ debug(0, "Screen::drawSprite() x = %d; y = %d; flags = %04X; resIndex = %d; offset = %08X; drawX = %d; drawY = %d",
+ sprite->x, sprite->y, sprite->flags, sprite->resIndex, sprite->offset,
+ sprite->x - _vm->_cameraX, sprite->y - _vm->_cameraY);
+ debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
+ sprite->width, sprite->height, sprite->origWidth, sprite->origHeight);
+
+ byte *source = _vm->_res->load(sprite->resIndex) + sprite->offset;
+ byte *dest = _frontScreen + (sprite->x - _vm->_cameraX) + (sprite->y - _vm->_cameraY) * 640;
+
+ // FIXME: Temporary hack until proper clipping is implemented
+ /*
+ int16 dx = sprite->x - _vm->_cameraX, dy = sprite->y - _vm->_cameraY;
+ if (dx < 0 || dy < 0 || dx + sprite->width >= 640 || dy + sprite->height >= 400)
+ return;
+ */
+
+ SpriteReader spriteReader(source, sprite);
+
+ if (sprite->flags & 0x40) {
+ // TODO: Shadow sprites
+ } else if (sprite->flags & 0x10) {
+ // 256 color sprite
+ drawSpriteCore(dest, spriteReader, sprite);
+ } else {
+ // 16 color sprite
+ if (sprite->flags & 1) {
+ SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else if (sprite->flags & 2) {
+ SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else {
+ drawSpriteCore(dest, spriteReader, sprite);
+ }
+ }
+
+ debug(0, "Screen::drawSprite() ok");
+
+}
+
+void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite) {
+
+ int16 destInc;
+
+ /*
+ if ((sprite->flags & 8))
+ return;
+ */
+
+ if (sprite->flags & 4) {
+ destInc = -1;
+ dest += sprite->width;
+ } else {
+ destInc = 1;
+ }
+
+ SpriteReaderStatus status;
+ PixelPacket packet;
+
+ byte *destp = dest;
+ int16 skipX = sprite->value1;
+
+ do {
+ status = reader.readPacket(packet);
+
+ if (skipX > 0) {
+ while (skipX > 0) {
+ skipX -= packet.count;
+ if (skipX < 0) {
+ packet.count = ABS(skipX);
+ break;
+ }
+ status = reader.readPacket(packet);
+ }
+ }
+
+ if (((sprite->flags & 0x10) && (packet.pixel != 0xFF)) || !(sprite->flags & 0x10) && (packet.pixel != 0)) {
+ if (sprite->flags & 0x40) {
+ } else if (sprite->flags & 0x10) {
+ packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
+ } else {
+ packet.pixel += sprite->baseColor - 1;
+ }
+ while (packet.count--) {
+ *dest = packet.pixel;
+ dest += destInc;
+ }
+ } else {
+ dest += packet.count * destInc;
+ }
+
+ if (status == kSrsEndOfLine) {
+ dest = destp + 640;
+ destp = dest;
+ skipX = sprite->value1;
+ }
+
+ } while (status != kSrsEndOfSprite);
+
+}
+
+void Screen::drawSprites() {
+ for (Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin(); iter != _spriteDrawList.end(); iter++) {
+ SpriteDrawItem *sprite = &(*iter);
+ drawSprite(sprite);
+ _vm->_segmap->restoreMasksBySprite(sprite);
+ }
+}
+
+void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
+
+ debug(0, "Screen::updateVerbLine() _verbLineNum = %d; _verbLineX = %d; _verbLineY = %d; _verbLineWidth = %d; _verbLineCount = %d",
+ _verbLineNum, _verbLineX, _verbLineY, _verbLineWidth, _verbLineCount);
+
+ Font font(_vm->_res->load(_fontResIndexArray[0]));
+
+ _verbLineItems[_verbLineNum].slotIndex = slotIndex;
+ _verbLineItems[_verbLineNum].slotOffset = slotOffset;
+
+ // First clear the line
+ int16 y = _verbLineY;
+ for (int16 i = 0; i < _verbLineCount; i++) {
+ byte *dest = _frontScreen + _verbLineX - _verbLineWidth / 2 + (y - 1 + _vm->_cameraHeight) * 640;
+ for (int16 j = 0; j < 20; j++) {
+ memset(dest, 0xE0, _verbLineWidth);
+ dest += 640;
+ }
+ y += 18;
+ }
+
+ int width = 0;
+ byte *sourceString;
+ byte *destString;
+ byte len;
+
+ _tempStringLen1 = 0;
+ destString = _tempString;
+ y = _verbLineY;
+
+ memset(_tempString, 0, sizeof(_tempString));
+
+ for (int16 i = 0; i <= _verbLineNum; i++) {
+ sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
+ preprocessText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
+ _tempStringLen1 += len;
+ }
+
+ if (_verbLineCount != 1) {
+ int16 charWidth;
+ if (*sourceString < 0xF0) {
+ while (*sourceString > 0x20 && *sourceString < 0xF0 && len > 0/*CHECKME, len check added*/) {
+ byte ch = *sourceString--;
+ _tempStringLen1--;
+ len--;
+ charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
+ width -= charWidth;
+ }
+ width += charWidth;
+ sourceString++;
+ _tempStringLen1 -= len;
+ _tempStringLen2 = len + 1;
+
+ drawString(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+
+ destString = _tempString;
+ width = 0;
+ preprocessText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
+
+ _tempStringLen1 += len;
+ y += 9;
+ }
+ y += 9;
+ }
+
+ _tempStringLen1 -= len;
+ _tempStringLen2 = len;
+
+ drawString(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+
+}
+
+void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
+
+ int16 x, y, maxWidth, width, length;
+ byte durationModifier = 1;
+ byte *textData = _vm->_script->getSlotData(slotIndex) + slotOffset;
+
+ TalkTextItem *item = &_talkTextItems[_talkTextItemNum];
+
+ item->fontNum = 0;
+ item->color = _talkTextFontColor;
+
+ //debug(0, "## _talkTextMaxWidth = %d", _talkTextMaxWidth);
+
+ x = CLIP<int16>(_talkTextX - _vm->_cameraX, 120, _talkTextMaxWidth);
+ y = CLIP<int16>(_talkTextY - _vm->_cameraY, 4, _vm->_cameraHeight - 16);
+
+ maxWidth = 624 - ABS(x - 320) * 2;
+
+ while (1) {
+ if (*textData == 0x0A) {
+ x = CLIP<int16>(textData[3], 120, _talkTextMaxWidth);
+ y = CLIP<int16>(READ_LE_UINT16(&textData[1]), 4, _vm->_cameraHeight - 16);
+ maxWidth = 624 - ABS(x - 320) * 2;
+ textData += 4;
+ } else if (*textData == 0x14) {
+ item->color = textData[1];
+ textData += 2;
+ } else if (*textData == 0x19) {
+ durationModifier = textData[1];
+ textData += 2;
+ } else if (*textData < 0x0A) {
+ item->fontNum = textData[1];
+ textData += 2;
+ } else
+ break;
+ }
+
+ item->slotIndex = slotIndex;
+ item->slotOffset = textData - _vm->_script->getSlotData(slotIndex);
+
+ width = 0;
+ length = 0;
+
+ item->rectCount = 0;
+
+ Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
+ int16 wordLength, wordWidth;
+
+ while (*textData < 0xF0) {
+ if (*textData == 0x1E) {
+ textData++;
+ addTalkTextRect(font, x, y, length, width, item);
+ // CHECKME?
+ width = 0;
+ length = 0;
+ } else {
+ wordLength = 0;
+ wordWidth = 0;
+ while (*textData >= 0x20 && *textData < 0xF0) {
+ byte ch = *textData++;
+ wordLength++;
+ if (ch == 0x20) {
+ wordWidth += font.getWidth();
+ break;
+ } else {
+ wordWidth += font.getCharWidth(ch) + font.getSpacing() - 1;
+ }
+ }
+
+ debug(0, "## width = %d; wordWidth = %d; width + wordWidth = %d; maxWidth + font.getWidth() = %d",
+ width, wordWidth, width + wordWidth, maxWidth + font.getWidth());
+
+ if (width + wordWidth > maxWidth + font.getWidth()) {
+ addTalkTextRect(font, x, y, length, width, item);
+ width = wordWidth;
+ length = wordLength;
+ } else {
+ width += wordWidth;
+ length += wordLength;
+ }
+ }
+ }
+
+ addTalkTextRect(font, x, y, length, width, item);
+
+ debug(0, "## item->rectCount = %d", item->rectCount);
+
+ int16 textDurationMultiplier = item->duration + 8;
+ // TODO: Check sound/text flags
+ if (*textData == 0xFE) {
+ //textDurationMultiplier += 100;
+ }
+ item->duration = 4 * textDurationMultiplier * durationModifier;
+
+}
+
+void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item) {
+
+ if (width > 0) {
+ TextRect *textRect = &item->rects[item->rectCount];
+ width = width + 1 - font.getSpacing();
+ textRect->width = width;
+ item->duration += length;
+ textRect->length = length;
+ textRect->y = y;
+ textRect->x = CLIP<int16>(x - width / 2, 0, 640);
+ item->rectCount++;
+ }
+
+ y += font.getHeight() - 1;
+
+}
+
+void Screen::drawTalkTextItems() {
+
+ //debug(0, "## _talkTextItemNum = %d", _talkTextItemNum);
+
+ for (int16 i = 0; i <= _talkTextItemNum; i++) {
+ TalkTextItem *item = &_talkTextItems[i];
+ byte *text = _vm->_script->getSlotData(item->slotIndex) + item->slotOffset;
+
+ if (item->fontNum == -1 || item->duration == 0)
+ continue;
+
+ item->duration -= _vm->_counter01;
+ if (item->duration < 0)
+ item->duration = 0;
+
+ Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
+ for (byte j = 0; j < item->rectCount; j++) {
+ int16 x = item->rects[j].x;
+ for (byte pos = 0; pos < item->rects[j].length; pos++) {
+ byte ch = *text++;
+ if (ch < 0x20)
+ continue;
+ if (ch == 0x20) {
+ x += font.getWidth();
+ } else {
+ drawChar2(font, _frontScreen, x, item->rects[j].y, ch, item->color);
+ x += font.getCharWidth(ch) + font.getSpacing() - 1;
+ }
+ }
+ }
+ }
+
+}
+
+int16 Screen::getTalkTextDuration() {
+ return _talkTextItems[_talkTextItemNum].duration;
+}
+
+void Screen::registerFont(uint fontIndex, uint resIndex) {
+ _fontResIndexArray[fontIndex] = resIndex;
+}
+
+void Screen::printText(byte *textData) {
+
+ int16 x = 0, y = 0;
+
+ // Really strange stuff.
+ for (int i = 30; i >= 0; i--) {
+ if (textData[i] >= 0xF0)
+ break;
+ if (i == 0)
+ return;
+ }
+
+ do {
+
+ if (*textData == 0x0A) {
+ // Set text position
+ y = textData[1];
+ x = READ_LE_UINT32(textData + 2);
+ textData += 4;
+ } else if (*textData == 0x0B) {
+ // Inc text position
+ y += textData[1]; // CHECKME: Maybe these are signed?
+ x += textData[2];
+ textData += 3;
+ } else {
+ byte *destString = _tempString;
+ int width = 0;
+ _tempStringLen1 = 0;
+ preprocessText(_fontResIndexArray[1], 640, width, textData, destString, _tempStringLen2);
+ drawString(x - width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1]);
+ }
+
+ } while (*textData != 0xFF);
+
+}
+
+void Screen::preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len) {
+
+ Font font(_vm->_res->load(fontResIndex));
+
+ len = 0;
+ while (*sourceString >= 0x20 && *sourceString < 0xF0) {
+ byte ch = *sourceString;
+ byte charWidth;
+ if (ch <= 0x20)
+ charWidth = font.getWidth();
+ else
+ charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
+ if (width + charWidth >= maxWidth)
+ break;
+ len++;
+ width += charWidth;
+ *destString++ = *sourceString++;
+ }
+}
+
+void Screen::drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex) {
+
+ debug(0, "Screen::drawString(%d, %d, %d, %d, %d) _tempStringLen1 = %d; _tempStringLen2 = %d", x, y, fontColor1, fontColor2, fontResIndex, _tempStringLen1, _tempStringLen2);
+
+ Font font(_vm->_res->load(fontResIndex));
+
+ byte color = fontColor1;
+ byte *text = _tempString;
+ byte len = _tempStringLen1 + _tempStringLen2;
+ int16 yadd = 1;
+
+ for (byte pos = 0; pos < len; pos++) {
+ if (pos == _tempStringLen1) {
+ color = fontColor2;
+ }
+ byte ch = *text++;
+ if (ch <= 0x20) {
+ x += font.getWidth();
+ } else {
+ drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color);
+ x += font.getCharWidth(ch) + font.getSpacing() - 1;
+ yadd = -yadd;
+ }
+ }
+
+}
+
+// TODO: Merge drawChar and drawChar2
+
+void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color) {
+
+ int16 charWidth, charHeight;
+ byte *charData;
+
+ dest += x + (y * 640);
+
+ charWidth = font.getCharWidth(ch);
+ charHeight = font.getHeight() - 2;
+ charData = font.getCharData(ch);
+
+ while (charHeight--) {
+ byte lineWidth = charWidth;
+ while (lineWidth > 0) {
+ byte count = charData[0] & 0x0F;
+ byte flags = charData[0] & 0xF0;
+ charData++;
+ lineWidth -= count;
+ if (!(flags & 0x80) && (flags & 0x10)) {
+ memset(dest, color, count);
+ }
+ dest += count;
+ }
+ dest += 640 - charWidth;
+ }
+
+}
+
+void Screen::drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color) {
+
+ int16 charWidth, charHeight;
+ byte *charData;
+
+ dest += x + (y * 640);
+
+ charWidth = font.getCharWidth(ch);
+ charHeight = font.getHeight() - 2;
+ charData = font.getCharData(ch);
+
+ while (charHeight--) {
+ byte lineWidth = charWidth;
+ while (lineWidth > 0) {
+ byte count = charData[0] & 0x0F;
+ byte flags = charData[0] & 0xF0;
+ charData++;
+ lineWidth -= count;
+
+ if ((flags & 0x80) == 0) {
+ if ((flags & 0x10) == 0) {
+ memset(dest, 0, count);
+ } else {
+ memset(dest, color, count);
+ }
+ }
+
+ dest += count;
+ }
+ dest += 640 - charWidth;
+ }
+
+}
+
+/*
+void Screen::update() {
+}
+*/
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
new file mode 100644
index 0000000..352eeae
--- /dev/null
+++ b/engines/toltecs/screen.h
@@ -0,0 +1,378 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_SCREEN_H
+#define TOLTECS_SCREEN_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/list.h"
+#include "common/array.h"
+
+#include "graphics/surface.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+struct DrawRequest {
+ int16 x, y;
+ int16 resIndex;
+ uint16 flags;
+ int16 baseColor;
+ int8 scaling;
+};
+
+struct SpriteDrawItem {
+ int16 x, y;
+ int16 width, height;
+ int16 origWidth, origHeight;
+ int16 resIndex;
+ uint32 offset;
+ int16 xdelta, ydelta;
+ uint16 flags;
+ int16 value1, yerror;
+ int16 ybottom;
+ int16 baseColor;
+};
+
+struct SpriteFrameEntry {
+ int16 y, x, h, w;
+ uint32 offset;
+ SpriteFrameEntry() {
+ }
+ SpriteFrameEntry(byte *data) {
+ y = READ_LE_UINT16(data + 0);
+ x = READ_LE_UINT16(data + 2);
+ h = READ_LE_UINT16(data + 4);
+ w = READ_LE_UINT16(data + 6);
+ offset = READ_LE_UINT32(data + 8);
+ }
+};
+
+class Font {
+public:
+ Font(byte *fontData) : _fontData(fontData) {
+ }
+ ~Font() {
+ }
+ int16 getSpacing() const {
+ return _fontData[1];
+ }
+ int16 getHeight() const {
+ return _fontData[2];
+ }
+ int16 getWidth() const {
+ return _fontData[3];
+ }
+ int16 getCharWidth(byte ch) const {
+ return _fontData[4 + (ch - 0x21)];
+ }
+ byte *getCharData(byte ch) const {
+ return _fontData + 0x298 + READ_LE_UINT16(&_fontData[0xE0 + (ch - 0x21) * 2]);
+ }
+protected:
+ byte *_fontData;
+};
+
+//*BEGIN*TEST*CODE********************************************************************************************
+
+struct PixelPacket {
+ byte count;
+ byte pixel;
+};
+
+enum SpriteReaderStatus {
+ kSrsPixelsLeft,
+ kSrsEndOfLine,
+ kSrsEndOfSprite
+};
+
+class SpriteFilter {
+public:
+ SpriteFilter(SpriteDrawItem *sprite) : _sprite(sprite) {
+ }
+ virtual SpriteReaderStatus readPacket(PixelPacket &packet) = 0;
+protected:
+ SpriteDrawItem *_sprite;
+};
+
+class SpriteReader : public SpriteFilter {
+public:
+ SpriteReader(byte *source, SpriteDrawItem *sprite) : SpriteFilter(sprite), _source(source) {
+ _curWidth = _sprite->origWidth;
+ _curHeight = _sprite->origHeight;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ if ((_sprite->flags & 0x40) || (_sprite->flags & 0x10)) {
+ packet.pixel = *_source++;
+ packet.count = *_source++;
+ } else {
+ packet.count = _source[0] & 0x0F;
+ packet.pixel = (_source[0] & 0xF0) >> 4;
+ _source++;
+ }
+ _curWidth -= packet.count;
+ if (_curWidth <= 0) {
+ _curHeight--;
+ if (_curHeight == 0) {
+ return kSrsEndOfSprite;
+ } else {
+ _curWidth = _sprite->origWidth;
+ return kSrsEndOfLine;
+ }
+ } else {
+ return kSrsPixelsLeft;
+ }
+ }
+ byte *getSource() {
+ return _source;
+ }
+ void setSource(byte *source) {
+ _source = source;
+ _curHeight++;
+ }
+protected:
+ byte *_source;
+ int16 _curWidth, _curHeight;
+};
+
+class SpriteFilterScaleDown : public SpriteFilter {
+public:
+ SpriteFilterScaleDown(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ _height = _sprite->height;
+ _yerror = _sprite->yerror;
+ _origHeight = _sprite->origHeight;
+ _scalerStatus = 0;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ SpriteReaderStatus status;
+ if (_scalerStatus == 0) {
+ _xerror = _sprite->xdelta;
+ _yerror -= 100;
+ while (_yerror <= 0) {
+ do {
+ status = _reader->readPacket(packet);
+ } while (status == kSrsPixelsLeft);
+ _yerror += _sprite->ydelta - 100;
+ }
+ if (status == kSrsEndOfSprite)
+ return kSrsEndOfSprite;
+ _scalerStatus = 1;
+ }
+ if (_scalerStatus == 1) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ if (packet.count > 0)
+ packet.count--;
+ _xerror += _sprite->xdelta;
+ }
+ }
+ if (status == kSrsEndOfLine) {
+ if (--_height == 0)
+ return kSrsEndOfSprite;
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
+ }
+ }
+ return kSrsPixelsLeft;
+ }
+protected:
+ SpriteReader *_reader;
+ int16 _xerror, _yerror;
+ int16 _height;
+ int16 _origHeight;
+ int _scalerStatus;
+};
+
+class SpriteFilterScaleUp : public SpriteFilter {
+public:
+ SpriteFilterScaleUp(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ _height = _sprite->height;
+ _yerror = _sprite->yerror;
+ _origHeight = _sprite->origHeight;
+ _scalerStatus = 0;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ SpriteReaderStatus status;
+ if (_scalerStatus == 0) {
+ _xerror = _sprite->xdelta;
+ _sourcep = _reader->getSource();
+ _scalerStatus = 1;
+ }
+ if (_scalerStatus == 1) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ packet.count++;
+ _xerror += _sprite->xdelta;
+ }
+ }
+ if (status == kSrsEndOfLine) {
+ if (--_height == 0)
+ return kSrsEndOfSprite;
+ _yerror -= 100;
+ if (_yerror <= 0) {
+ _reader->setSource(_sourcep);
+ _yerror += _sprite->ydelta + 100;
+ }
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
+ }
+ }
+ return kSrsPixelsLeft;
+ }
+protected:
+ SpriteReader *_reader;
+ byte *_sourcep;
+ int16 _xerror, _yerror;
+ int16 _height;
+ int16 _origHeight;
+ int _scalerStatus;
+};
+
+//*END*TEST*CODE**********************************************************************************************
+
+struct TextRect {
+ int16 x, y;
+ int16 width, length;
+};
+
+struct TalkTextItem {
+ int16 duration;
+ int16 slotIndex;
+ int16 slotOffset;
+ int16 fontNum;
+ byte color;
+ byte rectCount;
+ TextRect rects[15];
+};
+
+class Screen {
+public:
+ Screen(ToltecsEngine *vm);
+ ~Screen();
+
+ void unpackRle(byte *source, byte *dest, uint16 width, uint16 height);
+
+ void loadMouseCursor(uint resIndex);
+
+ void drawGuiImage(int16 x, int16 y, uint resIndex);
+
+ void startShakeScreen(int16 shakeCounter);
+ void stopShakeScreen();
+ void updateShakeScreen();
+
+ // Sprite list
+ void addStaticSprite(byte *spriteItem);
+ void addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, int16 *spriteArray, bool loop, int mode);
+ void clearSprites();
+
+ // Sprite drawing
+ void drawSprite(SpriteDrawItem *sprite);
+ void drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite);
+ void drawSprites();
+
+ // Verb line
+ void updateVerbLine(int16 slotIndex, int16 slotOffset);
+
+ // Talk text
+ void updateTalkText(int16 slotIndex, int16 slotOffset);
+ void addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item);
+ void drawTalkTextItems();
+ int16 getTalkTextDuration();
+
+ // Font/text
+ void registerFont(uint fontIndex, uint resIndex);
+ void printText(byte *textData);
+ void preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len);
+ void drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex);
+ void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color);
+ void drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color);
+
+//protected:
+public:
+
+ struct VerbLineItem {
+ int16 slotIndex;
+ int16 slotOffset;
+ };
+
+ struct Rect {
+ int16 x, y, width, height;
+ };
+
+ ToltecsEngine *_vm;
+
+ byte *_frontScreen, *_backScreen;
+
+ Common::List<SpriteDrawItem> _spriteDrawList;
+
+ uint _fontResIndexArray[10];
+ byte _fontColor1, _fontColor2;
+
+ byte _tempString[100];
+ byte _tempStringLen1, _tempStringLen2;
+
+ // Screen shaking
+ bool _shakeActive;
+ int16 _shakeCounterInit, _shakeCounter;
+ int _shakePos;
+
+ // Verb line
+ int16 _verbLineNum;
+ VerbLineItem _verbLineItems[8];
+ int16 _verbLineX, _verbLineY, _verbLineWidth;
+ int16 _verbLineCount;
+
+ // Talk text
+ int16 _talkTextX, _talkTextY;
+ int16 _talkTextMaxWidth;
+ byte _talkTextFontColor;
+ int16 _talkTextItemNum;
+ TalkTextItem _talkTextItems[5];
+
+ void addDrawRequest(const DrawRequest &drawRequest);
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_SCREEN_H */
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
new file mode 100644
index 0000000..5d7e55b
--- /dev/null
+++ b/engines/toltecs/script.cpp
@@ -0,0 +1,1219 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/animation.h"
+#include "toltecs/input.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+#include "toltecs/script.h"
+#include "toltecs/screen.h"
+#include "toltecs/segmap.h"
+
+namespace Toltecs {
+
+ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) {
+
+ _stack = new byte[4096 + 4];
+
+ memset(_slots, 0, sizeof(_slots));
+
+ _savedSp = 0;
+
+}
+
+ScriptInterpreter::~ScriptInterpreter() {
+ delete[] _stack;
+}
+
+void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
+
+ if (_slots[slotIndex].data) {
+ delete[] _slots[slotIndex].data;
+ }
+
+ _slots[slotIndex].resIndex = resIndex;
+ byte *scriptData = _vm->_res->load(resIndex);
+ _slots[slotIndex].size = _vm->_res->getCurItemSize();
+ _slots[slotIndex].data = new byte[_slots[slotIndex].size];
+ memcpy(_slots[slotIndex].data, scriptData, _slots[slotIndex].size);
+
+}
+
+void ScriptInterpreter::runScript(uint slotIndex) {
+
+ _switchStack1 = true;
+ _switchStack2 = false;
+ _switchStack3 = false;
+ _scriptFlag01 = false;
+
+ _regs.reg0 = 0;
+ _regs.reg1 = 0;
+ _regs.reg2 = 0;
+ _regs.reg3 = 0;
+ _regs.reg4 = slotIndex;
+ _regs.reg5 = 0;
+ _regs.reg6 = 0;
+ _regs.sp = 4096;
+ _regs.reg8 = 0;
+
+ _code = getSlotData(_regs.reg4);
+
+ while (1) {
+
+ if (_vm->_movieSceneFlag)
+ _vm->_input->_mouseButton = 0;
+
+ if (_switchStack1) {
+ _switchStack1 = false;
+ _localData = getSlotData(_regs.reg4);
+ }
+
+ if (_switchStack2) {
+ _switchStack2 = false;
+ _localData = getSlotData(_regs.reg5);
+ _switchStack1 = true;
+ }
+
+ if (_switchStack3) {
+ _switchStack3 = false;
+ _localData = _stack + 2;
+ _switchStack1 = true;
+ }
+
+ byte opcode = readByte();
+ execOpcode(opcode);
+
+ // Call updateScreen roughly every 10ms else the mouse cursor will be jerky
+ if (_vm->_system->getMillis() % 10 == 0)
+ _vm->_system->updateScreen();
+
+ }
+
+}
+
+byte ScriptInterpreter::readByte() {
+ return *_code++;
+}
+
+int16 ScriptInterpreter::readInt16() {
+ int16 value = READ_LE_UINT16(_code);
+ _code += 2;
+ return value;
+}
+
+void look(byte *code) {
+ char ln[256];
+ snprintf(ln, 256, "\t\t\t%02X %02X %02X %02X %02X %02X %02X %02X",
+ code[0], code[1], code[2], code[3], code[4], code[5], code[6], code[7]);
+ debug(1, "%s", ln);
+}
+
+void ScriptInterpreter::execOpcode(byte opcode) {
+
+#if 0
+ char ln[256];
+ snprintf(ln, 256, "\t\t\t%02X %02X %02X %02X %02X %02X %02X %02X",
+ _code[0], _code[1], _code[2], _code[3], _code[4], _code[5], _code[6], _code[7]);
+ debug(1, "%s", ln);
+#endif
+
+ int16 ofs;
+
+ debug(1, "opcode = %d", opcode);
+
+ switch (opcode) {
+ case 0:
+ {
+ // ok
+ _subCode = _code;
+ byte length = readByte();
+ debug(1, "length = %d", length);
+ uint16 kernelOpcode = readInt16();
+ debug(1, "callKernel %d", kernelOpcode);
+ execKernelOpcode(kernelOpcode);
+ _code += length - 2;
+ break;
+ }
+ case 1:
+ // ok
+ _regs.reg0 = readInt16();
+ debug(1, "mov reg0, #%d", _regs.reg0);
+ break;
+ case 2:
+ // ok
+ _regs.reg1 = readInt16();
+ debug(1, "mov reg1, #%d", _regs.reg1);
+ break;
+ case 3:
+ // ok
+ _regs.reg3 = readInt16();
+ debug(1, "mov reg3, #%d", _regs.reg3);
+ break;
+ case 4:
+ // ok
+ _regs.reg5 = _regs.reg0;
+ debug(1, "mov reg5, reg0");
+ break;
+ case 5:
+ // ok
+ _regs.reg3 = _regs.reg0;
+ debug(1, "mov reg3, reg0");
+ break;
+ case 6:
+ // ok
+ _regs.reg1 = _regs.reg0;
+ debug(1, "mov reg1, reg0");
+ break;
+ case 7:
+ _regs.reg1 = localRead16(_regs.reg3);
+ debug(1, "mov reg1, *%d", _regs.reg3);
+ break;
+ case 8:
+ localWrite16(_regs.reg3, _regs.reg0);
+ break;
+ case 9:
+ localWrite16(readInt16(), _regs.reg0);
+ break;
+ case 10:
+ localWrite8(readInt16(), _regs.reg0);
+ break;
+ case 11:
+ localWrite16(readInt16(), _regs.reg5);
+ break;
+ case 12:
+ localWrite16(readInt16(), _regs.reg4);
+ break;
+ case 13:
+ localWrite16(readInt16(), _regs.reg3);
+ break;
+ case 14:
+ _regs.reg3 = localRead16(readInt16());
+ break;
+ case 15:
+ _regs.reg2 = localRead16(_regs.reg1);
+ break;
+ case 16:
+ _regs.reg2 = localRead16(_regs.reg1 + readInt16());
+ break;
+ case 17:
+ _regs.reg2 = _regs.reg0;
+ break;
+ case 18:
+ _regs.reg0 += readInt16();
+ break;
+ case 19:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) + _regs.reg0);
+ break;
+ case 20:
+ _regs.reg0 += _regs.reg2;
+ break;
+ case 21:
+ _regs.reg3 += _regs.sp;
+ break;
+ case 22:
+ _regs.reg1 += _regs.sp;
+ break;
+ case 23:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) - _regs.reg0);
+ break;
+ case 24:
+ _regs.reg0 /= readInt16();
+ break;
+ case 25:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) / _regs.reg0);
+ break;
+ case 26:
+ // NOP
+ break;
+ case 27:
+ _regs.reg0 *= readInt16();
+ break;
+ case 28:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) * _regs.reg0);
+ break;
+ case 29:
+ _regs.reg0 *= _regs.reg2;
+ break;
+ case 30:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) + 1);
+ break;
+ case 31:
+ localWrite16(_regs.reg3, localRead16(_regs.reg3) - 1);
+ break;
+ case 32:
+ _switchStack2 = true;
+ break;
+ case 33:
+ _switchStack3 = true;
+ break;
+ case 34:
+ push16(_regs.reg0);
+ debug(1, "pushw reg0");
+ break;
+ case 35:
+ push16(_regs.reg1);
+ debug(1, "pushw reg1");
+ break;
+ case 36:
+ _regs.reg1 = pop16();
+ debug(1, "popw reg1");
+ break;
+ case 37:
+ _regs.reg0 = pop16();
+ debug(1, "popw reg0");
+ break;
+ case 38:
+ _regs.reg2 = -_regs.reg2;
+ break;
+ case 39:
+ _regs.reg8 = readInt16();
+ _scriptFlag01 = false;
+ break;
+ case 40:
+ _regs.reg8 = _regs.reg0;
+ _scriptFlag01 = false;
+ break;
+ case 41:
+ _regs.reg8 = readInt16();
+ _scriptFlag01 = true;
+ break;
+ case 42:
+ _regs.reg8 = _regs.reg0;
+ _scriptFlag01 = true;
+ break;
+ case 43:
+ debug(1, "retn (slot: %d; ofs: %04X)\n", _regs.reg4, _regs.reg0);
+ _code = getSlotData(_regs.reg4) + _regs.reg0;
+ break;
+ case 44:
+ debug(1, "retf (slot: %d; ofs: %04X)\n", _regs.reg5, _regs.reg0);
+ _code = getSlotData(_regs.reg5) + _regs.reg0;
+ _regs.reg4 = _regs.reg5;
+ _switchStack1 = true;
+ break;
+ case 45:
+ debug(1, "callnear %04X (slot: %d; ofs: %04X)\n", _regs.reg0, _regs.reg4, _regs.reg0);
+ push16(_code - getSlotData(_regs.reg4));
+ push16(_regs.reg4);
+ _code = getSlotData(_regs.reg4) + _regs.reg0;
+ break;
+ case 46:
+ debug(1, "callfar %04X (slot: %d; ofs: %04X)\n", _regs.reg0, _regs.reg5, _regs.reg0);
+ push16(_code - getSlotData(_regs.reg4));
+ push16(_regs.reg4);
+ _code = getSlotData(_regs.reg5) + _regs.reg0;
+ _regs.reg4 = _regs.reg5;
+ _switchStack1 = true;
+ break;
+ case 47:
+ _regs.reg4 = pop16();
+ ofs = pop16();
+ _code = getSlotData(_regs.reg4) + ofs;
+ debug(1, "ret (slot: %d; ofs: %04X)\n", _regs.reg4, ofs);
+ //_code = getSlotData(_regs.reg4) + pop16();
+ _switchStack1 = true;
+ break;
+ case 48:
+ _regs.reg4 = pop16();
+ ofs = pop16();
+ _code = getSlotData(_regs.reg4) + ofs;
+ debug(1, "retsp (slot: %d; ofs: %04X)\n", _regs.reg4, ofs);
+ //_code = getSlotData(_regs.reg4) + pop16();
+ _regs.sp += _regs.reg0;
+ _switchStack1 = true;
+ break;
+ case 49:
+ ofs = readByte();
+ debug(0, "49, len = %d", ofs);
+ _code += ofs;
+ break;
+ case 50:
+ if (_scriptFlag01) {
+ _regs.reg1 &= _regs.reg8;
+ if (_regs.reg1 == 0)
+ _code += 4;
+ } else {
+ if (_regs.reg1 == _regs.reg8)
+ _code += 4;
+ }
+ _code++;
+ break;
+ case 51:
+ if (_scriptFlag01) {
+ _regs.reg1 &= _regs.reg8;
+ if (_regs.reg1 != 0)
+ _code += 4;
+ } else {
+ if (_regs.reg1 != _regs.reg8)
+ _code += 4;
+ }
+ _code++;
+ break;
+ case 52:
+ if (_regs.reg1 >= _regs.reg8)
+ _code += 4;
+ _code++;
+ break;
+ case 53:
+ if (_regs.reg1 <= _regs.reg8)
+ _code += 4;
+ _code++;
+ break;
+ case 54:
+ if (_regs.reg1 < _regs.reg8)
+ _code += 4;
+ _code++;
+ break;
+ case 55:
+ if (_regs.reg1 > _regs.reg8)
+ _code += 4;
+ _code++;
+ break;
+ default:
+ {
+ /*
+ FILE *ex = fopen("error.0", "wb");
+ fwrite(_code - 8, 4096, 1, ex);
+ fclose(ex);
+ */
+ error("Invalid opcode %d", opcode);
+ }
+ }
+
+}
+
+void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
+
+ switch (kernelOpcode) {
+
+ case 0:
+ case 1:
+ // ok, NOPs
+ break;
+
+ case 2:// ok
+ {
+ debug(0, "o2_getGameVar(%d, %d)", arg16(3), arg16(5));
+ int16 value = getGameVar(arg16(3));
+ localWrite16(arg16(5), value);
+ break;
+ }
+
+ case 3:// ok
+ {
+ debug(0, "o2_setGameVar(%d, %d)", arg16(3), arg16(5));
+ VarType varType = getGameVarType(arg16(3));
+ int16 value;
+ if (varType == vtByte)
+ value = arg8(5);
+ else if (varType == vtWord)
+ value = arg16(5);
+ setGameVar(arg16(3), value);
+ break;
+ }
+
+ case 4:
+ {
+
+ debug(0, "o2_updateScreen()");
+
+ // TODO? updateSamples();
+
+ _vm->_screen->updateShakeScreen();
+
+ if (_vm->_quitGame)
+ return;
+
+ if (!_vm->_movieSceneFlag)
+ _vm->_input->update();
+ else
+ _vm->_input->_mouseButton = 0;
+
+ // TODO? Check keyb
+
+ _vm->_counter01--;
+ if (_vm->_counter01 <= 0) {
+ _vm->_counter01 = MIN(_vm->_counter02, 30);
+ _vm->_counter02 = 0;
+ _vm->updateScreen();
+ _vm->_flag01 = 1;
+ _vm->_system->delayMillis(5);
+ _vm->_counter02 = 1; // ?
+ } else {
+ _vm->_screen->clearSprites();
+ _vm->_flag01 = 0;
+ //_vm->_system->updateScreen();
+ }
+
+ // TODO
+ break;
+
+ }
+
+ case 5:// ok
+ {
+ debug(0, "o2_mouseDeltaStuff(%d)", arg16(3));
+ localWrite16(arg16(5), _vm->_input->getMouseDeltaStuff(arg16(3)));
+ break;
+ }
+
+ case 6:// ok
+ {
+ debug(0, "o2_printText()");
+ _vm->_screen->printText((byte*)localPtr(arg16(3)));
+ break;
+ }
+
+ case 7:// ok
+ {
+ debug(0, "o2_updateVerbLine(slot: %d; offset: %04X)", arg16(5), arg16(3));
+ _vm->_screen->updateVerbLine(arg16(5), arg16(3));
+ break;
+ }
+
+ case 8:// ok
+ {
+ debug(0, "o2_setFontColor(%d)", arg8(3));
+ _vm->_screen->_fontColor1 = 0;
+ _vm->_screen->_fontColor2 = arg8(3);
+ break;
+ }
+
+ case 9:// ok
+ {
+ debug(0, "o2_getTalkTextDuration()");
+ int16 duration = _vm->_screen->getTalkTextDuration();
+ localWrite16(arg16(3), duration);
+ break;
+ }
+
+ case 10:// ok
+ {
+ debug(0, "o2_talk(slot: %d; offset: %d)", arg16(5), arg16(3));
+ _vm->talk(arg16(5), arg16(3));
+ break;
+ }
+
+ case 11:// ok
+ {
+ debug(0, "o2_findFragment(%d, %d)", arg16(3), arg16(5));
+ localWrite16(arg16(5), _vm->_palette->findFragment(arg16(3)));
+ break;
+ }
+
+ case 12:// ok
+ {
+ debug(0, "o2_clearPaletteFragments()");
+ _vm->_palette->clearFragments();
+ break;
+ }
+
+ case 13:// ok
+ {
+ debug(0, "o2_addFragment(%d, %d)", arg16(3), arg16(5));
+ _vm->_palette->addFragment(arg16(3), arg16(5));
+ break;
+ }
+
+ case 14:// ok
+ {
+ debug(0, "o2_setDeltaPalette(animPalette, %d, %d, %d, %d)", arg8(6), arg8(5), arg8(4), arg8(3));
+ _vm->_palette->setDeltaPalette(_vm->_anim->_palette, arg8(6), (char)arg8(5), arg8(4), arg8(3));
+ break;
+ }
+
+ case 16:// TODO
+ {
+ debug(0, "o2_makeTransColorTable");
+ break;
+ }
+
+ case 17:// ok
+ {
+ debug(0, "o2_setDeltaPalette(mainPalette, %d, %d, %d, %d)", arg8(6), arg8(5), arg8(4), arg8(3));
+ _vm->_palette->setDeltaPalette(_vm->_palette->getMainPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
+ break;
+ }
+
+ case 18:// ok
+ {
+ debug(0, "o2_loadScript(resIndex: %d; slotIndex: %d)", arg16(4), arg8(3));
+ int16 codeOfs = _code - getSlotData(_regs.reg4);
+ loadScript(arg16(4), arg8(3));
+ _code = getSlotData(_regs.reg4) + codeOfs;
+ _switchStack1 = true;
+ break;
+ }
+
+ case 19:// ok
+ {
+ debug(0, "o2_registerFont(%d, %d)", arg8(3), arg16(4));
+ _vm->_screen->registerFont(arg8(3), arg16(4));
+ break;
+ }
+
+ case 20:// ok
+ {
+ debug(0, "o2_loadAddPalette(startIndex: %d; resIndex: %d)", arg8(3), arg16(4));
+ _vm->_palette->loadAddPalette(arg16(4), arg8(3));
+ break;
+ }
+
+ case 21:// TODO
+ {
+ debug(0, "o2_loadScene(resIndex: %d; flag: %d)", arg16(4), arg8(3));
+ if (arg8(3) == 0) {
+ _vm->loadScene(arg16(4));
+ } else {
+ _vm->_screen->loadMouseCursor(arg16(4));
+ }
+ break;
+ }
+
+ case 22:// ok
+ {
+ debug(0, "o2_setCameraTop(%d)", arg8(3));
+ _vm->setCameraTop(arg8(3));
+ break;
+ }
+
+ case 23:// ok
+ {
+ debug(0, "o2_findMouseInRectIndex1(offset: %d; slot: %d; elemSize: %d; var: %d; index: %d)", arg16(3), arg16(5), arg16(7), arg16(9), arg16(11));
+ int16 index = -1;
+ if (_vm->_input->_mouseY < _vm->_cameraHeight) {
+ index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
+ _vm->_input->_mouseX + _vm->_cameraX,
+ _vm->_input->_mouseY + _vm->_cameraY,
+ arg16(11) + 1, arg16(7));
+ }
+ localWrite16(arg16(9), index);
+ break;
+ }
+
+ case 24:// ok
+ {
+ debug(0, "o2_findMouseInRectIndex2(offset: %d, slot: %d, elemSize: %d, var: %d)", arg16(3), arg16(5), arg16(7), arg16(9));
+ int16 index = -1;
+
+ debug(0, "_vm->_input->_mouseDisabled = %d", _vm->_input->_mouseDisabled);
+
+ /* FIXME: This opcode is called after the Revistronic logo at the beginning,
+ but at the slot/offset there's bytecode and not a rect array as expected.
+ To avoid crashes we skip searching the rectangle index for now when scene 215 is active.
+ I don't know yet whether this is a bug in the original engine as well or just here.
+ Needs some more checking.
+ */
+ if (_vm->_sceneResIndex != 215) {
+ if (_vm->_input->_mouseY < _vm->_cameraHeight) {
+ index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
+ _vm->_input->_mouseX + _vm->_cameraX,
+ _vm->_input->_mouseY + _vm->_cameraY,
+ 0, arg16(7));
+ }
+ }
+
+ localWrite16(arg16(9), index);
+
+ break;
+ }
+
+ case 25:// ok
+ {
+ debug(0, "o2_drawGuiImage(x: %d; y: %d; resIndex: %d)", arg16(5), arg16(3), arg16(7));
+ _vm->_screen->drawGuiImage(arg16(5), arg16(3), arg16(7));
+ break;
+ }
+
+ case 26:// ok
+ {
+ debug(0, "o2_addAnimatedSpriteNoLoop(2; x: %d; y: %d; fragmentId: %d; offset: %d)", arg16(5), arg16(3), arg16(7), arg16(9));
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), false, 2);
+ break;
+ }
+
+ case 27:// ok
+ {
+ debug(0, "o2_addAnimatedSprite(2; x: %d; y: %d; fragmentId: %d; offset: %d)", arg16(5), arg16(3), arg16(7), arg16(9));
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), true, 2);
+ break;
+ }
+
+ case 28:// ok
+ {
+ debug(1, "o2_addStaticSprite()");
+ _vm->_screen->addStaticSprite(_subCode + 3);
+ break;
+ }
+
+ case 29:// ok
+ {
+ debug(0, "o2_addAnimatedSprite(1; x: %d; y: %d; value: %d; offset: %d)", arg16(5), arg16(3), arg16(7), arg16(9));
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), true, 1);
+ break;
+ }
+
+ case 30:// ok
+ {
+ debug(0, "o2_findPath(sourceX: %d; sourceY: %d; destX: %d; destY: %d; slotIndex: %d; offset: %d)", arg16(5), arg16(3), arg16(9), arg16(7), arg16(13), arg16(11));
+ _vm->_segmap->findPath((int16*)(getSlotData(arg16(13)) + arg16(11)), arg16(9), arg16(7), arg16(5), arg16(3));
+ break;
+ }
+
+ case 31:// ok
+ {
+ debug(0, "o2_walk()");
+ _vm->walk(getSlotData(arg16(5)) + arg16(3));
+ break;
+ }
+
+ case 32:// ok
+ {
+ debug(0, "o2_scrollCameraUp()");
+ _vm->scrollCameraUp(4);
+ break;
+ }
+
+ case 33:// ok
+ {
+ debug(0, "o2_scrollCameraDown()");
+ _vm->scrollCameraDown(4);
+ break;
+ }
+
+ case 34:// ok
+ {
+ debug(0, "o2_scrollCameraLeft()");
+ _vm->scrollCameraLeft(4);
+ break;
+ }
+
+ case 35:// ok
+ {
+ debug(0, "o2_scrollCameraRight()");
+ _vm->scrollCameraRight(4);
+ break;
+ }
+
+ case 36:// ok
+ {
+ debug(0, "o2_scrollCameraUpEx(%d)", arg16(3));
+ _vm->scrollCameraUp(arg16(3));
+ break;
+ }
+
+ case 37:// ok
+ {
+ debug(0, "o2_scrollCameraDownEx(%d)", arg16(3));
+ _vm->scrollCameraDown(arg16(3));
+ break;
+ }
+
+ case 38:// ok
+ {
+ debug(0, "o2_scrollCameraLeftEx(%d)", arg16(3));
+ _vm->scrollCameraLeft(arg16(3));
+ break;
+ }
+
+ case 39:// ok
+ {
+ debug(0, "o2_scrollCameraRightEx(%d)", arg16(3));
+ _vm->scrollCameraRight(arg16(3));
+ break;
+ }
+
+ case 40:// ok
+ {
+ debug(0, "o2_setCamera(%d, %d)", arg16(5), arg16(3));
+ _vm->setCamera(arg16(5), arg16(3));
+ break;
+ }
+
+ case 42:// ok
+ {
+ debug(0, "o2_getRgbModifiertAtPoint(x: %d; y: %d; id: %d; varSlot: %d; varOffset: %d)", arg16(5), arg16(3), arg16(7), arg16(11), arg16(9));
+ byte *rgb = getSlotData(arg16(11)) + arg16(9);
+ _vm->_segmap->getRgbModifiertAtPoint(arg16(5), arg16(3), arg16(7), rgb[0], rgb[1], rgb[2]);
+ break;
+ }
+
+ case 43:// ok
+ {
+ debug(0, "o2_startAnim(%d)", arg16(3));
+ _vm->_anim->start(arg16(3));
+ break;
+ }
+
+ case 44:// ok
+ {
+ debug(0, "o2_animNextFrame()");
+ _vm->_anim->nextFrame();
+ break;
+ }
+
+ case 45:// ok
+ {
+ // NOP
+ break;
+ }
+
+ case 46:// ok
+ {
+ debug(0, "o2_getAnimFrameNumber(%d)", arg16(3));
+ localWrite16(arg16(3), _vm->_anim->getFrameNumber());
+ break;
+ }
+
+ case 47:
+ {
+ // almost ok
+ debug(0, "o2_getAnimStatus()");
+ int16 status = _vm->_anim->getStatus();
+ if (status == 0 || status == 1) {
+ // TODO mov screenFlag01, 0
+ }
+ localWrite16(arg16(3), status);
+ break;
+ }
+
+ case 48:// ok
+ {
+ _vm->_screen->startShakeScreen(arg16(3));
+ break;
+ }
+
+ case 49:// ok
+ {
+ _vm->_screen->stopShakeScreen();
+ break;
+ }
+
+ case 50:// TODO
+ {
+ debug(0, "o2_startSequence");
+ break;
+ }
+
+ case 51:// TODO
+ {
+ debug(0, "o2_endSequence");
+ break;
+ }
+
+ case 52:// TODO
+ {
+ debug(0, "o2_sequenceVolumeStuff");
+ break;
+ }
+
+ case 53:// TODO
+ {
+ debug(0, "o2_playSound1(%d, %d, %d, %d)", arg16(9), arg16(7), arg16(5), arg16(3));
+ break;
+ }
+
+ case 54:// TODO
+ {
+ debug(0, "o2_playSound2(%d, %d, %d)", arg16(7), arg16(5), arg16(3));
+ break;
+ }
+
+ case 55:// TODO
+ debug(0, "o2_clearScreen()");
+ break;
+
+ case 56:// ok
+ {
+ // NOP
+ break;
+ }
+
+ case 57:// TODO
+ {
+ debug(0, "o2_handleInput");
+ int16 varOfs = arg16(3);
+
+ localWrite16(varOfs, 0);
+
+ //_vm->_input->update();
+ break;
+ }
+
+ case 58:// TODO
+ {
+ debug(0, "o2_runOptionsScreen(%d, %d)", arg16(5), arg16(3));
+ break;
+ }
+
+ case 59:// TODO
+ {
+ debug(0, "o2_precacheResources(%04X)", arg16(3));
+ break;
+ }
+
+ case 60:// TODO
+ {
+ debug(0, "o2_precacheSounds1(%04X)", arg16(3));
+ // CHECKME
+ _vm->_screen->clearSprites();
+ break;
+ }
+
+ case 61:// TODO
+ {
+ debug(0, "o2_deleteAllPbfFilesByExternalArray()");
+ break;
+ }
+
+ case 63:// ok
+ {
+ _regs.sp = _savedSp;
+ break;
+ }
+
+ case 64:// ok
+ {
+ _savedSp = _regs.sp;
+ break;
+ }
+
+ case 65:// TODO
+ {
+ debug(0, "o2_playMovie(%d, %d)", arg16(3), arg16(5));
+ break;
+ }
+
+ case 66:
+ // NOP
+ break;
+
+ default:
+ error("Invalid kernel opcode %d", kernelOpcode);
+ }
+
+}
+
+ScriptInterpreter::VarType ScriptInterpreter::getGameVarType(uint variable) {
+ switch (variable) {
+ case 0: return vtByte;
+ case 1: return vtWord;
+ case 2: return vtWord;
+ case 3: return vtByte;
+ case 4: return vtWord;
+ case 5: return vtWord;
+ case 6: return vtWord;
+ case 7: return vtWord;
+ case 8: return vtWord;
+ case 9: return vtWord;
+ case 10: return vtWord;
+ case 11: return vtWord;
+ case 12: return vtByte;
+ case 13: return vtWord;
+ case 14: return vtWord;
+ case 15: return vtWord;
+ case 16: return vtWord;
+ case 17: return vtWord;
+ case 18: return vtWord;
+ case 19: return vtWord;
+ case 20: return vtWord;
+ case 21: return vtWord;
+ default:
+ error("Invalid game variable");
+ }
+}
+
+const char *getVarName(uint variable) {
+ switch (variable) {
+ case 0: return "mouseDisabled";
+ case 1: return "mouseY";
+ case 2: return "mouseX";
+ case 3: return "mouseButton";
+ case 4: return "verbLineY";
+ case 5: return "verbLineX";
+ case 6: return "verbLineWidth";
+ case 7: return "verbLineCount";
+ case 8: return "verbLineNum";
+ case 9: return "talkTextItemNum";
+ case 10: return "talkTextY";
+ case 11: return "talkTextX";
+ case 12: return "talkTextFontColor";
+ case 13: return "cameraY";
+ case 14: return "cameraX";
+ case 15: return "walkSpeedY";
+ case 16: return "walkSpeedX";
+ case 17: return "flag01";
+ case 18: return "sceneResIndex";
+ case 19: return "cameraTop";
+ case 20: return "sceneHeight";
+ case 21: return "sceneWidth";
+ }
+ return "(invalid)";
+}
+
+int16 ScriptInterpreter::getGameVar(uint variable) {
+ debug(0, "ScriptInterpreter::getGameVar(%d{%s})", variable, getVarName(variable));
+
+ int16 value = 0;
+
+ switch (variable) {
+ case 0:
+ value = _vm->_input->_mouseDisabled;
+ break;
+ case 1:
+ value = _vm->_input->_mouseY;
+ break;
+ case 2:
+ value = _vm->_input->_mouseX;
+ break;
+ case 3:
+ value = _vm->_input->_mouseButton;
+ break;
+ case 4:
+ value = _vm->_screen->_verbLineY;
+ break;
+ case 5:
+ value = _vm->_screen->_verbLineX;
+ break;
+ case 6:
+ value = _vm->_screen->_verbLineWidth;
+ break;
+ case 7:
+ value = _vm->_screen->_verbLineCount;
+ break;
+ case 8:
+ value = _vm->_screen->_verbLineNum;
+ break;
+ case 9:
+ value = _vm->_screen->_talkTextItemNum;
+ break;
+ case 10:
+ value = _vm->_screen->_talkTextY;
+ break;
+ case 11:
+ value = _vm->_screen->_talkTextX;
+ break;
+ case 12:
+ value = _vm->_screen->_talkTextFontColor;
+ break;
+ case 13:
+ value = _vm->_cameraY;
+ break;
+ case 14:
+ value = _vm->_cameraX;
+ break;
+ case 15:
+ value = _vm->_walkSpeedY;
+ break;
+ case 16:
+ value = _vm->_walkSpeedX;
+ break;
+ case 17:
+ value = _vm->_flag01;
+ break;
+ case 18:
+ value = _vm->_sceneResIndex;
+ break;
+ case 19:
+ value = _vm->_cameraTop;
+ break;
+ case 20:
+ value = _vm->_sceneHeight;
+ break;
+ case 21:
+ value = _vm->_sceneWidth;
+ break;
+ default:
+ warning("Getting unimplemented game variable %s (%d)", getVarName(variable), variable);
+ break;
+ }
+
+
+ return value;
+
+}
+
+void ScriptInterpreter::setGameVar(uint variable, int16 value) {
+ debug(0, "ScriptInterpreter::setGameVar(%d{%s}, %d)", variable, getVarName(variable), value);
+
+ switch (variable) {
+ case 0:
+ _vm->_input->_mouseDisabled = value;
+ break;
+ case 3:
+ _vm->_input->_mouseButton = value;
+ break;
+ case 4:
+ _vm->_screen->_verbLineY = value;
+ break;
+ case 5:
+ _vm->_screen->_verbLineX = value;
+ break;
+ case 6:
+ _vm->_screen->_verbLineWidth = value;
+ break;
+ case 7:
+ _vm->_screen->_verbLineCount = value;
+ break;
+ case 8:
+ _vm->_screen->_verbLineNum = value;
+ break;
+ case 9:
+ _vm->_screen->_talkTextItemNum = value;
+ break;
+ case 10:
+ _vm->_screen->_talkTextY = value;
+ break;
+ case 11:
+ _vm->_screen->_talkTextX = value;
+ break;
+ case 12:
+ _vm->_screen->_talkTextFontColor = value;
+ break;
+ case 13:
+ _vm->_cameraY = value;
+ break;
+ case 14:
+ _vm->_cameraX = value;
+ break;
+ case 15:
+ _vm->_walkSpeedY = value;
+ break;
+ case 16:
+ _vm->_walkSpeedX = value;
+ break;
+ case 17:
+ _vm->_flag01 = value != 0;
+ break;
+ case 18:
+ _vm->_sceneResIndex = value;
+ break;
+ case 19:
+ _vm->_cameraTop = value;
+ break;
+ case 20:
+ _vm->_sceneHeight = value;
+ break;
+ case 21:
+ _vm->_sceneWidth = value;
+ break;
+ case 1:
+ case 2:
+ default:
+ warning("Setting unimplemented game variable %s (%d) to %d", getVarName(variable), variable, value);
+ break;
+ }
+
+
+}
+
+byte ScriptInterpreter::arg8(int16 offset) {
+ return _subCode[offset];
+}
+
+int16 ScriptInterpreter::arg16(int16 offset) {
+ return READ_LE_UINT16(&_subCode[offset]);
+}
+
+int32 ScriptInterpreter::arg32(int16 offset) {
+ return READ_LE_UINT32(&_subCode[offset]);
+}
+
+void ScriptInterpreter::push8(byte value) {
+ _stack[_regs.sp] = value;
+ _regs.sp--;
+}
+
+byte ScriptInterpreter::pop8() {
+ _regs.sp++;
+ return _stack[_regs.sp];
+}
+
+void ScriptInterpreter::push16(int16 value) {
+ WRITE_LE_UINT16(_stack + _regs.sp, value);
+ _regs.sp -= 2;
+}
+
+int16 ScriptInterpreter::pop16() {
+ _regs.sp += 2;
+ return READ_LE_UINT16(_stack + _regs.sp);
+}
+
+void ScriptInterpreter::push32(int32 value) {
+ WRITE_LE_UINT32(_stack + _regs.sp, value);
+ _regs.sp -= 4;
+}
+
+int32 ScriptInterpreter::pop32() {
+ _regs.sp += 4;
+ return READ_LE_UINT32(_stack + _regs.sp);
+}
+
+void ScriptInterpreter::localWrite8(int16 offset, byte value) {
+ debug(1, "localWrite8(%d, %d)", offset, value);
+ _localData[offset] = value;
+}
+
+byte ScriptInterpreter::localRead8(int16 offset) {
+ debug(1, "localRead8(%d) -> %d", offset, _localData[offset]);
+ return _localData[offset];
+}
+
+void ScriptInterpreter::localWrite16(int16 offset, int16 value) {
+ debug(1, "localWrite16(%d, %d)", offset, value);
+ WRITE_LE_UINT16(&_localData[offset], value);
+}
+
+int16 ScriptInterpreter::localRead16(int16 offset) {
+ debug(1, "localRead16(%d) -> %d", offset, (int16)READ_LE_UINT16(&_localData[offset]));
+ return (int16)READ_LE_UINT16(&_localData[offset]);
+}
+
+void ScriptInterpreter::localWrite32(int16 offset, int32 value) {
+ debug(1, "localWrite32(%d, %d)", offset, value);
+ WRITE_LE_UINT32(&_localData[offset], value);
+}
+
+int32 ScriptInterpreter::localRead32(int16 offset) {
+ debug(1, "localRead32(%d) -> %d", offset, (int32)READ_LE_UINT32(&_localData[offset]));
+ return (int32)READ_LE_UINT32(&_localData[offset]);
+}
+
+byte *ScriptInterpreter::localPtr(int16 offset) {
+ debug(1, "localPtr(%d)", offset);
+ return &_localData[offset];
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
new file mode 100644
index 0000000..6f2d5b7
--- /dev/null
+++ b/engines/toltecs/script.h
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_SCRIPT_H
+#define TOLTECS_SCRIPT_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+const int kMaxScriptSlots = 50;
+
+class ScriptInterpreter {
+public:
+ ScriptInterpreter(ToltecsEngine *vm);
+ ~ScriptInterpreter();
+
+ void loadScript(uint resIndex, uint slotIndex);
+ void runScript(uint slotIndex);
+
+ byte *getSlotData(int slotIndex) const { return _slots[slotIndex].data; }
+
+protected:
+
+ enum VarType {
+ vtByte,
+ vtWord
+ };
+
+ struct ScriptRegs {
+ int16 reg0;
+ int16 reg1;
+ int16 reg2;
+ int16 reg3;
+ int16 reg4;
+ int16 reg5;
+ int16 reg6;
+ int16 sp;
+ int16 reg8;
+ };
+
+ struct ScriptSlot {
+ byte *data;
+ int32 size;
+ uint resIndex;
+ };
+
+ ToltecsEngine *_vm;
+
+ byte *_stack;
+
+ byte *_code, *_subCode;
+ byte *_localData;
+ bool _switchStack1, _switchStack2, _switchStack3;
+ bool _scriptFlag01;
+
+ ScriptSlot _slots[kMaxScriptSlots];
+
+ ScriptRegs _regs;
+ int16 _savedSp;
+
+ byte readByte();
+ int16 readInt16();
+
+ void execOpcode(byte opcode);
+ void execKernelOpcode(uint16 kernelOpcode);
+
+ VarType getGameVarType(uint variable);
+ int16 getGameVar(uint variable);
+ void setGameVar(uint variable, int16 value);
+
+ byte arg8(int16 offset);
+ int16 arg16(int16 offset);
+ int32 arg32(int16 offset);
+
+ void push8(byte value);
+ byte pop8();
+ void push16(int16 value);
+ int16 pop16();
+ void push32(int32 value);
+ int32 pop32();
+
+ void localWrite8(int16 offset, byte value);
+ byte localRead8(int16 offset);
+ void localWrite16(int16 offset, int16 value);
+ int16 localRead16(int16 offset);
+ void localWrite32(int16 offset, int32 value);
+ int32 localRead32(int16 offset);
+ byte *localPtr(int16 offset);
+
+};
+
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_H */
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
new file mode 100644
index 0000000..6c4796f
--- /dev/null
+++ b/engines/toltecs/segmap.cpp
@@ -0,0 +1,535 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+#include "common/stream.h"
+
+#include "graphics/primitives.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+#include "toltecs/segmap.h"
+
+namespace Toltecs {
+
+SegmentMap::SegmentMap(ToltecsEngine *vm) : _vm(vm) {
+ _maskRectData = new byte[32768];
+}
+
+SegmentMap::~SegmentMap() {
+ delete[] _maskRectData;
+}
+
+void SegmentMap::load(byte *source) {
+
+ // TODO: Use MemoryReadStream
+
+ _maskRects.clear();
+ _pathRects.clear();
+ _infoRects.clear();
+
+ // Load mask rects
+ uint16 maskSize = READ_LE_UINT16(source);
+ source += 2;
+ uint16 maskRectCount = READ_LE_UINT16(source);
+ source += 2;
+ uint16 maskRectDataSize = maskRectCount * 12 + 2;
+
+ debug(0, "SegmentMap::load() maskRectCount = %d", maskRectCount);
+
+ for (uint16 i = 0; i < maskRectCount; i++) {
+ SegmapMaskRect maskRect;
+ maskRect.y = READ_LE_UINT16(source);
+ maskRect.x = READ_LE_UINT16(source + 2);
+ maskRect.height = READ_LE_UINT16(source + 4);
+ maskRect.width = READ_LE_UINT16(source + 6);
+ maskRect.maskOffset = READ_LE_UINT16(source + 8);
+ maskRect.maskOffset -= maskRectDataSize;
+ maskRect.ybottom = READ_LE_UINT16(source + 10);
+
+ debug(0, "SegmentMap::load() (%d, %d, %d, %d, %04X, %d)",
+ maskRect.x, maskRect.y, maskRect.width, maskRect.height, maskRect.maskOffset, maskRect.ybottom);
+
+ source += 12;
+ _maskRects.push_back(maskRect);
+ }
+
+ memcpy(_maskRectData, source, maskSize - maskRectDataSize);
+ source += maskSize - maskRectDataSize;
+
+ // Load path rects
+
+ source += 2; // skip rects array size
+
+ uint16 pathRectCount = READ_LE_UINT16(source);
+ source += 2;
+
+ debug(0, "SegmentMap::load() pathRectCount = %d", pathRectCount);
+
+ for (uint16 i = 0; i < pathRectCount; i++) {
+ SegmapPathRect pathRect;
+ pathRect.y = READ_LE_UINT16(source);
+ pathRect.x = READ_LE_UINT16(source + 2);
+ pathRect.height = READ_LE_UINT16(source + 4);
+ pathRect.width = READ_LE_UINT16(source + 6);
+
+ debug(0, "SegmentMap::load() (%d, %d, %d, %d)", pathRect.x, pathRect.y, pathRect.width, pathRect.height);
+
+ source += 8;
+ _pathRects.push_back(pathRect);
+ }
+
+ // Load info rects
+
+ source += 2; // skip rects array size
+
+ uint16 infoRectCount = READ_LE_UINT16(source);
+ source += 2;
+ debug(0, "SegmentMap::load() infoRectCount = %d", infoRectCount);
+ for (uint16 i = 0; i < infoRectCount; i++) {
+ SegmapInfoRect infoRect;
+ infoRect.y = READ_LE_UINT16(source);
+ infoRect.x = READ_LE_UINT16(source + 2);
+ infoRect.height = READ_LE_UINT16(source + 4);
+ infoRect.width = READ_LE_UINT16(source + 6);
+ infoRect.id = source[8];
+ infoRect.a = source[9];
+ infoRect.b = source[10];
+ infoRect.c = source[11];
+
+ debug(0, "SegmentMap::load() (%d, %d, %d, %d) (%d, %d, %d, %d)",
+ infoRect.x, infoRect.y, infoRect.width, infoRect.height,
+ infoRect.id, (int8)infoRect.a, (int8)infoRect.b, (int8)infoRect.c);
+
+ source += 12;
+ _infoRects.push_back(infoRect);
+ }
+
+ // TODO Other stuff
+
+
+}
+
+int SegmentMap::findPathRectAtPoint(int x, int y) {
+ for (uint rectIndex = 0; rectIndex < _pathRects.size(); rectIndex++) {
+ if (y >= _pathRects[rectIndex].y && y <= _pathRects[rectIndex].y + _pathRects[rectIndex].height &&
+ x >= _pathRects[rectIndex].x && x <= _pathRects[rectIndex].x + _pathRects[rectIndex].width) {
+ return rectIndex;
+ }
+ }
+ return -1;
+}
+
+void SegmentMap::adjustPathPoint(int x, int y) {
+
+ if (findPathRectAtPoint(x, y) != -1)
+ return;
+
+ uint32 minDistance = 0xFFFFFFFF, distance;
+ int x2, y2;
+
+ for (uint rectIndex = 0; rectIndex < _pathRects.size(); rectIndex++) {
+
+ if (ABS(x - _pathRects[rectIndex].x) >= ABS((x - (_pathRects[rectIndex].x + _pathRects[rectIndex].width)))) {
+ x2 = _pathRects[rectIndex].x + _pathRects[rectIndex].width;
+ } else {
+ x2 = _pathRects[rectIndex].x;
+ }
+
+ if (ABS(y - _pathRects[rectIndex].y) >= ABS((y - (_pathRects[rectIndex].y + _pathRects[rectIndex].height)))) {
+ y2 = _pathRects[rectIndex].y + _pathRects[rectIndex].height;
+ } else {
+ y2 = _pathRects[rectIndex].y;
+ }
+
+ if (x >= _pathRects[rectIndex].x && x < _pathRects[rectIndex].x + _pathRects[rectIndex].width) {
+ x2 = x;
+ }
+
+ distance = ABS(y - y2) + ABS(x - x2);
+ if (distance < minDistance) {
+ if (y >= _pathRects[rectIndex].y && y <= _pathRects[rectIndex].y + _pathRects[rectIndex].height)
+ _y = y;
+ else
+ _y = y2;
+ if (x >= _pathRects[rectIndex].x && x <= _pathRects[rectIndex].x + _pathRects[rectIndex].width)
+ _x = x;
+ else
+ _x = x2;
+ minDistance = distance;
+ }
+
+ }
+
+}
+
+int SegmentMap::findNextPathRect(int srcRectIndex) {
+
+ uint v28;
+ int result;
+ int minDistance, distance;
+ int x1, y1, x2, y2;
+ int nx1, nx2, nx3;
+ int ny, ny2, ny3;
+
+ result = -1;
+ minDistance = 65535;
+
+ x1 = _pathRects[srcRectIndex].x;
+ y1 = _pathRects[srcRectIndex].y;
+
+ x2 = x1 + _pathRects[srcRectIndex].width;
+ y2 = y1 + _pathRects[srcRectIndex].height;
+
+ for (uint rectIndex = 0; rectIndex < _pathRects.size(); ++rectIndex) {
+
+ if ( y1 == _pathRects[rectIndex].height + _pathRects[rectIndex].y && x1 < _pathRects[rectIndex].x + _pathRects[rectIndex].width && x2 > _pathRects[rectIndex].x ) {
+ ny = y1;
+
+LABEL_28:
+ if ( x1 >= _pathRects[rectIndex].x ) {
+ nx1 = x1;
+ } else {
+ nx1 = _pathRects[rectIndex].x;
+ }
+ if ( x2 <= _pathRects[rectIndex].x + _pathRects[rectIndex].width ) {
+ nx2 = x2 - 1;
+ } else {
+ nx2 = _pathRects[rectIndex].x + _pathRects[rectIndex].width - 1;
+ }
+ if ( ABS(_x - nx1) >= ABS(_x - nx2) ) {
+ nx3 = nx2 - 1;
+ } else {
+ nx3 = nx1;
+ }
+ if ( _x > nx1 && _x < nx2 ) {
+ nx3 = _x;
+ }
+ goto LABEL_55;
+ }
+ if ( y2 == _pathRects[rectIndex].y && x1 < _pathRects[rectIndex].x + _pathRects[rectIndex].width && x2 > _pathRects[rectIndex].x ) {
+ ny = y2 - 1;
+ goto LABEL_28;
+ }
+ if ( x1 == _pathRects[rectIndex].x + _pathRects[rectIndex].width && y1 < _pathRects[rectIndex].y + _pathRects[rectIndex].height && y2 > _pathRects[rectIndex].y ) {
+ nx3 = x1;
+ } else {
+ if ( x2 != _pathRects[rectIndex].x || y1 >= _pathRects[rectIndex].y + _pathRects[rectIndex].height || y2 <= _pathRects[rectIndex].y )
+ continue;
+ nx3 = x2 - 1;
+ }
+ if ( y1 >= _pathRects[rectIndex].y ) {
+ ny3 = y1;
+ } else {
+ ny3 = _pathRects[rectIndex].y;
+ }
+ if ( y2 <= _pathRects[rectIndex].y + _pathRects[rectIndex].height ) {
+ ny2 = y2 - 1;
+ } else {
+ ny2 = _pathRects[rectIndex].y + _pathRects[rectIndex].height - 1;
+ }
+ if ( ABS(_y - ny3) >= ABS(_y - ny2) ) {
+ ny = ny2 - 1;
+ } else {
+ ny = ny3;
+ }
+ if ( _y > ny3 && _y < ny2 ) {
+ ny = _y;
+ }
+
+LABEL_55:
+ distance = ABS(_x - nx3) + ABS(_y - ny);
+ v28 = 0;
+ while ( v28 < _rectIndexArray2Count ) {
+ if ( rectIndex == _rectIndexArray2[v28] ) {
+ distance = minDistance;
+ break;
+ }
+ ++v28;
+ }
+
+ v28 = 0;
+ while ( v28 < _rectIndexArray1Count ) {
+ if ( rectIndex == _rectIndexArray1[v28] ) {
+ distance = minDistance;
+ break;
+ }
+ ++v28;
+ }
+
+ if ( distance < minDistance ) {
+ result = rectIndex;
+ minDistance = distance;
+ _pointsArray[_pointsCount].y = ny;
+ _pointsArray[_pointsCount].x = nx3;
+ }
+
+ }
+
+ return result;
+}
+
+struct LineData {
+ int pitch;
+ byte *surf;
+};
+
+void plotProc(int x, int y, int color, void *data) {
+ LineData *ld = (LineData*)data;
+ ld->surf[x + y * ld->pitch] = color;
+}
+
+void SegmentMap::findPath(int16 *pointsArray, int destX, int destY, int x, int y) {
+
+ int index;
+ int sourceRectIndex, destRectIndex;
+ int pointsCount;
+
+ pointsCount = 2;
+ index = 0;
+
+ debug(0, "SegmentMap::findPath(fromX: %d; fromY: %d; toX: %d; toY: %d)", x, y, destX, destY);
+
+ sourceRectIndex = findPathRectAtPoint(x, y);
+ if ( sourceRectIndex == -1 ) {
+ adjustPathPoint(x, y);
+ x = _x;
+ y = _y;
+ }
+
+ _rectIndexArray1Count = 0;
+ _rectIndexArray2Count = 0;
+ _pointsCount = 0;
+
+ _x = destX;
+ _y = destY;
+
+ adjustPathPoint(_x, _y);
+ destRectIndex = findPathRectAtPoint(_x, _y);
+ sourceRectIndex = findPathRectAtPoint(x, y);
+ if ( sourceRectIndex != -1 ) {
+ if ( destRectIndex != sourceRectIndex ) {
+ while ( 1 ) {
+ do {
+ _rectIndexArray2[_rectIndexArray2Count++] = sourceRectIndex;
+ sourceRectIndex = findNextPathRect(sourceRectIndex);
+ _pointsCount++;
+ } while ( sourceRectIndex != -1 && sourceRectIndex != destRectIndex );
+ if ( sourceRectIndex != -1 && sourceRectIndex == destRectIndex )
+ break;
+ _rectIndexArray1[_rectIndexArray1Count++] = _rectIndexArray2[--_rectIndexArray2Count];
+ _pointsCount -= 2;
+ sourceRectIndex = _rectIndexArray2[--_rectIndexArray2Count];
+ }
+ sourceRectIndex = 0;
+ while ( sourceRectIndex < _pointsCount ) {
+ pointsArray[pointsCount++] = _pointsArray[sourceRectIndex].y;
+ pointsArray[pointsCount++] = _pointsArray[sourceRectIndex].x;
+ index++;
+ sourceRectIndex++;
+ }
+ }
+
+ pointsArray[pointsCount++] = _y;
+ pointsArray[pointsCount++] = _x;
+
+ pointsArray[0] = 0;
+ pointsArray[1] = index + 1;
+ }
+
+ debug(0, "SegmentMap::findPath() count = %d", pointsArray[1]);
+
+ /*
+ int sx = x, sy = y;
+ LineData ld;
+ ld.pitch = _vm->_sceneWidth;
+ ld.surf = _vm->_screen->_backScreen;
+ for (int16 i = 0; i < pointsArray[1] * 2; i+=2) {
+ debug(0, "x = %d; y = %d", pointsArray[3+i], pointsArray[2+i]);
+ Graphics::drawLine(sx, sy, pointsArray[3+i], pointsArray[2+i], 0xFF, plotProc, &ld);
+ sx = pointsArray[3+i];
+ sy = pointsArray[2+i];
+ }
+ */
+
+}
+
+int8 SegmentMap::getScalingAtPoint(int16 x, int16 y) {
+ int8 scaling = 0;
+ for (uint i = 0; i < _infoRects.size(); i++) {
+ if (_infoRects[i].id == 0 &&
+ y >= _infoRects[i].y && y <= _infoRects[i].y + _infoRects[i].height &&
+ x >= _infoRects[i].x && x <= _infoRects[i].x + _infoRects[i].width) {
+ char topScaling = (char)_infoRects[i].b;
+ char bottomScaling = (char)_infoRects[i].c;
+ if (y - _infoRects[i].y > 0) {
+ scaling = (ABS(y - _infoRects[i].y) * (bottomScaling - topScaling) / _infoRects[i].height) + topScaling;
+ }
+ }
+ }
+ return scaling;
+}
+
+void SegmentMap::getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byte &g, byte &b) {
+ r = 0;
+ g = 0;
+ b = 0;
+ for (uint i = 0; i < _infoRects.size(); i++) {
+ if (_infoRects[i].id == id &&
+ y >= _infoRects[i].y && y <= _infoRects[i].y + _infoRects[i].height &&
+ x >= _infoRects[i].x && x <= _infoRects[i].x + _infoRects[i].width) {
+
+ r = _infoRects[i].a;
+ g = _infoRects[i].b;
+ b = _infoRects[i].c;
+ }
+ }
+ debug(0, "SegmentMap::getRgbModifiertAtPoint() r: %d; g: %d; b: %d", r, g, b);
+}
+
+void SegmentMap::restoreMasksBySprite(SpriteDrawItem *sprite) {
+ // TODO: This needs more optimization
+ for (uint i = 0; i < _maskRects.size(); i++) {
+
+#if 0
+ if ( *(__int16 *)((char *)&spriteDrawList[0].y2 + v5) <= (unsigned __int16)v3->ybottom )
+ {
+ if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].height + v5)
+ + *(__int16 *)((char *)&spriteDrawList[0].y + v5)) > v3->y )
+ {
+ if ( (unsigned __int16)(v3->height + v3->y) > *(__int16 *)((char *)&spriteDrawList[0].y + v5) )
+ {
+ if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].width + v5)
+ + *(__int16 *)((char *)&spriteDrawList[0].x + v5)) > v3->x )
+ {
+ if ( (unsigned __int16)(v3->width + v3->x) > *(__int16 *)((char *)&spriteDrawList[0].x + v5) )
+ {
+
+#endif
+
+ if (sprite->ybottom <= _maskRects[i].ybottom) {
+ restoreMask(i);
+ }
+ }
+
+}
+
+void SegmentMap::restoreMask(int16 index) {
+ // TODO: This needs more optimization
+ SegmapMaskRect *maskRect = &_maskRects[index];
+
+ int16 maskX = maskRect->x, maskY = maskRect->y;
+ int16 skipX = 0;
+ int16 x = maskRect->x - _vm->_cameraX;
+ int16 y = maskRect->y - _vm->_cameraY;
+ int16 width = maskRect->width;
+ int16 height = maskRect->height;
+ byte *mask = _maskRectData + maskRect->maskOffset;
+
+ debug(0, "SegmentMap::restoreMask() screenX = %d; screenY = %d; maskX = %d; maskY = %d",
+ x, y, maskRect->x, maskRect->y);
+
+ // Not on screen, skip
+ if (x + width < 0 || y + height < 0 || x >= 640 || y >= _vm->_cameraHeight)
+ return;
+
+ if (x < 0) {
+ skipX = -x;
+ x = 0;
+ }
+
+ if (y < 0) {
+ int16 skipY = -y;
+ for (int16 h = 0; h < skipY; h++) {
+ int16 w = width;
+ while (w > 0) {
+ w -= (*mask++) & 0x7F;
+ }
+ }
+ y = 0;
+ height -= skipY;
+ maskY += skipY;
+ }
+
+ if (x + width >= 640) {
+ width -= x + width - 640;
+ }
+
+ if (y + height >= _vm->_cameraHeight) {
+ height -= y + height - _vm->_cameraHeight;
+ }
+
+ byte *backScreen = _vm->_screen->_backScreen + maskX + (maskY * _vm->_sceneWidth);
+ byte *frontScreen = _vm->_screen->_frontScreen + x + (y * 640);
+
+ for (int16 h = 0; h < height; h++) {
+ byte *src = backScreen;
+ byte *dst = frontScreen;
+ byte maskLine[640], *maskLineP = maskLine;
+
+ int16 w = width;
+ while (w > 0) {
+ byte m = *mask++;
+ byte count = m & 0x7F;
+ if (m & 0x80)
+ memset(maskLineP, 1, count);
+ else
+ memset(maskLineP, 0, count);
+ maskLineP += count;
+ w -= count;
+ }
+
+ src += skipX;
+ for (int16 c = skipX; c < width; c++) {
+ if (maskLine[c] == 1)
+ *dst = *src;
+ dst++;
+ src++;
+ }
+
+ backScreen += _vm->_sceneWidth;
+ frontScreen += 640;
+ }
+
+}
+
+void SegmentMap::debugDrawRects(Graphics::Surface *surf) {
+ for (uint16 i = 0; i < _pathRects.size(); i++) {
+ SegmapPathRect pathRect = _pathRects[i];
+ surf->frameRect(
+ Common::Rect(pathRect.x, pathRect.y, pathRect.x + pathRect.width, pathRect.y + pathRect.height),
+ 255);
+ }
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
new file mode 100644
index 0000000..0ebb3f4
--- /dev/null
+++ b/engines/toltecs/segmap.h
@@ -0,0 +1,134 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_SEGMAP_H
+#define TOLTECS_SEGMAP_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "graphics/surface.h"
+
+#include "engines/engine.h"
+
+#include "toltecs/screen.h"
+
+namespace Toltecs {
+
+struct ScriptWalk {
+ int16 y, x;
+ int16 y1, x1, y2, x2;
+ int16 yerror, xerror;
+ int16 mulValue;
+ int16 scaling;
+};
+
+class SegmentMap {
+public:
+ SegmentMap(ToltecsEngine *vm);
+ ~SegmentMap();
+
+ void load(byte *source);
+
+ int findPathRectAtPoint(int x, int y);
+ void adjustPathPoint(int x, int y);
+
+ void findPath(int16 *pointsArray, int destX, int destY, int x, int y);
+
+ int8 getScalingAtPoint(int16 x, int16 y);
+ void getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byte &g, byte &b);
+
+ void restoreMasksBySprite(SpriteDrawItem *sprite);
+ void restoreMask(int16 index);
+
+ void debugDrawRects(Graphics::Surface *surf);
+
+//protected:
+public: // for debugging purposes
+
+ struct SegmapMaskRect {
+ int16 y, x;
+ int16 height, width;
+ int16 maskOffset;
+ int16 ybottom;
+ };
+
+ struct SegmapPathRect {
+ int16 y, x;
+ int16 height, width;
+ };
+
+ struct SegmapInfoRect {
+ int16 y, x;
+ int16 height, width;
+ byte id;
+ byte a, b, c;
+ };
+
+ struct PathPoint {
+ int16 y, x;
+ };
+
+ typedef Common::Array<SegmapMaskRect> SegmapMaskRectArray;
+ typedef Common::Array<SegmapPathRect> SegmapPathRectArray;
+ typedef Common::Array<SegmapInfoRect> SegmapInfoRectArray;
+
+ ToltecsEngine *_vm;
+
+ SegmapMaskRectArray _maskRects;
+ byte *_maskRectData;
+
+ SegmapPathRectArray _pathRects;
+ SegmapInfoRectArray _infoRects;
+
+ int _rectIndexArray1[1000];
+ uint _rectIndexArray1Count;
+
+ int _rectIndexArray2[1000];
+ uint _rectIndexArray2Count;
+
+ PathPoint _pointsArray[1000];
+ int16 _pointsCount;
+
+ int _x, _y;
+
+ int findNextPathRect(int srcRectIndex);
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_SEGMAP_H */
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
new file mode 100644
index 0000000..78f3e23
--- /dev/null
+++ b/engines/toltecs/toltecs.cpp
@@ -0,0 +1,483 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+#include "common/str.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "graphics/surface.h"
+#include "graphics/cursorman.h"
+#include "graphics/primitives.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/animation.h"
+#include "toltecs/input.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+#include "toltecs/script.h"
+#include "toltecs/screen.h"
+#include "toltecs/segmap.h"
+
+namespace Toltecs {
+
+struct GameSettings {
+ const char *gameid;
+ const char *description;
+ byte id;
+ uint32 features;
+ const char *detectname;
+};
+
+ToltecsEngine::ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+
+ // Setup mixer
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+
+ _rnd = new Common::RandomSource();
+ syst->getEventManager()->registerRandomSource(*_rnd, "toltecs");
+
+ int cd_num = ConfMan.getInt("cdrom");
+ if (cd_num >= 0)
+ _system->openCD(cd_num);
+
+}
+
+ToltecsEngine::~ToltecsEngine() {
+ delete _rnd;
+}
+
+int ToltecsEngine::init() {
+ // Initialize backend
+ _system->beginGFXTransaction();
+ initCommonGFX(false);
+ _system->initSize(640, 400);
+ _system->endGFXTransaction();
+ return 0;
+}
+
+int ToltecsEngine::go() {
+
+ _system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true);
+
+ _quitGame = false;
+ _counter01 = 0;
+ _counter02 = 0;
+ _movieSceneFlag = false;
+ _flag01 = 0;
+
+ _cameraX = 0;
+ _cameraY = 0;
+ _newCameraX = 0;
+ _newCameraY = 0;
+ _cameraTop = 26;
+ _cameraHeight = 0;
+ _yetAnotherX = 0;
+
+ _sceneWidth = 0;
+ _sceneHeight = 0;
+
+ _doSpeech = true;
+ _doText = true;
+
+ _walkSpeedY = 5;
+ _walkSpeedX = 1;
+
+ _arc = new ArchiveReader();
+ _arc->openArchive("WESTERN");
+
+ _res = new ResourceCache(this);
+
+ _screen = new Screen(this);
+
+ _script = new ScriptInterpreter(this);
+ _anim = new AnimationPlayer(this);
+ _palette = new Palette(this);
+ _segmap = new SegmentMap(this);
+ _input = new Input(this);
+
+ _system->showMouse(true);
+
+#if 1
+
+ _script->loadScript(0, 0);
+ _script->runScript(0);
+
+#endif
+
+ delete _arc;
+ delete _res;
+ delete _screen;
+ delete _script;
+ delete _anim;
+ delete _palette;
+ delete _segmap;
+ delete _input;
+
+ return 0;
+}
+
+void ToltecsEngine::loadScene(uint resIndex) {
+ // TODO
+
+ byte *scene = _res->load(resIndex);
+
+ uint32 imageSize = READ_LE_UINT32(scene);
+ _sceneResIndex = resIndex;
+ _sceneHeight = READ_LE_UINT16(scene + 4);
+ _sceneWidth = READ_LE_UINT16(scene + 6);
+
+ // Load scene palette
+ _palette->loadAddPaletteFrom(scene + 8, 0, 128);
+
+ // Load scene background
+ byte *source = scene + 392;
+ byte *destp = _screen->_backScreen;
+ byte *destEnd = destp + _sceneWidth * _sceneHeight;
+ while (destp < destEnd) {
+ int count = 1;
+ byte pixel = *source++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ count = *source++;
+ count += 2;
+ }
+ memset(destp, pixel, count);
+ destp += count;
+ }
+
+ debug(0, "_sceneWidth = %d; _sceneHeight = %d", _sceneWidth, _sceneHeight);
+
+ // Load scene segmap
+ _segmap->load(scene + imageSize + 4);
+
+}
+
+void ToltecsEngine::updateScreen() {
+ // TODO
+
+ byte *destp = _screen->_frontScreen;
+ byte *srcp = _screen->_backScreen + _cameraX + _cameraY * _sceneWidth;
+ for (uint y = 0; y < MIN<uint>(_cameraHeight, 400); y++) {
+ memcpy(destp, srcp, MIN<uint>(_sceneWidth, 640));
+ destp += 640;
+ srcp += _sceneWidth;
+ }
+
+ _screen->drawSprites();
+ _screen->clearSprites();
+
+ _screen->drawTalkTextItems();
+
+ _system->copyRectToScreen((const byte *)_screen->_frontScreen, 640, 0, 0, 640, 400);
+ _system->updateScreen();
+
+ updateCamera();
+}
+
+void ToltecsEngine::setCamera(int16 x, int16 y) {
+
+ // TODO font_sub_4B5BB()
+
+ if (x > _sceneWidth)
+ x = _sceneWidth;
+
+ if (y > _sceneHeight - _cameraHeight)
+ y = _sceneHeight - _cameraHeight;
+
+ // TODO DirtyRect clearing stuff
+
+ _screen->clearSprites();
+
+ _cameraX = x;
+ _newCameraX = x;
+
+ _cameraY = y;
+ _newCameraY = y;
+
+ // TODO More DirtyRect clearing stuff
+
+}
+
+void ToltecsEngine::setCameraTop(int16 top) {
+ if (top != _cameraTop) {
+ _cameraTop = top;
+ _cameraHeight = 400 - _cameraTop;
+ debug(0, "ToltecsEngine::setCameraTop() _cameraTop = %d; _cameraHeight = %d", _cameraTop, _cameraHeight);
+ // TODO: clearScreen();
+ }
+}
+
+void ToltecsEngine::scrollCameraUp(int16 delta) {
+ if (_newCameraY > 0) {
+ if (_newCameraY < delta)
+ _newCameraY = 0;
+ else
+ _newCameraY -= delta;
+ // TODO: font_sub_4B5BB();
+ }
+}
+
+void ToltecsEngine::scrollCameraDown(int16 delta) {
+ debug(0, "ToltecsEngine::scrollCameraDown(%d)", delta);
+ if (_newCameraY != _sceneHeight - _cameraHeight) {
+ if (_sceneHeight - _cameraHeight < _newCameraY + delta)
+ delta += (_sceneHeight - _cameraHeight) - (delta + _newCameraY);
+ _newCameraY += delta;
+ debug(0, "ToltecsEngine::scrollCameraDown() _newCameraY = %d; delta = %d", _newCameraY, delta);
+ // TODO: font_sub_4B5BB();
+ }
+}
+
+void ToltecsEngine::scrollCameraLeft(int16 delta) {
+ if (_newCameraX > 0) {
+ if (_newCameraX < delta)
+ _newCameraX = 0;
+ else
+ _newCameraX -= delta;
+ // TODO: font_sub_4B5BB();
+ }
+}
+
+void ToltecsEngine::scrollCameraRight(int16 delta) {
+ debug(0, "ToltecsEngine::scrollCameraRight(%d)", delta);
+ if (_newCameraX != _sceneWidth - 640) {
+ if (_sceneWidth - 640 < delta + _newCameraX)
+ delta += (_sceneWidth - 640) - (delta + _newCameraX);
+ _newCameraX += delta;
+ debug(0, "ToltecsEngine::scrollCameraRight() _newCameraX = %d; delta = %d", _newCameraY, delta);
+ // TODO: font_sub_4B5BB();
+ }
+}
+
+void ToltecsEngine::updateCamera() {
+
+ _yetAnotherX = _newCameraX;
+ if (_cameraX != _yetAnotherX) {
+ //dirtyFullRefresh = -1;
+ }
+ _cameraX = _yetAnotherX;
+
+ if (_cameraY != _newCameraY) {
+ if (_cameraY < _newCameraY) {
+ /*
+ drawRequest.resIndex = -(cameraY - anotherY);
+ drawRequest.y = cameraHeight + cameraY;
+ drawRequest.x = cameraX;
+ drawRequest.flags = 640;
+ */
+ debug(0, "ToltecsEngine::updateCamera() a: (%d, %d, %d, %d)",
+ -(_cameraY - _newCameraY), _cameraHeight + _cameraY, _cameraX, 640);
+ //dirtyFullRefresh = -1;
+ } else {
+ /*
+ drawRequest.resIndex = cameraY - anotherY;
+ drawRequest.y = anotherY;
+ drawRequest.x = cameraX;
+ drawRequest.flags = 640;
+ */
+ debug(0, "ToltecsEngine::updateCamera() b: (%d, %d, %d, %d)",
+ _cameraY - _newCameraY, _newCameraY, _cameraX, 640);
+ //dirtyFullRefresh = -1;
+ }
+ }
+ _cameraY = _newCameraY;
+
+ debug(0, "ToltecsEngine::checkCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
+
+}
+
+void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
+
+ byte *scanData = _script->getSlotData(slotIndex) + slotOffset;
+
+ while (*scanData < 0xF0) {
+
+ if (*scanData == 0x19) {
+ scanData++;
+ } else if (*scanData == 0x14) {
+ scanData++;
+ } else if (*scanData == 0x0A) {
+ scanData += 4;
+ } else if (*scanData < 0x0A) {
+ scanData++;
+ }
+
+ scanData++;
+ }
+
+ if (*scanData == 0xFE) {
+ if (_doSpeech) {
+ int16 resIndex = READ_LE_UINT16(scanData + 1);
+ debug(0, "ToltecsEngine::talk() playSound(resIndex: %d)", resIndex);
+ }
+ if (_doText) {
+ _screen->updateTalkText(slotIndex, slotOffset);
+ } else {
+ // TODO: font_sub_4B3E2
+ }
+ } else {
+ _screen->updateTalkText(slotIndex, slotOffset);
+ }
+
+}
+
+void ToltecsEngine::playText(int16 slotIndex, int16 slotOffset) {
+
+ byte *textData = _script->getSlotData(slotIndex) + slotOffset;
+
+ debug(0, "ToltecsEngine::playText() [textData = %s]", (char*)textData);
+
+ Common::String str;
+ while (*textData < 0xF0) {
+ if (*textData >= 32)
+ str += (char)*textData;
+ textData++;
+ }
+
+ debug(0, "ToltecsEngine::playText() [%s]", str.c_str());
+
+}
+
+void ToltecsEngine::walk(byte *walkData) {
+
+ int16 xdelta, ydelta, v8, v10, v11;
+ int16 xstep, ystep;
+ ScriptWalk walkInfo;
+
+ walkInfo.y = READ_LE_UINT16(walkData + 0);
+ walkInfo.x = READ_LE_UINT16(walkData + 2);
+ walkInfo.y1 = READ_LE_UINT16(walkData + 4);
+ walkInfo.x1 = READ_LE_UINT16(walkData + 6);
+ walkInfo.y2 = READ_LE_UINT16(walkData + 8);
+ walkInfo.x2 = READ_LE_UINT16(walkData + 10);
+ walkInfo.yerror = READ_LE_UINT16(walkData + 12);
+ walkInfo.xerror = READ_LE_UINT16(walkData + 14);
+ walkInfo.mulValue = READ_LE_UINT16(walkData + 16);
+ walkInfo.scaling = READ_LE_UINT16(walkData + 18);
+
+ walkInfo.scaling = -_segmap->getScalingAtPoint(walkInfo.x, walkInfo.y);
+
+ if (walkInfo.y1 < walkInfo.y2)
+ ystep = -1;
+ else
+ ystep = 1;
+ ydelta = ABS(walkInfo.y1 - walkInfo.y2) * _walkSpeedY;
+
+ if (walkInfo.x1 < walkInfo.x2)
+ xstep = -1;
+ else
+ xstep = 1;
+ xdelta = ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX;
+
+ debug(0, "ToltecsEngine::walk() xdelta = %d; ydelta = %d", xdelta, ydelta);
+
+ if (xdelta > ydelta)
+ SWAP(xdelta, ydelta);
+
+ v8 = 100 * xdelta;
+ if (v8 != 0) {
+ if (walkInfo.scaling > 0)
+ v8 -= v8 * ABS(walkInfo.scaling) / 100;
+ else
+ v8 += v8 * ABS(walkInfo.scaling) / 100;
+ if (ydelta != 0)
+ v8 /= ydelta;
+ }
+
+ if (ydelta > ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX) {
+ v10 = 100 - walkInfo.scaling;
+ v11 = v8;
+ } else {
+ v10 = v8;
+ v11 = 100 - walkInfo.scaling;
+ }
+
+ walkInfo.yerror += walkInfo.mulValue * v10;
+ while (walkInfo.yerror >= 100 * _walkSpeedY) {
+ walkInfo.yerror -= 100 * _walkSpeedY;
+ if (walkInfo.y == walkInfo.y1) {
+ walkInfo.x = walkInfo.x1;
+ break;
+ }
+ walkInfo.y += ystep;
+ }
+
+ walkInfo.xerror += walkInfo.mulValue * v11;
+ while (walkInfo.xerror >= 100 * _walkSpeedX) {
+ walkInfo.xerror -= 100 * _walkSpeedX;
+ if (walkInfo.x == walkInfo.x1) {
+ walkInfo.y = walkInfo.y1;
+ break;
+ }
+ walkInfo.x += xstep;
+ }
+
+ WRITE_LE_UINT16(walkData + 0, walkInfo.y);
+ WRITE_LE_UINT16(walkData + 2, walkInfo.x);
+ WRITE_LE_UINT16(walkData + 4, walkInfo.y1);
+ WRITE_LE_UINT16(walkData + 6, walkInfo.x1);
+ WRITE_LE_UINT16(walkData + 8, walkInfo.y2);
+ WRITE_LE_UINT16(walkData + 10, walkInfo.x2);
+ WRITE_LE_UINT16(walkData + 12, walkInfo.yerror);
+ WRITE_LE_UINT16(walkData + 14, walkInfo.xerror);
+ WRITE_LE_UINT16(walkData + 16, walkInfo.mulValue);
+ WRITE_LE_UINT16(walkData + 18, walkInfo.scaling);
+
+}
+
+int16 ToltecsEngine::findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize) {
+
+ rectData += index * itemSize;
+
+ while (1) {
+ int16 rectY = READ_LE_UINT16(rectData);
+ if (rectY == -10)
+ break;
+ int16 rectX = READ_LE_UINT16(rectData + 2);
+ int16 rectH = READ_LE_UINT16(rectData + 4);
+ int16 rectW = READ_LE_UINT16(rectData + 6);
+
+ debug(0, "x = %d; y = %d; x1 = %d; y2 = %d; w = %d; h = %d",
+ x, y, rectX, rectY, rectW, rectH);
+
+ if (x >= rectX && x <= rectX + rectW && y >= rectY && y <= rectY + rectH) {
+ return index;
+ }
+ index++;
+ rectData += itemSize;
+ }
+
+ return -1;
+
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
new file mode 100644
index 0000000..47c7a94
--- /dev/null
+++ b/engines/toltecs/toltecs.h
@@ -0,0 +1,130 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_H
+#define TOLTECS_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+enum ToltecsGameFeatures {
+ GF_PACKED = (1 << 0)
+};
+
+struct ToltecsGameDescription;
+
+class AnimationPlayer;
+class ArchiveReader;
+class Input;
+class Palette;
+class ResourceCache;
+class ScriptInterpreter;
+class Screen;
+class SegmentMap;
+
+class ToltecsEngine : public ::Engine {
+ Common::KeyState _keyPressed;
+
+protected:
+ int init();
+ int go();
+// void shutdown();
+
+public:
+ ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDesc);
+ virtual ~ToltecsEngine();
+
+ Common::RandomSource *_rnd;
+ const ToltecsGameDescription *_gameDescription;
+ uint32 getFeatures() const;
+ Common::Language getLanguage() const;
+
+ void loadScene(uint resIndex);
+
+ void updateScreen();
+
+ void setCamera(int16 x, int16 y);
+ void setCameraTop(int16 top);
+ void scrollCameraUp(int16 delta);
+ void scrollCameraDown(int16 delta);
+ void scrollCameraLeft(int16 delta);
+ void scrollCameraRight(int16 delta);
+ void updateCamera();
+
+ void talk(int16 slotIndex, int16 slotOffset);
+ void playText(int16 slotIndex, int16 slotOffset);
+
+ void walk(byte *walkData);
+
+ int16 findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize);
+
+public:
+ AnimationPlayer *_anim;
+ ArchiveReader *_arc;
+ Input *_input;
+ Palette *_palette;
+ ResourceCache *_res;
+ ScriptInterpreter *_script;
+ Screen *_screen;
+ SegmentMap *_segmap;
+
+ uint _sceneResIndex;
+ int16 _sceneWidth, _sceneHeight;
+ //byte _scenePalette[768];
+
+ bool _quitGame;
+ int _counter01, _counter02;
+ bool _movieSceneFlag;
+ byte _flag01;
+
+ // TODO: Move camera stuff into own Scene class
+ int16 _cameraX, _cameraY;
+ int16 _newCameraX, _newCameraY;
+ int16 _cameraTop, _cameraHeight;
+ int16 _yetAnotherX;
+
+ bool _doSpeech, _doText;
+
+ int16 _walkSpeedY, _walkSpeedX;
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_H */
Commit: f4e156b3b313d63983c5da68e3b76811926db9de
https://github.com/scummvm/scummvm/commit/f4e156b3b313d63983c5da68e3b76811926db9de
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Fixed tabs and formatting.
Changed paths:
engines/toltecs/animation.cpp
engines/toltecs/animation.h
engines/toltecs/input.cpp
engines/toltecs/input.h
engines/toltecs/palette.cpp
engines/toltecs/palette.h
engines/toltecs/resource.cpp
engines/toltecs/resource.h
engines/toltecs/screen.cpp
engines/toltecs/screen.h
engines/toltecs/script.cpp
engines/toltecs/script.h
engines/toltecs/segmap.cpp
engines/toltecs/segmap.h
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
index 2dbffbd..2ecc12b 100644
--- a/engines/toltecs/animation.cpp
+++ b/engines/toltecs/animation.cpp
@@ -39,7 +39,7 @@
namespace Toltecs {
AnimationPlayer::AnimationPlayer(ToltecsEngine *vm) : _vm(vm) {
- _animBuffer = new byte[262144];
+ _animBuffer = new byte[262144];
}
AnimationPlayer::~AnimationPlayer() {
@@ -64,7 +64,7 @@ void AnimationPlayer::start(uint resIndex) {
debug(1, "AnimationPlayer::start() width = %d; height = %d; frameCount = %d", _width, _height, _frameCount);
- unpackFrame();
+ unpackFrame();
_keepFrameCounter = 0;
_frameNumber = 0;
@@ -92,8 +92,8 @@ void AnimationPlayer::nextFrame() {
debug(1, "AnimationPlayer::nextFrame() frameNumber = %d", _frameNumber);
if (_keepFrameCounter > 0) {
- _keepFrameCounter--;
- return;
+ _keepFrameCounter--;
+ return;
}
_vm->_arc->openResource(_resIndex);
@@ -101,18 +101,18 @@ void AnimationPlayer::nextFrame() {
_curFrameSize = _nextFrameSize;
if (_curFrameSize == 0)
- _curFrameSize = 1;
+ _curFrameSize = 1;
_vm->_arc->read(_animBuffer, _curFrameSize);
_nextFrameSize = _vm->_arc->readUint32LE();
_nextFrameOffset += _curFrameSize + 4;
if (_curFrameSize > 1) {
- unpackFrame();
- // TODO mov animDrawFrameFlag, 0FFFFh
+ unpackFrame();
+ // TODO mov animDrawFrameFlag, 0FFFFh
} else {
- _keepFrameCounter = _animBuffer[0] - 1;
- // TODO mov animDrawFrameFlag, 0
+ _keepFrameCounter = _animBuffer[0] - 1;
+ // TODO mov animDrawFrameFlag, 0
}
_vm->_arc->closeResource();
@@ -124,16 +124,16 @@ int16 AnimationPlayer::getStatus() {
debug(1, "AnimationPlayer::getStatus()");
int16 status = -1;
if (_frameNumber == _frameCount)
- status = 0;
+ status = 0;
else if (_frameNumber == _frameCount - 1)
- status = 1;
+ status = 1;
debug(1, "AnimationPlayer::getStatus() status = %d", status);
return status;
}
void AnimationPlayer::unpackFrame() {
- _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_frontScreen, _width, _height);
- _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_backScreen, _width, _height);
+ _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_frontScreen, _width, _height);
+ _vm->_screen->unpackRle(_animBuffer, _vm->_screen->_backScreen, _width, _height);
}
} // End of namespace Toltecs
diff --git a/engines/toltecs/animation.h b/engines/toltecs/animation.h
index dc48421..a8bef1f 100644
--- a/engines/toltecs/animation.h
+++ b/engines/toltecs/animation.h
@@ -49,23 +49,23 @@ namespace Toltecs {
class AnimationPlayer {
public:
- AnimationPlayer(ToltecsEngine *vm);
- ~AnimationPlayer();
-
- void start(uint resIndex);
- void nextFrame();
- int16 getStatus();
- uint16 getFrameNumber() const { return _frameNumber; }
-
+ AnimationPlayer(ToltecsEngine *vm);
+ ~AnimationPlayer();
+
+ void start(uint resIndex);
+ void nextFrame();
+ int16 getStatus();
+ uint16 getFrameNumber() const { return _frameNumber; }
+
//protected:
public:
- ToltecsEngine *_vm;
+ ToltecsEngine *_vm;
// 262144
- byte *_animBuffer;
-
- uint _resIndex;
- byte _palette[768];
+ byte *_animBuffer;
+
+ uint _resIndex;
+ byte _palette[768];
uint16 _width, _height;
uint16 _frameNumber, _frameCount;
diff --git a/engines/toltecs/input.cpp b/engines/toltecs/input.cpp
index 50e9129..ca09a9b 100644
--- a/engines/toltecs/input.cpp
+++ b/engines/toltecs/input.cpp
@@ -47,11 +47,11 @@ Input::Input(ToltecsEngine *vm) : _vm(vm) {
_mouseCounter = 0;
_mouseButtonPressedFlag = false;
_mouseButton = 0;
- _mouseDisabled = 0;
+ _mouseDisabled = 0;
- _leftButtonDown = false;
+ _leftButtonDown = false;
_rightButtonDown = false;
-
+
}
Input::~Input() {
@@ -73,22 +73,22 @@ void Input::update() {
case Common::EVENT_LBUTTONDOWN:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
- _leftButtonDown = true;
+ _leftButtonDown = true;
break;
case Common::EVENT_LBUTTONUP:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
- _leftButtonDown = false;
+ _leftButtonDown = false;
break;
case Common::EVENT_RBUTTONDOWN:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
- _rightButtonDown = true;
+ _rightButtonDown = true;
break;
case Common::EVENT_RBUTTONUP:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
- _rightButtonDown = false;
+ _rightButtonDown = false;
break;
default:
break;
@@ -99,27 +99,27 @@ void Input::update() {
_mousePosDelta = _mousePosDelta + _mouseY - _mouseX;
if (_mouseCounter > 0)
- _mouseCounter--;
-
+ _mouseCounter--;
+
byte mouseButtons = 0;
if (_leftButtonDown)
- mouseButtons |= 1;
+ mouseButtons |= 1;
if (_rightButtonDown)
- mouseButtons |= 2;
-
+ mouseButtons |= 2;
+
if (mouseButtons != 0) {
if (!_mouseButtonPressedFlag) {
- _mouseButton = mouseButtons;
- if (_mouseCounter != 0)
- _mouseButton |= 0x80;
+ _mouseButton = mouseButtons;
+ if (_mouseCounter != 0)
+ _mouseButton |= 0x80;
_mouseCounter = 30; // maybe TODO
_mouseButtonPressedFlag = true;
} else {
- _mouseButton = 0;
+ _mouseButton = 0;
}
} else {
- _mouseButtonPressedFlag = false;
- _mouseButton = 0;
+ _mouseButtonPressedFlag = false;
+ _mouseButton = 0;
}
}
diff --git a/engines/toltecs/input.h b/engines/toltecs/input.h
index c82dd78..06196b8 100644
--- a/engines/toltecs/input.h
+++ b/engines/toltecs/input.h
@@ -46,8 +46,8 @@ namespace Toltecs {
class Input {
public:
- Input(ToltecsEngine *vm);
- ~Input();
+ Input(ToltecsEngine *vm);
+ ~Input();
void update();
@@ -58,7 +58,7 @@ public:
//protected:
public:
- ToltecsEngine *_vm;
+ ToltecsEngine *_vm;
int16 _mouseX, _mouseY;
int16 _mousePosDelta;
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 6ff20ff..7c882f1 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -50,13 +50,13 @@ Palette::~Palette() {
void Palette::setFullPalette(byte *palette) {
byte colors[1024];
for (int i = 0; i < 256; i++) {
- colors[i * 4 + 0] = palette[i * 3 + 0] << 2;
- colors[i * 4 + 1] = palette[i * 3 + 1] << 2;
- colors[i * 4 + 2] = palette[i * 3 + 2] << 2;
- colors[i * 4 + 3] = 255;
+ colors[i * 4 + 0] = palette[i * 3 + 0] << 2;
+ colors[i * 4 + 1] = palette[i * 3 + 1] << 2;
+ colors[i * 4 + 2] = palette[i * 3 + 2] << 2;
+ colors[i * 4 + 3] = 255;
}
- _vm->_system->setPalette((const byte *)colors, 0, 256);
- _vm->_system->updateScreen();
+ _vm->_system->setPalette((const byte *)colors, 0, 256);
+ _vm->_system->updateScreen();
}
void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex) {
@@ -74,32 +74,32 @@ void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 c
_vm->_system->grabPalette(colors, 0, 256);
if (deltaValue < 0) {
- deltaValue = -deltaValue;
- while (count--) {
- rgb = *palPtr++;
- if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
- rgb = *palPtr++;
- if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
- rgb = *palPtr++;
- if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
- index++;
+ deltaValue = -deltaValue;
+ while (count--) {
+ rgb = *palPtr++;
+ if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ rgb = *palPtr++;
+ if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ rgb = *palPtr++;
+ if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ index++;
}
} else {
- while (count--) {
- rgb = *palPtr++;
- if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
- rgb = *palPtr++;
- if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
- rgb = *palPtr++;
- if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
- index++;
+ while (count--) {
+ rgb = *palPtr++;
+ if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
+ rgb = *palPtr++;
+ if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
+ rgb = *palPtr++;
+ if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
+ index++;
}
}
debug(0, "startIndex = %d; colorCount = %d", startIndex, colorCount);
- _vm->_system->setPalette((const byte *)colors, 0, 256);
-
+ _vm->_system->setPalette((const byte *)colors, 0, 256);
+
}
void Palette::loadAddPalette(uint resIndex, byte startIndex) {
@@ -136,10 +136,10 @@ uint16 Palette::findFragment(int16 id) {
uint16 result = 0;
for (PaletteFragmentArray::iterator iter = _fragments.begin(); iter != _fragments.end(); iter++) {
- PaletteFragment fragment = *iter;
- if (fragment.id == id) {
- result = (fragment.count << 8) | fragment.index;
- break;
+ PaletteFragment fragment = *iter;
+ if (fragment.id == id) {
+ result = (fragment.count << 8) | fragment.index;
+ break;
}
}
diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h
index b550b80..339ff8d 100644
--- a/engines/toltecs/palette.h
+++ b/engines/toltecs/palette.h
@@ -49,37 +49,37 @@ namespace Toltecs {
class Palette {
public:
- Palette(ToltecsEngine *vm);
- ~Palette();
+ Palette(ToltecsEngine *vm);
+ ~Palette();
void setFullPalette(byte *palette);
void setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex);
-
- void loadAddPalette(uint resIndex, byte startIndex);
- void loadAddPaletteFrom(byte *source, byte startIndex, byte count);
-
- void addFragment(uint resIndex, int16 id);
- uint16 findFragment(int16 id);
- void clearFragments();
-
- byte *getMainPalette() { return _mainPalette; }
-
+
+ void loadAddPalette(uint resIndex, byte startIndex);
+ void loadAddPaletteFrom(byte *source, byte startIndex, byte count);
+
+ void addFragment(uint resIndex, int16 id);
+ uint16 findFragment(int16 id);
+ void clearFragments();
+
+ byte *getMainPalette() { return _mainPalette; }
+
protected:
struct PaletteFragment {
- int16 id;
- byte index, count;
+ int16 id;
+ byte index, count;
};
typedef Common::Array<PaletteFragment> PaletteFragmentArray;
- ToltecsEngine *_vm;
-
- byte _mainPalette[768];
-
+ ToltecsEngine *_vm;
+
+ byte _mainPalette[768];
+
PaletteFragmentArray _fragments;
byte _fragmentIndex;
-
+
};
} // End of namespace Toltecs
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index 0280467..9449fdf 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -49,7 +49,7 @@ ArchiveReader::~ArchiveReader() {
void ArchiveReader::openArchive(const char *filename) {
open(filename);
for (uint i = 0; i < 10000; i++)
- _offsets[i] = readUint32LE();
+ _offsets[i] = readUint32LE();
}
uint32 ArchiveReader::openResource(uint resIndex) {
@@ -98,8 +98,8 @@ ResourceCache::ResourceCache(ToltecsEngine *vm) : _vm(vm) {
memset(_cache, 0, sizeof(_cache));
_cacheCount = 0;
- _curItemOffset = 0;
- _curItemSize = 0;
+ _curItemOffset = 0;
+ _curItemSize = 0;
}
@@ -110,11 +110,11 @@ ResourceCache::~ResourceCache() {
byte *ResourceCache::load(uint resIndex) {
byte *data = NULL;
if (existsItem(resIndex)) {
- debug(1, "ResourceCache::load(%d) From cache", resIndex);
- data = _base + _curItemOffset;
+ debug(1, "ResourceCache::load(%d) From cache", resIndex);
+ data = _base + _curItemOffset;
} else {
- debug(1, "ResourceCache::load(%d) From disk", resIndex);
- uint32 size = _vm->_arc->openResource(resIndex);
+ debug(1, "ResourceCache::load(%d) From disk", resIndex);
+ uint32 size = _vm->_arc->openResource(resIndex);
data = addItem(resIndex, size);
_vm->_arc->read(data, size);
_vm->_arc->closeResource();
@@ -124,10 +124,10 @@ byte *ResourceCache::load(uint resIndex) {
bool ResourceCache::existsItem(uint resIndex) {
for (uint i = 0; i < _cacheCount; i++) {
- if (_cache[i].resIndex == resIndex) {
- _curItemOffset = _cache[i].offset;
- _curItemSize = _cache[i].size;
- return true;
+ if (_cache[i].resIndex == resIndex) {
+ _curItemOffset = _cache[i].offset;
+ _curItemSize = _cache[i].size;
+ return true;
}
}
return false;
@@ -137,15 +137,15 @@ byte *ResourceCache::addItem(uint resIndex, uint32 size) {
checkCapacity(size);
- _curItemOffset = _bytesUsed;
- _curItemSize = size;
+ _curItemOffset = _bytesUsed;
+ _curItemSize = size;
- _cache[_cacheCount].resIndex = resIndex;
- _cache[_cacheCount].offset = _curItemOffset;
- _cache[_cacheCount].size = _curItemSize;
- _cacheCount++;
-
- _bytesUsed += size;
+ _cache[_cacheCount].resIndex = resIndex;
+ _cache[_cacheCount].offset = _curItemOffset;
+ _cache[_cacheCount].size = _curItemSize;
+ _cacheCount++;
+
+ _bytesUsed += size;
return _base + _curItemOffset;
@@ -153,8 +153,8 @@ byte *ResourceCache::addItem(uint resIndex, uint32 size) {
void ResourceCache::checkCapacity(uint32 size) {
if (_cacheCount > kMaxCacheItems || _bytesUsed + size > kMaxCacheSize) {
- _cacheCount = 0;
- _bytesUsed = 0;
+ _cacheCount = 0;
+ _bytesUsed = 0;
}
}
diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h
index c15918b..b4d21c3 100644
--- a/engines/toltecs/resource.h
+++ b/engines/toltecs/resource.h
@@ -48,7 +48,7 @@ namespace Toltecs {
TODO:
ArchiveReader:
- - Add support for external resources; and check if they're used
+ - Add support for external resources; and check if they're used
*/
@@ -58,20 +58,20 @@ const uint kMaxCacheSize = 8 * 1024 * 1024; // 8 MB
class ArchiveReader : public Common::File {
public:
- ArchiveReader();
- ~ArchiveReader();
-
- void openArchive(const char *filename);
-
- // Returns the size of the opened resource
- uint32 openResource(uint resIndex);
- // Closes the resource
- void closeResource();
- // Returns the size of the resource
- uint32 getResourceSize(uint resIndex);
-
- void dump(uint resIndex, const char *prefix = NULL);
-
+ ArchiveReader();
+ ~ArchiveReader();
+
+ void openArchive(const char *filename);
+
+ // Returns the size of the opened resource
+ uint32 openResource(uint resIndex);
+ // Closes the resource
+ void closeResource();
+ // Returns the size of the resource
+ uint32 getResourceSize(uint resIndex);
+
+ void dump(uint resIndex, const char *prefix = NULL);
+
protected:
uint32 _offsets[10000];
@@ -79,23 +79,23 @@ protected:
class ResourceCache {
public:
- ResourceCache(ToltecsEngine *vm);
- ~ResourceCache();
-
- byte *load(uint resIndex);
- uint32 getCurItemSize() const { return _curItemSize; }
+ ResourceCache(ToltecsEngine *vm);
+ ~ResourceCache();
+
+ byte *load(uint resIndex);
+ uint32 getCurItemSize() const { return _curItemSize; }
protected:
struct CacheItem {
- uint resIndex;
- //int value; // what is this?
- int32 offset; // offset into _base
- uint32 size; // size of the item
+ uint resIndex;
+ //int value; // what is this?
+ int32 offset; // offset into _base
+ uint32 size; // size of the item
};
- ToltecsEngine *_vm;
-
+ ToltecsEngine *_vm;
+
byte *_base;
uint32 _bytesUsed;
uint32 _curItemOffset, _curItemSize;
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 69d2966..779513a 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -45,12 +45,12 @@ namespace Toltecs {
Screen::Screen(ToltecsEngine *vm) : _vm(vm) {
- _frontScreen = new byte[268800];
+ _frontScreen = new byte[268800];
_backScreen = new byte[870400];
memset(_fontResIndexArray, 0, sizeof(_fontResIndexArray));
- _fontColor1 = 0;
- _fontColor2 = 0;
+ _fontColor1 = 0;
+ _fontColor2 = 0;
// Screen shaking
_shakeActive = false;
@@ -85,37 +85,37 @@ Screen::~Screen() {
void Screen::unpackRle(byte *source, byte *dest, uint16 width, uint16 height) {
int32 size = width * height;
- while (size > 0) {
- byte a = *source++;
- byte b = *source++;
- if (a == 0) {
- dest += b;
- size -= b;
- } else {
- b = ((b << 4) & 0xF0) | ((b >> 4) & 0x0F);
- memset(dest, b, a);
- dest += a;
- size -= a;
- }
- }
+ while (size > 0) {
+ byte a = *source++;
+ byte b = *source++;
+ if (a == 0) {
+ dest += b;
+ size -= b;
+ } else {
+ b = ((b << 4) & 0xF0) | ((b >> 4) & 0x0F);
+ memset(dest, b, a);
+ dest += a;
+ size -= a;
+ }
+ }
}
void Screen::loadMouseCursor(uint resIndex) {
byte mouseCursor[16 * 16], *mouseCursorP = mouseCursor;
byte *cursorData = _vm->_res->load(resIndex);
for (int i = 0; i < 32; i++) {
- byte pixel;
- byte mask1 = *cursorData++;
- byte mask2 = *cursorData++;
- for (int j = 0; j < 8; j++) {
- pixel = 0xE5;
- if ((mask2 & 0x80) == 0)
- pixel = 0xE0;
- mask2 <<= 1;
- if ((mask1 & 0x80) == 0)
- pixel = 0;
- mask1 <<= 1;
- *mouseCursorP++ = pixel;
+ byte pixel;
+ byte mask1 = *cursorData++;
+ byte mask2 = *cursorData++;
+ for (int j = 0; j < 8; j++) {
+ pixel = 0xE5;
+ if ((mask2 & 0x80) == 0)
+ pixel = 0xE0;
+ mask2 <<= 1;
+ if ((mask1 & 0x80) == 0)
+ pixel = 0;
+ mask1 <<= 1;
+ *mouseCursorP++ = pixel;
}
}
//CursorMan.replaceCursor((const byte*)mouseCursor, 16, 16, 0, 0, 0);
@@ -151,9 +151,9 @@ void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
*dest++ = pixel;
workWidth--;
if (workWidth == 0) {
- workHeight--;
- dest += 640 - width;
- workWidth = width;
+ workHeight--;
+ dest += 640 - width;
+ workWidth = width;
}
}
}
@@ -174,11 +174,11 @@ void Screen::stopShakeScreen() {
void Screen::updateShakeScreen() {
if (_shakeActive) {
- _shakeCounter--;
- if (_shakeCounter == 0) {
- _shakeCounter = _shakeCounterInit;
- _shakePos ^= 8;
- _vm->_system->setShakePos(_shakePos);
+ _shakeCounter--;
+ if (_shakeCounter == 0) {
+ _shakeCounter = _shakeCounterInit;
+ _shakePos ^= 8;
+ _vm->_system->setShakePos(_shakePos);
}
}
}
@@ -198,13 +198,13 @@ void Screen::addStaticSprite(byte *spriteItem) {
debug(0, "Screen::addStaticSprite() x = %d; y = %d; baseColor = %d; resIndex = %d; flags = %04X", drawRequest.x, drawRequest.y, drawRequest.baseColor, drawRequest.resIndex, drawRequest.flags);
- addDrawRequest(drawRequest);
+ addDrawRequest(drawRequest);
}
void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, int16 *spriteArray, bool loop, int mode) {
- debug(0, "Screen::addAnimatedSprite(%d, %d, %d)", x, y, fragmentId);
+ debug(0, "Screen::addAnimatedSprite(%d, %d, %d)", x, y, fragmentId);
DrawRequest drawRequest;
memset(&drawRequest, 0, sizeof(drawRequest));
@@ -245,13 +245,13 @@ void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, i
loopNum++;
if (loopNum == loopCount) {
if (loop) {
- loopNum = 0;
+ loopNum = 0;
} else {
- loopNum--;
+ loopNum--;
}
}
} else {
- loopNum |= 0x8000;
+ loopNum |= 0x8000;
}
WRITE_LE_UINT16(spriteItem + 0, loopNum);
@@ -263,8 +263,8 @@ void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, i
void Screen::clearSprites() {
- _spriteDrawList.clear();
- // TODO
+ _spriteDrawList.clear();
+ // TODO
}
@@ -275,12 +275,12 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
byte *spriteData;
int16 frameNum;
- SpriteDrawItem sprite;
- memset(&sprite, 0, sizeof(SpriteDrawItem));
+ SpriteDrawItem sprite;
+ memset(&sprite, 0, sizeof(SpriteDrawItem));
if (drawRequest.flags == 0xFFFF)
- return;
-
+ return;
+
sprite.flags = 0;
sprite.baseColor = drawRequest.baseColor;
sprite.x = drawRequest.x;
@@ -291,11 +291,11 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
spriteData = _vm->_res->load(drawRequest.resIndex);
if (drawRequest.flags & 0x2000) {
- sprite.flags |= 0x10;
+ sprite.flags |= 0x10;
}
if (drawRequest.flags & 0x4000) {
- sprite.flags |= 0x40;
+ sprite.flags |= 0x40;
}
frameNum = drawRequest.flags & 0x0FFF;
@@ -305,7 +305,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
SpriteFrameEntry spriteFrameEntry(spriteData + frameNum * 12);
if (spriteFrameEntry.w == 0 || spriteFrameEntry.h == 0)
- return;
+ return;
sprite.offset = spriteFrameEntry.offset;
@@ -316,9 +316,9 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.origHeight = spriteFrameEntry.h;
if (drawRequest.flags & 0x1000) {
- spriteDraw_X = spriteFrameEntry.w - spriteFrameEntry.x;
+ spriteDraw_X = spriteFrameEntry.w - spriteFrameEntry.x;
} else {
- spriteDraw_X = spriteFrameEntry.x;
+ spriteDraw_X = spriteFrameEntry.x;
}
spriteDraw_Y = spriteFrameEntry.y;
@@ -327,7 +327,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (drawRequest.scaling != 0) {
- byte scaleValue = ABS(drawRequest.scaling);
+ byte scaleValue = ABS(drawRequest.scaling);
scaleValueX = scaleValue * sprite.origWidth;
sprite.xdelta = (10000 * sprite.origWidth) / scaleValueX;
@@ -338,63 +338,63 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
scaleValueY /= 100;
if (drawRequest.scaling > 0) {
- sprite.flags |= 2;
- sprite.width = sprite.origWidth + scaleValueX;
- sprite.height = sprite.origHeight + scaleValueY;
- spriteDraw_X += (spriteDraw_X * scaleValue) / 100;
- spriteDraw_Y += (spriteDraw_Y * scaleValue) / 100;
+ sprite.flags |= 2;
+ sprite.width = sprite.origWidth + scaleValueX;
+ sprite.height = sprite.origHeight + scaleValueY;
+ spriteDraw_X += (spriteDraw_X * scaleValue) / 100;
+ spriteDraw_Y += (spriteDraw_Y * scaleValue) / 100;
} else {
- sprite.flags |= 1;
+ sprite.flags |= 1;
sprite.width = sprite.origWidth - scaleValueX;
- sprite.height = sprite.origHeight - 1 - scaleValueY;
+ sprite.height = sprite.origHeight - 1 - scaleValueY;
if (sprite.width <= 0 || sprite.height <= 0)
- return;
- spriteDraw_X -= (spriteDraw_X * scaleValue) / 100;
- spriteDraw_Y -= (spriteDraw_Y * scaleValue) / 100;
+ return;
+ spriteDraw_X -= (spriteDraw_X * scaleValue) / 100;
+ spriteDraw_Y -= (spriteDraw_Y * scaleValue) / 100;
}
}
sprite.x -= spriteDraw_X;
- sprite.y -= spriteDraw_Y;
+ sprite.y -= spriteDraw_Y;
- sprite.yerror = sprite.ydelta;
+ sprite.yerror = sprite.ydelta;
// Now we check if the sprite needs to be clipped
// Clip Y
- if (sprite.y - _vm->_cameraY < 0) {
-
- int16 clipHeight = ABS(sprite.y - _vm->_cameraY);
- int16 chopHeight, skipHeight, lineWidth;
- byte *spriteFrameData;
+ if (sprite.y - _vm->_cameraY < 0) {
+
+ int16 clipHeight = ABS(sprite.y - _vm->_cameraY);
+ int16 chopHeight, skipHeight, lineWidth;
+ byte *spriteFrameData;
sprite.height -= clipHeight;
if (sprite.height <= 0)
- return;
+ return;
- sprite.y = _vm->_cameraY;
-
- // If the sprite is scaled
- if (sprite.flags & 3) {
- chopHeight = sprite.ydelta;
+ sprite.y = _vm->_cameraY;
+
+ // If the sprite is scaled
+ if (sprite.flags & 3) {
+ chopHeight = sprite.ydelta;
skipHeight = clipHeight;
- if ((sprite.flags & 2) == 0) {
- do {
- chopHeight -= 100;
- if (chopHeight <= 0) {
- skipHeight++;
- chopHeight += sprite.ydelta;
+ if ((sprite.flags & 2) == 0) {
+ do {
+ chopHeight -= 100;
+ if (chopHeight <= 0) {
+ skipHeight++;
+ chopHeight += sprite.ydelta;
} else {
- clipHeight--;
+ clipHeight--;
}
} while (clipHeight > 0);
} else {
- do {
- chopHeight -= 100;
- if (chopHeight < 0) {
- skipHeight--;
- chopHeight += sprite.ydelta + 100;
+ do {
+ chopHeight -= 100;
+ if (chopHeight < 0) {
+ skipHeight--;
+ chopHeight += sprite.ydelta + 100;
}
clipHeight--;
} while (clipHeight > 0);
@@ -407,72 +407,72 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
// Now the sprite's offset is adjusted to point to the starting line
if ((sprite.flags & 0x10) == 0) {
while (clipHeight--) {
- lineWidth = 0;
- while (lineWidth </*CHECKME was != */ sprite.origWidth) {
- sprite.offset++;
- lineWidth += (*spriteFrameData++) & 0x0F;
+ lineWidth = 0;
+ while (lineWidth </*CHECKME was != */ sprite.origWidth) {
+ sprite.offset++;
+ lineWidth += (*spriteFrameData++) & 0x0F;
}
}
} else {
- lineWidth = 0;
+ lineWidth = 0;
while (clipHeight--) {
- while (lineWidth < sprite.origWidth) {
- sprite.offset += 2;
- spriteFrameData++;
+ while (lineWidth < sprite.origWidth) {
+ sprite.offset += 2;
+ spriteFrameData++;
lineWidth += *spriteFrameData++;
}
}
}
-
+
}
if (sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight > 0)
- sprite.height -= sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight;
+ sprite.height -= sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight;
if (sprite.height <= 0)
- return;
-
+ return;
+
sprite.value1 = 0;
if (drawRequest.flags & 0x1000) {
- // Left border
- sprite.flags |= 4;
- if (sprite.x - _vm->_cameraX < 0) {
- sprite.width -= ABS(sprite.x - _vm->_cameraX);
- if (sprite.width <= 0)
- return;
+ // Left border
+ sprite.flags |= 4;
+ if (sprite.x - _vm->_cameraX < 0) {
+ sprite.width -= ABS(sprite.x - _vm->_cameraX);
+ if (sprite.width <= 0)
+ return;
sprite.x = _vm->_cameraX;
}
- // Right border
+ // Right border
if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
- sprite.flags |= 8;
- sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
- if (sprite.width <= 0)
- return;
+ sprite.flags |= 8;
+ sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
+ if (sprite.width <= 0)
+ return;
sprite.value1 = sprite.x + sprite.width - _vm->_cameraX - 640;
}
} else {
- // Left border
- if (sprite.x - _vm->_cameraX < 0) {
- sprite.flags |= 8;
- sprite.width -= ABS(sprite.x - _vm->_cameraX);
- if (sprite.width <= 0)
- return;
- sprite.value1 = ABS(sprite.x - _vm->_cameraX);
- sprite.x = _vm->_cameraX;
+ // Left border
+ if (sprite.x - _vm->_cameraX < 0) {
+ sprite.flags |= 8;
+ sprite.width -= ABS(sprite.x - _vm->_cameraX);
+ if (sprite.width <= 0)
+ return;
+ sprite.value1 = ABS(sprite.x - _vm->_cameraX);
+ sprite.x = _vm->_cameraX;
}
- // Right border
+ // Right border
if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
- sprite.flags |= 8;
+ sprite.flags |= 8;
sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
- if (sprite.width <= 0)
- return;
+ if (sprite.width <= 0)
+ return;
}
}
// Add sprite sorted by priority
Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin();
while (iter != _spriteDrawList.end() && (*iter).ybottom <= sprite.ybottom) {
- iter++;
+ iter++;
}
_spriteDrawList.insert(iter, sprite);
@@ -480,43 +480,43 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
void Screen::drawSprite(SpriteDrawItem *sprite) {
- debug(0, "Screen::drawSprite() x = %d; y = %d; flags = %04X; resIndex = %d; offset = %08X; drawX = %d; drawY = %d",
+ debug(0, "Screen::drawSprite() x = %d; y = %d; flags = %04X; resIndex = %d; offset = %08X; drawX = %d; drawY = %d",
sprite->x, sprite->y, sprite->flags, sprite->resIndex, sprite->offset,
sprite->x - _vm->_cameraX, sprite->y - _vm->_cameraY);
- debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
+ debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
sprite->width, sprite->height, sprite->origWidth, sprite->origHeight);
- byte *source = _vm->_res->load(sprite->resIndex) + sprite->offset;
- byte *dest = _frontScreen + (sprite->x - _vm->_cameraX) + (sprite->y - _vm->_cameraY) * 640;
+ byte *source = _vm->_res->load(sprite->resIndex) + sprite->offset;
+ byte *dest = _frontScreen + (sprite->x - _vm->_cameraX) + (sprite->y - _vm->_cameraY) * 640;
// FIXME: Temporary hack until proper clipping is implemented
/*
int16 dx = sprite->x - _vm->_cameraX, dy = sprite->y - _vm->_cameraY;
if (dx < 0 || dy < 0 || dx + sprite->width >= 640 || dy + sprite->height >= 400)
- return;
- */
+ return;
+ */
+
+ SpriteReader spriteReader(source, sprite);
- SpriteReader spriteReader(source, sprite);
-
if (sprite->flags & 0x40) {
- // TODO: Shadow sprites
+ // TODO: Shadow sprites
} else if (sprite->flags & 0x10) {
- // 256 color sprite
- drawSpriteCore(dest, spriteReader, sprite);
+ // 256 color sprite
+ drawSpriteCore(dest, spriteReader, sprite);
} else {
- // 16 color sprite
- if (sprite->flags & 1) {
- SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
- drawSpriteCore(dest, spriteScaler, sprite);
+ // 16 color sprite
+ if (sprite->flags & 1) {
+ SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
} else if (sprite->flags & 2) {
- SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
- drawSpriteCore(dest, spriteScaler, sprite);
+ SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
} else {
- drawSpriteCore(dest, spriteReader, sprite);
+ drawSpriteCore(dest, spriteReader, sprite);
}
}
- debug(0, "Screen::drawSprite() ok");
+ debug(0, "Screen::drawSprite() ok");
}
@@ -526,14 +526,14 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
/*
if ((sprite->flags & 8))
- return;
- */
+ return;
+ */
if (sprite->flags & 4) {
- destInc = -1;
+ destInc = -1;
dest += sprite->width;
} else {
- destInc = 1;
+ destInc = 1;
}
SpriteReaderStatus status;
@@ -546,29 +546,29 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
status = reader.readPacket(packet);
if (skipX > 0) {
- while (skipX > 0) {
- skipX -= packet.count;
- if (skipX < 0) {
+ while (skipX > 0) {
+ skipX -= packet.count;
+ if (skipX < 0) {
packet.count = ABS(skipX);
break;
}
- status = reader.readPacket(packet);
+ status = reader.readPacket(packet);
}
}
if (((sprite->flags & 0x10) && (packet.pixel != 0xFF)) || !(sprite->flags & 0x10) && (packet.pixel != 0)) {
if (sprite->flags & 0x40) {
} else if (sprite->flags & 0x10) {
- packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
+ packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
} else {
- packet.pixel += sprite->baseColor - 1;
- }
- while (packet.count--) {
- *dest = packet.pixel;
+ packet.pixel += sprite->baseColor - 1;
+ }
+ while (packet.count--) {
+ *dest = packet.pixel;
dest += destInc;
}
} else {
- dest += packet.count * destInc;
+ dest += packet.count * destInc;
}
if (status == kSrsEndOfLine) {
@@ -583,7 +583,7 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
void Screen::drawSprites() {
for (Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin(); iter != _spriteDrawList.end(); iter++) {
- SpriteDrawItem *sprite = &(*iter);
+ SpriteDrawItem *sprite = &(*iter);
drawSprite(sprite);
_vm->_segmap->restoreMasksBySprite(sprite);
}
@@ -596,16 +596,16 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
Font font(_vm->_res->load(_fontResIndexArray[0]));
- _verbLineItems[_verbLineNum].slotIndex = slotIndex;
- _verbLineItems[_verbLineNum].slotOffset = slotOffset;
+ _verbLineItems[_verbLineNum].slotIndex = slotIndex;
+ _verbLineItems[_verbLineNum].slotOffset = slotOffset;
// First clear the line
int16 y = _verbLineY;
for (int16 i = 0; i < _verbLineCount; i++) {
byte *dest = _frontScreen + _verbLineX - _verbLineWidth / 2 + (y - 1 + _vm->_cameraHeight) * 640;
for (int16 j = 0; j < 20; j++) {
- memset(dest, 0xE0, _verbLineWidth);
- dest += 640;
+ memset(dest, 0xE0, _verbLineWidth);
+ dest += 640;
}
y += 18;
}
@@ -622,19 +622,19 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
memset(_tempString, 0, sizeof(_tempString));
for (int16 i = 0; i <= _verbLineNum; i++) {
- sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
+ sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
preprocessText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
_tempStringLen1 += len;
}
if (_verbLineCount != 1) {
- int16 charWidth;
- if (*sourceString < 0xF0) {
+ int16 charWidth;
+ if (*sourceString < 0xF0) {
while (*sourceString > 0x20 && *sourceString < 0xF0 && len > 0/*CHECKME, len check added*/) {
- byte ch = *sourceString--;
- _tempStringLen1--;
- len--;
- charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
+ byte ch = *sourceString--;
+ _tempStringLen1--;
+ len--;
+ charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
width -= charWidth;
}
width += charWidth;
@@ -642,14 +642,14 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
_tempStringLen1 -= len;
_tempStringLen2 = len + 1;
- drawString(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+ drawString(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
destString = _tempString;
width = 0;
preprocessText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
_tempStringLen1 += len;
- y += 9;
+ y += 9;
}
y += 9;
}
@@ -667,10 +667,10 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
byte durationModifier = 1;
byte *textData = _vm->_script->getSlotData(slotIndex) + slotOffset;
- TalkTextItem *item = &_talkTextItems[_talkTextItemNum];
+ TalkTextItem *item = &_talkTextItems[_talkTextItemNum];
- item->fontNum = 0;
- item->color = _talkTextFontColor;
+ item->fontNum = 0;
+ item->color = _talkTextFontColor;
//debug(0, "## _talkTextMaxWidth = %d", _talkTextMaxWidth);
@@ -680,53 +680,53 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
maxWidth = 624 - ABS(x - 320) * 2;
while (1) {
- if (*textData == 0x0A) {
+ if (*textData == 0x0A) {
x = CLIP<int16>(textData[3], 120, _talkTextMaxWidth);
y = CLIP<int16>(READ_LE_UINT16(&textData[1]), 4, _vm->_cameraHeight - 16);
maxWidth = 624 - ABS(x - 320) * 2;
textData += 4;
} else if (*textData == 0x14) {
- item->color = textData[1];
- textData += 2;
+ item->color = textData[1];
+ textData += 2;
} else if (*textData == 0x19) {
- durationModifier = textData[1];
- textData += 2;
+ durationModifier = textData[1];
+ textData += 2;
} else if (*textData < 0x0A) {
- item->fontNum = textData[1];
- textData += 2;
+ item->fontNum = textData[1];
+ textData += 2;
} else
- break;
+ break;
}
- item->slotIndex = slotIndex;
- item->slotOffset = textData - _vm->_script->getSlotData(slotIndex);
-
- width = 0;
- length = 0;
-
- item->rectCount = 0;
-
- Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
+ item->slotIndex = slotIndex;
+ item->slotOffset = textData - _vm->_script->getSlotData(slotIndex);
+
+ width = 0;
+ length = 0;
+
+ item->rectCount = 0;
+
+ Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
int16 wordLength, wordWidth;
- while (*textData < 0xF0) {
+ while (*textData < 0xF0) {
if (*textData == 0x1E) {
- textData++;
- addTalkTextRect(font, x, y, length, width, item);
- // CHECKME?
+ textData++;
+ addTalkTextRect(font, x, y, length, width, item);
+ // CHECKME?
width = 0;
length = 0;
} else {
- wordLength = 0;
- wordWidth = 0;
- while (*textData >= 0x20 && *textData < 0xF0) {
- byte ch = *textData++;
- wordLength++;
- if (ch == 0x20) {
- wordWidth += font.getWidth();
- break;
+ wordLength = 0;
+ wordWidth = 0;
+ while (*textData >= 0x20 && *textData < 0xF0) {
+ byte ch = *textData++;
+ wordLength++;
+ if (ch == 0x20) {
+ wordWidth += font.getWidth();
+ break;
} else {
- wordWidth += font.getCharWidth(ch) + font.getSpacing() - 1;
+ wordWidth += font.getCharWidth(ch) + font.getSpacing() - 1;
}
}
@@ -751,7 +751,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
int16 textDurationMultiplier = item->duration + 8;
// TODO: Check sound/text flags
if (*textData == 0xFE) {
- //textDurationMultiplier += 100;
+ //textDurationMultiplier += 100;
}
item->duration = 4 * textDurationMultiplier * durationModifier;
@@ -760,14 +760,14 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item) {
if (width > 0) {
- TextRect *textRect = &item->rects[item->rectCount];
- width = width + 1 - font.getSpacing();
- textRect->width = width;
- item->duration += length;
- textRect->length = length;
- textRect->y = y;
- textRect->x = CLIP<int16>(x - width / 2, 0, 640);
- item->rectCount++;
+ TextRect *textRect = &item->rects[item->rectCount];
+ width = width + 1 - font.getSpacing();
+ textRect->width = width;
+ item->duration += length;
+ textRect->length = length;
+ textRect->y = y;
+ textRect->x = CLIP<int16>(x - width / 2, 0, 640);
+ item->rectCount++;
}
y += font.getHeight() - 1;
@@ -782,25 +782,25 @@ void Screen::drawTalkTextItems() {
TalkTextItem *item = &_talkTextItems[i];
byte *text = _vm->_script->getSlotData(item->slotIndex) + item->slotOffset;
- if (item->fontNum == -1 || item->duration == 0)
- continue;
+ if (item->fontNum == -1 || item->duration == 0)
+ continue;
item->duration -= _vm->_counter01;
if (item->duration < 0)
- item->duration = 0;
-
- Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
+ item->duration = 0;
+
+ Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
for (byte j = 0; j < item->rectCount; j++) {
int16 x = item->rects[j].x;
for (byte pos = 0; pos < item->rects[j].length; pos++) {
- byte ch = *text++;
- if (ch < 0x20)
- continue;
- if (ch == 0x20) {
- x += font.getWidth();
+ byte ch = *text++;
+ if (ch < 0x20)
+ continue;
+ if (ch == 0x20) {
+ x += font.getWidth();
} else {
- drawChar2(font, _frontScreen, x, item->rects[j].y, ch, item->color);
- x += font.getCharWidth(ch) + font.getSpacing() - 1;
+ drawChar2(font, _frontScreen, x, item->rects[j].y, ch, item->color);
+ x += font.getCharWidth(ch) + font.getSpacing() - 1;
}
}
}
@@ -822,30 +822,30 @@ void Screen::printText(byte *textData) {
// Really strange stuff.
for (int i = 30; i >= 0; i--) {
- if (textData[i] >= 0xF0)
- break;
+ if (textData[i] >= 0xF0)
+ break;
if (i == 0)
- return;
+ return;
}
do {
- if (*textData == 0x0A) {
- // Set text position
- y = textData[1];
- x = READ_LE_UINT32(textData + 2);
- textData += 4;
+ if (*textData == 0x0A) {
+ // Set text position
+ y = textData[1];
+ x = READ_LE_UINT32(textData + 2);
+ textData += 4;
} else if (*textData == 0x0B) {
- // Inc text position
- y += textData[1]; // CHECKME: Maybe these are signed?
- x += textData[2];
- textData += 3;
+ // Inc text position
+ y += textData[1]; // CHECKME: Maybe these are signed?
+ x += textData[2];
+ textData += 3;
} else {
byte *destString = _tempString;
int width = 0;
_tempStringLen1 = 0;
- preprocessText(_fontResIndexArray[1], 640, width, textData, destString, _tempStringLen2);
- drawString(x - width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1]);
+ preprocessText(_fontResIndexArray[1], 640, width, textData, destString, _tempStringLen2);
+ drawString(x - width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1]);
}
} while (*textData != 0xFF);
@@ -858,17 +858,17 @@ void Screen::preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&
len = 0;
while (*sourceString >= 0x20 && *sourceString < 0xF0) {
- byte ch = *sourceString;
+ byte ch = *sourceString;
byte charWidth;
- if (ch <= 0x20)
- charWidth = font.getWidth();
+ if (ch <= 0x20)
+ charWidth = font.getWidth();
else
charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
if (width + charWidth >= maxWidth)
- break;
+ break;
len++;
width += charWidth;
- *destString++ = *sourceString++;
+ *destString++ = *sourceString++;
}
}
@@ -884,16 +884,16 @@ void Screen::drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint
int16 yadd = 1;
for (byte pos = 0; pos < len; pos++) {
- if (pos == _tempStringLen1) {
- color = fontColor2;
+ if (pos == _tempStringLen1) {
+ color = fontColor2;
}
- byte ch = *text++;
- if (ch <= 0x20) {
- x += font.getWidth();
+ byte ch = *text++;
+ if (ch <= 0x20) {
+ x += font.getWidth();
} else {
- drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color);
- x += font.getCharWidth(ch) + font.getSpacing() - 1;
- yadd = -yadd;
+ drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color);
+ x += font.getCharWidth(ch) + font.getSpacing() - 1;
+ yadd = -yadd;
}
}
@@ -912,19 +912,19 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
charHeight = font.getHeight() - 2;
charData = font.getCharData(ch);
- while (charHeight--) {
- byte lineWidth = charWidth;
- while (lineWidth > 0) {
- byte count = charData[0] & 0x0F;
- byte flags = charData[0] & 0xF0;
+ while (charHeight--) {
+ byte lineWidth = charWidth;
+ while (lineWidth > 0) {
+ byte count = charData[0] & 0x0F;
+ byte flags = charData[0] & 0xF0;
charData++;
lineWidth -= count;
if (!(flags & 0x80) && (flags & 0x10)) {
- memset(dest, color, count);
+ memset(dest, color, count);
}
dest += count;
}
- dest += 640 - charWidth;
+ dest += 640 - charWidth;
}
}
@@ -940,25 +940,25 @@ void Screen::drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch,
charHeight = font.getHeight() - 2;
charData = font.getCharData(ch);
- while (charHeight--) {
- byte lineWidth = charWidth;
- while (lineWidth > 0) {
- byte count = charData[0] & 0x0F;
- byte flags = charData[0] & 0xF0;
+ while (charHeight--) {
+ byte lineWidth = charWidth;
+ while (lineWidth > 0) {
+ byte count = charData[0] & 0x0F;
+ byte flags = charData[0] & 0xF0;
charData++;
lineWidth -= count;
if ((flags & 0x80) == 0) {
if ((flags & 0x10) == 0) {
- memset(dest, 0, count);
- } else {
- memset(dest, color, count);
+ memset(dest, 0, count);
+ } else {
+ memset(dest, color, count);
}
}
dest += count;
}
- dest += 640 - charWidth;
+ dest += 640 - charWidth;
}
}
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 352eeae..156e4e1 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -122,16 +122,16 @@ enum SpriteReaderStatus {
class SpriteFilter {
public:
- SpriteFilter(SpriteDrawItem *sprite) : _sprite(sprite) {
+ SpriteFilter(SpriteDrawItem *sprite) : _sprite(sprite) {
}
virtual SpriteReaderStatus readPacket(PixelPacket &packet) = 0;
protected:
- SpriteDrawItem *_sprite;
+ SpriteDrawItem *_sprite;
};
class SpriteReader : public SpriteFilter {
public:
- SpriteReader(byte *source, SpriteDrawItem *sprite) : SpriteFilter(sprite), _source(source) {
+ SpriteReader(byte *source, SpriteDrawItem *sprite) : SpriteFilter(sprite), _source(source) {
_curWidth = _sprite->origWidth;
_curHeight = _sprite->origHeight;
}
@@ -146,23 +146,23 @@ public:
}
_curWidth -= packet.count;
if (_curWidth <= 0) {
- _curHeight--;
- if (_curHeight == 0) {
- return kSrsEndOfSprite;
+ _curHeight--;
+ if (_curHeight == 0) {
+ return kSrsEndOfSprite;
} else {
- _curWidth = _sprite->origWidth;
- return kSrsEndOfLine;
+ _curWidth = _sprite->origWidth;
+ return kSrsEndOfLine;
}
} else {
- return kSrsPixelsLeft;
+ return kSrsPixelsLeft;
}
}
byte *getSource() {
- return _source;
+ return _source;
}
void setSource(byte *source) {
- _source = source;
- _curHeight++;
+ _source = source;
+ _curHeight++;
}
protected:
byte *_source;
@@ -171,49 +171,49 @@ protected:
class SpriteFilterScaleDown : public SpriteFilter {
public:
- SpriteFilterScaleDown(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ SpriteFilterScaleDown(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
_height = _sprite->height;
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
_scalerStatus = 0;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
- SpriteReaderStatus status;
+ SpriteReaderStatus status;
if (_scalerStatus == 0) {
_xerror = _sprite->xdelta;
_yerror -= 100;
while (_yerror <= 0) {
- do {
- status = _reader->readPacket(packet);
+ do {
+ status = _reader->readPacket(packet);
} while (status == kSrsPixelsLeft);
_yerror += _sprite->ydelta - 100;
}
if (status == kSrsEndOfSprite)
- return kSrsEndOfSprite;
- _scalerStatus = 1;
+ return kSrsEndOfSprite;
+ _scalerStatus = 1;
}
if (_scalerStatus == 1) {
- status = _reader->readPacket(packet);
- byte updcount = packet.count;
- while (updcount--) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
_xerror -= 100;
if (_xerror <= 0) {
- if (packet.count > 0)
- packet.count--;
- _xerror += _sprite->xdelta;
+ if (packet.count > 0)
+ packet.count--;
+ _xerror += _sprite->xdelta;
}
}
if (status == kSrsEndOfLine) {
if (--_height == 0)
return kSrsEndOfSprite;
- _scalerStatus = 0;
- return kSrsEndOfLine;
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
}
}
return kSrsPixelsLeft;
}
protected:
- SpriteReader *_reader;
+ SpriteReader *_reader;
int16 _xerror, _yerror;
int16 _height;
int16 _origHeight;
@@ -222,46 +222,46 @@ protected:
class SpriteFilterScaleUp : public SpriteFilter {
public:
- SpriteFilterScaleUp(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ SpriteFilterScaleUp(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
_height = _sprite->height;
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
_scalerStatus = 0;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
- SpriteReaderStatus status;
- if (_scalerStatus == 0) {
+ SpriteReaderStatus status;
+ if (_scalerStatus == 0) {
_xerror = _sprite->xdelta;
_sourcep = _reader->getSource();
- _scalerStatus = 1;
+ _scalerStatus = 1;
}
if (_scalerStatus == 1) {
- status = _reader->readPacket(packet);
- byte updcount = packet.count;
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
while (updcount--) {
- _xerror -= 100;
- if (_xerror <= 0) {
- packet.count++;
- _xerror += _sprite->xdelta;
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ packet.count++;
+ _xerror += _sprite->xdelta;
}
}
if (status == kSrsEndOfLine) {
if (--_height == 0)
return kSrsEndOfSprite;
- _yerror -= 100;
+ _yerror -= 100;
if (_yerror <= 0) {
- _reader->setSource(_sourcep);
+ _reader->setSource(_sourcep);
_yerror += _sprite->ydelta + 100;
}
- _scalerStatus = 0;
- return kSrsEndOfLine;
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
}
}
return kSrsPixelsLeft;
}
protected:
- SpriteReader *_reader;
- byte *_sourcep;
+ SpriteReader *_reader;
+ byte *_sourcep;
int16 _xerror, _yerror;
int16 _height;
int16 _origHeight;
@@ -271,7 +271,7 @@ protected:
//*END*TEST*CODE**********************************************************************************************
struct TextRect {
- int16 x, y;
+ int16 x, y;
int16 width, length;
};
@@ -306,8 +306,8 @@ public:
void clearSprites();
// Sprite drawing
- void drawSprite(SpriteDrawItem *sprite);
- void drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite);
+ void drawSprite(SpriteDrawItem *sprite);
+ void drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite);
void drawSprites();
// Verb line
@@ -331,12 +331,12 @@ public:
public:
struct VerbLineItem {
- int16 slotIndex;
+ int16 slotIndex;
int16 slotOffset;
};
struct Rect {
- int16 x, y, width, height;
+ int16 x, y, width, height;
};
ToltecsEngine *_vm;
@@ -345,11 +345,11 @@ public:
Common::List<SpriteDrawItem> _spriteDrawList;
- uint _fontResIndexArray[10];
- byte _fontColor1, _fontColor2;
-
- byte _tempString[100];
- byte _tempStringLen1, _tempStringLen2;
+ uint _fontResIndexArray[10];
+ byte _fontColor1, _fontColor2;
+
+ byte _tempString[100];
+ byte _tempStringLen1, _tempStringLen2;
// Screen shaking
bool _shakeActive;
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 5d7e55b..73c78e8 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -60,7 +60,7 @@ ScriptInterpreter::~ScriptInterpreter() {
void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
if (_slots[slotIndex].data) {
- delete[] _slots[slotIndex].data;
+ delete[] _slots[slotIndex].data;
}
_slots[slotIndex].resIndex = resIndex;
@@ -355,8 +355,8 @@ void ScriptInterpreter::execOpcode(byte opcode) {
_switchStack1 = true;
break;
case 49:
- ofs = readByte();
- debug(0, "49, len = %d", ofs);
+ ofs = readByte();
+ debug(0, "49, len = %d", ofs);
_code += ofs;
break;
case 50:
@@ -1047,8 +1047,8 @@ int16 ScriptInterpreter::getGameVar(uint variable) {
value = _vm->_sceneResIndex;
break;
case 19:
- value = _vm->_cameraTop;
- break;
+ value = _vm->_cameraTop;
+ break;
case 20:
value = _vm->_sceneHeight;
break;
@@ -1121,8 +1121,8 @@ void ScriptInterpreter::setGameVar(uint variable, int16 value) {
_vm->_sceneResIndex = value;
break;
case 19:
- _vm->_cameraTop = value;
- break;
+ _vm->_cameraTop = value;
+ break;
case 20:
_vm->_sceneHeight = value;
break;
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index 6f2d5b7..7b91105 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -48,19 +48,19 @@ const int kMaxScriptSlots = 50;
class ScriptInterpreter {
public:
- ScriptInterpreter(ToltecsEngine *vm);
- ~ScriptInterpreter();
-
+ ScriptInterpreter(ToltecsEngine *vm);
+ ~ScriptInterpreter();
+
void loadScript(uint resIndex, uint slotIndex);
void runScript(uint slotIndex);
-
+
byte *getSlotData(int slotIndex) const { return _slots[slotIndex].data; }
protected:
enum VarType {
- vtByte,
- vtWord
+ vtByte,
+ vtWord
};
struct ScriptRegs {
@@ -76,15 +76,15 @@ protected:
};
struct ScriptSlot {
- byte *data;
- int32 size;
- uint resIndex;
+ byte *data;
+ int32 size;
+ uint resIndex;
};
- ToltecsEngine *_vm;
-
- byte *_stack;
-
+ ToltecsEngine *_vm;
+
+ byte *_stack;
+
byte *_code, *_subCode;
byte *_localData;
bool _switchStack1, _switchStack2, _switchStack3;
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 6c4796f..351bf82 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -43,7 +43,7 @@
namespace Toltecs {
SegmentMap::SegmentMap(ToltecsEngine *vm) : _vm(vm) {
- _maskRectData = new byte[32768];
+ _maskRectData = new byte[32768];
}
SegmentMap::~SegmentMap() {
@@ -54,9 +54,9 @@ void SegmentMap::load(byte *source) {
// TODO: Use MemoryReadStream
- _maskRects.clear();
- _pathRects.clear();
- _infoRects.clear();
+ _maskRects.clear();
+ _pathRects.clear();
+ _infoRects.clear();
// Load mask rects
uint16 maskSize = READ_LE_UINT16(source);
@@ -85,7 +85,7 @@ void SegmentMap::load(byte *source) {
}
memcpy(_maskRectData, source, maskSize - maskRectDataSize);
- source += maskSize - maskRectDataSize;
+ source += maskSize - maskRectDataSize;
// Load path rects
@@ -213,65 +213,65 @@ int SegmentMap::findNextPathRect(int srcRectIndex) {
for (uint rectIndex = 0; rectIndex < _pathRects.size(); ++rectIndex) {
- if ( y1 == _pathRects[rectIndex].height + _pathRects[rectIndex].y && x1 < _pathRects[rectIndex].x + _pathRects[rectIndex].width && x2 > _pathRects[rectIndex].x ) {
+ if (y1 == _pathRects[rectIndex].height + _pathRects[rectIndex].y && x1 < _pathRects[rectIndex].x + _pathRects[rectIndex].width && x2 > _pathRects[rectIndex].x) {
ny = y1;
LABEL_28:
- if ( x1 >= _pathRects[rectIndex].x ) {
+ if (x1 >= _pathRects[rectIndex].x) {
nx1 = x1;
} else {
nx1 = _pathRects[rectIndex].x;
}
- if ( x2 <= _pathRects[rectIndex].x + _pathRects[rectIndex].width ) {
+ if (x2 <= _pathRects[rectIndex].x + _pathRects[rectIndex].width) {
nx2 = x2 - 1;
} else {
nx2 = _pathRects[rectIndex].x + _pathRects[rectIndex].width - 1;
}
- if ( ABS(_x - nx1) >= ABS(_x - nx2) ) {
+ if (ABS(_x - nx1) >= ABS(_x - nx2)) {
nx3 = nx2 - 1;
} else {
nx3 = nx1;
}
- if ( _x > nx1 && _x < nx2 ) {
+ if (_x > nx1 && _x < nx2) {
nx3 = _x;
}
goto LABEL_55;
}
- if ( y2 == _pathRects[rectIndex].y && x1 < _pathRects[rectIndex].x + _pathRects[rectIndex].width && x2 > _pathRects[rectIndex].x ) {
+ if (y2 == _pathRects[rectIndex].y && x1 < _pathRects[rectIndex].x + _pathRects[rectIndex].width && x2 > _pathRects[rectIndex].x) {
ny = y2 - 1;
goto LABEL_28;
}
- if ( x1 == _pathRects[rectIndex].x + _pathRects[rectIndex].width && y1 < _pathRects[rectIndex].y + _pathRects[rectIndex].height && y2 > _pathRects[rectIndex].y ) {
+ if (x1 == _pathRects[rectIndex].x + _pathRects[rectIndex].width && y1 < _pathRects[rectIndex].y + _pathRects[rectIndex].height && y2 > _pathRects[rectIndex].y) {
nx3 = x1;
} else {
- if ( x2 != _pathRects[rectIndex].x || y1 >= _pathRects[rectIndex].y + _pathRects[rectIndex].height || y2 <= _pathRects[rectIndex].y )
+ if (x2 != _pathRects[rectIndex].x || y1 >= _pathRects[rectIndex].y + _pathRects[rectIndex].height || y2 <= _pathRects[rectIndex].y)
continue;
nx3 = x2 - 1;
}
- if ( y1 >= _pathRects[rectIndex].y ) {
+ if (y1 >= _pathRects[rectIndex].y) {
ny3 = y1;
} else {
ny3 = _pathRects[rectIndex].y;
}
- if ( y2 <= _pathRects[rectIndex].y + _pathRects[rectIndex].height ) {
+ if (y2 <= _pathRects[rectIndex].y + _pathRects[rectIndex].height) {
ny2 = y2 - 1;
} else {
ny2 = _pathRects[rectIndex].y + _pathRects[rectIndex].height - 1;
}
- if ( ABS(_y - ny3) >= ABS(_y - ny2) ) {
+ if (ABS(_y - ny3) >= ABS(_y - ny2)) {
ny = ny2 - 1;
} else {
ny = ny3;
}
- if ( _y > ny3 && _y < ny2 ) {
+ if (_y > ny3 && _y < ny2) {
ny = _y;
}
LABEL_55:
distance = ABS(_x - nx3) + ABS(_y - ny);
v28 = 0;
- while ( v28 < _rectIndexArray2Count ) {
- if ( rectIndex == _rectIndexArray2[v28] ) {
+ while (v28 < _rectIndexArray2Count) {
+ if (rectIndex == _rectIndexArray2[v28]) {
distance = minDistance;
break;
}
@@ -279,15 +279,15 @@ LABEL_55:
}
v28 = 0;
- while ( v28 < _rectIndexArray1Count ) {
- if ( rectIndex == _rectIndexArray1[v28] ) {
+ while (v28 < _rectIndexArray1Count) {
+ if (rectIndex == _rectIndexArray1[v28]) {
distance = minDistance;
break;
}
++v28;
}
- if ( distance < minDistance ) {
+ if (distance < minDistance) {
result = rectIndex;
minDistance = distance;
_pointsArray[_pointsCount].y = ny;
@@ -321,7 +321,7 @@ void SegmentMap::findPath(int16 *pointsArray, int destX, int destY, int x, int y
debug(0, "SegmentMap::findPath(fromX: %d; fromY: %d; toX: %d; toY: %d)", x, y, destX, destY);
sourceRectIndex = findPathRectAtPoint(x, y);
- if ( sourceRectIndex == -1 ) {
+ if (sourceRectIndex == -1) {
adjustPathPoint(x, y);
x = _x;
y = _y;
@@ -337,22 +337,22 @@ void SegmentMap::findPath(int16 *pointsArray, int destX, int destY, int x, int y
adjustPathPoint(_x, _y);
destRectIndex = findPathRectAtPoint(_x, _y);
sourceRectIndex = findPathRectAtPoint(x, y);
- if ( sourceRectIndex != -1 ) {
- if ( destRectIndex != sourceRectIndex ) {
- while ( 1 ) {
+ if (sourceRectIndex != -1) {
+ if (destRectIndex != sourceRectIndex) {
+ while (1) {
do {
_rectIndexArray2[_rectIndexArray2Count++] = sourceRectIndex;
sourceRectIndex = findNextPathRect(sourceRectIndex);
_pointsCount++;
- } while ( sourceRectIndex != -1 && sourceRectIndex != destRectIndex );
- if ( sourceRectIndex != -1 && sourceRectIndex == destRectIndex )
+ } while (sourceRectIndex != -1 && sourceRectIndex != destRectIndex);
+ if (sourceRectIndex != -1 && sourceRectIndex == destRectIndex)
break;
_rectIndexArray1[_rectIndexArray1Count++] = _rectIndexArray2[--_rectIndexArray2Count];
_pointsCount -= 2;
sourceRectIndex = _rectIndexArray2[--_rectIndexArray2Count];
}
sourceRectIndex = 0;
- while ( sourceRectIndex < _pointsCount ) {
+ while (sourceRectIndex < _pointsCount) {
pointsArray[pointsCount++] = _pointsArray[sourceRectIndex].y;
pointsArray[pointsCount++] = _pointsArray[sourceRectIndex].x;
index++;
@@ -375,9 +375,9 @@ void SegmentMap::findPath(int16 *pointsArray, int destX, int destY, int x, int y
ld.pitch = _vm->_sceneWidth;
ld.surf = _vm->_screen->_backScreen;
for (int16 i = 0; i < pointsArray[1] * 2; i+=2) {
- debug(0, "x = %d; y = %d", pointsArray[3+i], pointsArray[2+i]);
- Graphics::drawLine(sx, sy, pointsArray[3+i], pointsArray[2+i], 0xFF, plotProc, &ld);
- sx = pointsArray[3+i];
+ debug(0, "x = %d; y = %d", pointsArray[3+i], pointsArray[2+i]);
+ Graphics::drawLine(sx, sy, pointsArray[3+i], pointsArray[2+i], 0xFF, plotProc, &ld);
+ sx = pointsArray[3+i];
sy = pointsArray[2+i];
}
*/
@@ -393,7 +393,7 @@ int8 SegmentMap::getScalingAtPoint(int16 x, int16 y) {
char topScaling = (char)_infoRects[i].b;
char bottomScaling = (char)_infoRects[i].c;
if (y - _infoRects[i].y > 0) {
- scaling = (ABS(y - _infoRects[i].y) * (bottomScaling - topScaling) / _infoRects[i].height) + topScaling;
+ scaling = (ABS(y - _infoRects[i].y) * (bottomScaling - topScaling) / _infoRects[i].height) + topScaling;
}
}
}
@@ -422,23 +422,23 @@ void SegmentMap::restoreMasksBySprite(SpriteDrawItem *sprite) {
for (uint i = 0; i < _maskRects.size(); i++) {
#if 0
- if ( *(__int16 *)((char *)&spriteDrawList[0].y2 + v5) <= (unsigned __int16)v3->ybottom )
- {
- if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].height + v5)
- + *(__int16 *)((char *)&spriteDrawList[0].y + v5)) > v3->y )
- {
- if ( (unsigned __int16)(v3->height + v3->y) > *(__int16 *)((char *)&spriteDrawList[0].y + v5) )
- {
- if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].width + v5)
- + *(__int16 *)((char *)&spriteDrawList[0].x + v5)) > v3->x )
- {
- if ( (unsigned __int16)(v3->width + v3->x) > *(__int16 *)((char *)&spriteDrawList[0].x + v5) )
- {
+ if ( *(__int16 *)((char *)&spriteDrawList[0].y2 + v5) <= (unsigned __int16)v3->ybottom )
+ {
+ if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].height + v5)
+ + *(__int16 *)((char *)&spriteDrawList[0].y + v5)) > v3->y )
+ {
+ if ( (unsigned __int16)(v3->height + v3->y) > *(__int16 *)((char *)&spriteDrawList[0].y + v5) )
+ {
+ if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].width + v5)
+ + *(__int16 *)((char *)&spriteDrawList[0].x + v5)) > v3->x )
+ {
+ if ( (unsigned __int16)(v3->width + v3->x) > *(__int16 *)((char *)&spriteDrawList[0].x + v5) )
+ {
#endif
- if (sprite->ybottom <= _maskRects[i].ybottom) {
- restoreMask(i);
+ if (sprite->ybottom <= _maskRects[i].ybottom) {
+ restoreMask(i);
}
}
@@ -456,63 +456,63 @@ void SegmentMap::restoreMask(int16 index) {
int16 height = maskRect->height;
byte *mask = _maskRectData + maskRect->maskOffset;
- debug(0, "SegmentMap::restoreMask() screenX = %d; screenY = %d; maskX = %d; maskY = %d",
+ debug(0, "SegmentMap::restoreMask() screenX = %d; screenY = %d; maskX = %d; maskY = %d",
x, y, maskRect->x, maskRect->y);
// Not on screen, skip
if (x + width < 0 || y + height < 0 || x >= 640 || y >= _vm->_cameraHeight)
- return;
+ return;
if (x < 0) {
- skipX = -x;
- x = 0;
+ skipX = -x;
+ x = 0;
}
if (y < 0) {
- int16 skipY = -y;
+ int16 skipY = -y;
for (int16 h = 0; h < skipY; h++) {
- int16 w = width;
- while (w > 0) {
+ int16 w = width;
+ while (w > 0) {
w -= (*mask++) & 0x7F;
}
}
- y = 0;
- height -= skipY;
- maskY += skipY;
+ y = 0;
+ height -= skipY;
+ maskY += skipY;
}
if (x + width >= 640) {
- width -= x + width - 640;
+ width -= x + width - 640;
}
if (y + height >= _vm->_cameraHeight) {
- height -= y + height - _vm->_cameraHeight;
+ height -= y + height - _vm->_cameraHeight;
}
byte *backScreen = _vm->_screen->_backScreen + maskX + (maskY * _vm->_sceneWidth);
byte *frontScreen = _vm->_screen->_frontScreen + x + (y * 640);
for (int16 h = 0; h < height; h++) {
- byte *src = backScreen;
- byte *dst = frontScreen;
- byte maskLine[640], *maskLineP = maskLine;
-
- int16 w = width;
- while (w > 0) {
- byte m = *mask++;
- byte count = m & 0x7F;
- if (m & 0x80)
+ byte *src = backScreen;
+ byte *dst = frontScreen;
+ byte maskLine[640], *maskLineP = maskLine;
+
+ int16 w = width;
+ while (w > 0) {
+ byte m = *mask++;
+ byte count = m & 0x7F;
+ if (m & 0x80)
memset(maskLineP, 1, count);
else
- memset(maskLineP, 0, count);
+ memset(maskLineP, 0, count);
maskLineP += count;
w -= count;
}
src += skipX;
for (int16 c = skipX; c < width; c++) {
- if (maskLine[c] == 1)
- *dst = *src;
+ if (maskLine[c] == 1)
+ *dst = *src;
dst++;
src++;
}
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index 0ebb3f4..7ec7cfb 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -58,17 +58,17 @@ struct ScriptWalk {
class SegmentMap {
public:
- SegmentMap(ToltecsEngine *vm);
- ~SegmentMap();
+ SegmentMap(ToltecsEngine *vm);
+ ~SegmentMap();
void load(byte *source);
-
- int findPathRectAtPoint(int x, int y);
- void adjustPathPoint(int x, int y);
-
- void findPath(int16 *pointsArray, int destX, int destY, int x, int y);
-
- int8 getScalingAtPoint(int16 x, int16 y);
+
+ int findPathRectAtPoint(int x, int y);
+ void adjustPathPoint(int x, int y);
+
+ void findPath(int16 *pointsArray, int destX, int destY, int x, int y);
+
+ int8 getScalingAtPoint(int16 x, int16 y);
void getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byte &g, byte &b);
void restoreMasksBySprite(SpriteDrawItem *sprite);
@@ -99,20 +99,20 @@ public: // for debugging purposes
};
struct PathPoint {
- int16 y, x;
+ int16 y, x;
};
typedef Common::Array<SegmapMaskRect> SegmapMaskRectArray;
typedef Common::Array<SegmapPathRect> SegmapPathRectArray;
typedef Common::Array<SegmapInfoRect> SegmapInfoRectArray;
- ToltecsEngine *_vm;
-
- SegmapMaskRectArray _maskRects;
- byte *_maskRectData;
+ ToltecsEngine *_vm;
- SegmapPathRectArray _pathRects;
- SegmapInfoRectArray _infoRects;
+ SegmapMaskRectArray _maskRects;
+ byte *_maskRectData;
+
+ SegmapPathRectArray _pathRects;
+ SegmapInfoRectArray _infoRects;
int _rectIndexArray1[1000];
uint _rectIndexArray1Count;
@@ -123,10 +123,10 @@ public: // for debugging purposes
PathPoint _pointsArray[1000];
int16 _pointsCount;
- int _x, _y;
-
- int findNextPathRect(int srcRectIndex);
-
+ int _x, _y;
+
+ int findNextPathRect(int srcRectIndex);
+
};
} // End of namespace Toltecs
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 78f3e23..73de88f 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -86,8 +86,8 @@ int ToltecsEngine::init() {
int ToltecsEngine::go() {
- _system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true);
-
+ _system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true);
+
_quitGame = false;
_counter01 = 0;
_counter02 = 0;
@@ -108,7 +108,7 @@ int ToltecsEngine::go() {
_doSpeech = true;
_doText = true;
- _walkSpeedY = 5;
+ _walkSpeedY = 5;
_walkSpeedX = 1;
_arc = new ArchiveReader();
@@ -124,8 +124,8 @@ int ToltecsEngine::go() {
_segmap = new SegmentMap(this);
_input = new Input(this);
- _system->showMouse(true);
-
+ _system->showMouse(true);
+
#if 1
_script->loadScript(0, 0);
@@ -151,7 +151,7 @@ void ToltecsEngine::loadScene(uint resIndex) {
byte *scene = _res->load(resIndex);
uint32 imageSize = READ_LE_UINT32(scene);
- _sceneResIndex = resIndex;
+ _sceneResIndex = resIndex;
_sceneHeight = READ_LE_UINT16(scene + 4);
_sceneWidth = READ_LE_UINT16(scene + 6);
@@ -192,10 +192,10 @@ void ToltecsEngine::updateScreen() {
srcp += _sceneWidth;
}
- _screen->drawSprites();
- _screen->clearSprites();
+ _screen->drawSprites();
+ _screen->clearSprites();
- _screen->drawTalkTextItems();
+ _screen->drawTalkTextItems();
_system->copyRectToScreen((const byte *)_screen->_frontScreen, 640, 0, 0, 640, 400);
_system->updateScreen();
@@ -208,10 +208,10 @@ void ToltecsEngine::setCamera(int16 x, int16 y) {
// TODO font_sub_4B5BB()
if (x > _sceneWidth)
- x = _sceneWidth;
+ x = _sceneWidth;
if (y > _sceneHeight - _cameraHeight)
- y = _sceneHeight - _cameraHeight;
+ y = _sceneHeight - _cameraHeight;
// TODO DirtyRect clearing stuff
@@ -321,28 +321,28 @@ void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
while (*scanData < 0xF0) {
- if (*scanData == 0x19) {
- scanData++;
+ if (*scanData == 0x19) {
+ scanData++;
} else if (*scanData == 0x14) {
- scanData++;
+ scanData++;
} else if (*scanData == 0x0A) {
- scanData += 4;
+ scanData += 4;
} else if (*scanData < 0x0A) {
- scanData++;
+ scanData++;
}
- scanData++;
+ scanData++;
}
if (*scanData == 0xFE) {
- if (_doSpeech) {
- int16 resIndex = READ_LE_UINT16(scanData + 1);
- debug(0, "ToltecsEngine::talk() playSound(resIndex: %d)", resIndex);
+ if (_doSpeech) {
+ int16 resIndex = READ_LE_UINT16(scanData + 1);
+ debug(0, "ToltecsEngine::talk() playSound(resIndex: %d)", resIndex);
}
if (_doText) {
- _screen->updateTalkText(slotIndex, slotOffset);
+ _screen->updateTalkText(slotIndex, slotOffset);
} else {
- // TODO: font_sub_4B3E2
+ // TODO: font_sub_4B3E2
}
} else {
_screen->updateTalkText(slotIndex, slotOffset);
@@ -358,9 +358,9 @@ void ToltecsEngine::playText(int16 slotIndex, int16 slotOffset) {
Common::String str;
while (*textData < 0xF0) {
- if (*textData >= 32)
- str += (char)*textData;
- textData++;
+ if (*textData >= 32)
+ str += (char)*textData;
+ textData++;
}
debug(0, "ToltecsEngine::playText() [%s]", str.c_str());
@@ -387,21 +387,21 @@ void ToltecsEngine::walk(byte *walkData) {
walkInfo.scaling = -_segmap->getScalingAtPoint(walkInfo.x, walkInfo.y);
if (walkInfo.y1 < walkInfo.y2)
- ystep = -1;
+ ystep = -1;
else
ystep = 1;
ydelta = ABS(walkInfo.y1 - walkInfo.y2) * _walkSpeedY;
if (walkInfo.x1 < walkInfo.x2)
- xstep = -1;
+ xstep = -1;
else
xstep = 1;
xdelta = ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX;
- debug(0, "ToltecsEngine::walk() xdelta = %d; ydelta = %d", xdelta, ydelta);
+ debug(0, "ToltecsEngine::walk() xdelta = %d; ydelta = %d", xdelta, ydelta);
if (xdelta > ydelta)
- SWAP(xdelta, ydelta);
+ SWAP(xdelta, ydelta);
v8 = 100 * xdelta;
if (v8 != 0) {
@@ -414,8 +414,8 @@ void ToltecsEngine::walk(byte *walkData) {
}
if (ydelta > ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX) {
- v10 = 100 - walkInfo.scaling;
- v11 = v8;
+ v10 = 100 - walkInfo.scaling;
+ v11 = v8;
} else {
v10 = v8;
v11 = 100 - walkInfo.scaling;
@@ -459,18 +459,18 @@ int16 ToltecsEngine::findRectAtPoint(byte *rectData, int16 x, int16 y, int16 ind
rectData += index * itemSize;
while (1) {
- int16 rectY = READ_LE_UINT16(rectData);
- if (rectY == -10)
- break;
- int16 rectX = READ_LE_UINT16(rectData + 2);
- int16 rectH = READ_LE_UINT16(rectData + 4);
- int16 rectW = READ_LE_UINT16(rectData + 6);
-
- debug(0, "x = %d; y = %d; x1 = %d; y2 = %d; w = %d; h = %d",
- x, y, rectX, rectY, rectW, rectH);
-
- if (x >= rectX && x <= rectX + rectW && y >= rectY && y <= rectY + rectH) {
- return index;
+ int16 rectY = READ_LE_UINT16(rectData);
+ if (rectY == -10)
+ break;
+ int16 rectX = READ_LE_UINT16(rectData + 2);
+ int16 rectH = READ_LE_UINT16(rectData + 4);
+ int16 rectW = READ_LE_UINT16(rectData + 6);
+
+ debug(0, "x = %d; y = %d; x1 = %d; y2 = %d; w = %d; h = %d",
+ x, y, rectX, rectY, rectW, rectH);
+
+ if (x >= rectX && x <= rectX + rectW && y >= rectY && y <= rectY + rectH) {
+ return index;
}
index++;
rectData += itemSize;
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 47c7a94..1d5a394 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -79,7 +79,7 @@ public:
void updateScreen();
- void setCamera(int16 x, int16 y);
+ void setCamera(int16 x, int16 y);
void setCameraTop(int16 top);
void scrollCameraUp(int16 delta);
void scrollCameraDown(int16 delta);
Commit: 0c3f2ab5d51fe32792896e16c28dfeec97474010
https://github.com/scummvm/scummvm/commit/0c3f2ab5d51fe32792896e16c28dfeec97474010
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Some cleanup of the pathfinding code.
Changed paths:
engines/toltecs/segmap.cpp
engines/toltecs/segmap.h
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 351bf82..f0b3082 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -98,12 +98,12 @@ void SegmentMap::load(byte *source) {
for (uint16 i = 0; i < pathRectCount; i++) {
SegmapPathRect pathRect;
- pathRect.y = READ_LE_UINT16(source);
- pathRect.x = READ_LE_UINT16(source + 2);
- pathRect.height = READ_LE_UINT16(source + 4);
- pathRect.width = READ_LE_UINT16(source + 6);
+ pathRect.y1 = READ_LE_UINT16(source);
+ pathRect.x1 = READ_LE_UINT16(source + 2);
+ pathRect.y2 = pathRect.y1 + READ_LE_UINT16(source + 4);
+ pathRect.x2 = pathRect.x1 + READ_LE_UINT16(source + 6);
- debug(0, "SegmentMap::load() (%d, %d, %d, %d)", pathRect.x, pathRect.y, pathRect.width, pathRect.height);
+ debug(0, "SegmentMap::load() (%d, %d, %d, %d)", pathRect.x1, pathRect.y1, pathRect.x2, pathRect.y2);
source += 8;
_pathRects.push_back(pathRect);
@@ -140,158 +140,138 @@ void SegmentMap::load(byte *source) {
}
-int SegmentMap::findPathRectAtPoint(int x, int y) {
- for (uint rectIndex = 0; rectIndex < _pathRects.size(); rectIndex++) {
- if (y >= _pathRects[rectIndex].y && y <= _pathRects[rectIndex].y + _pathRects[rectIndex].height &&
- x >= _pathRects[rectIndex].x && x <= _pathRects[rectIndex].x + _pathRects[rectIndex].width) {
+int16 SegmentMap::findPathRectAtPoint(int16 x, int16 y) {
+ for (int16 rectIndex = 0; rectIndex < (int16)_pathRects.size(); rectIndex++) {
+ if (y >= _pathRects[rectIndex].y1 && y <= _pathRects[rectIndex].y2 &&
+ x >= _pathRects[rectIndex].x1 && x <= _pathRects[rectIndex].x2) {
return rectIndex;
}
}
return -1;
}
-void SegmentMap::adjustPathPoint(int x, int y) {
+void SegmentMap::adjustPathPoint(int16 &x, int16 &y) {
if (findPathRectAtPoint(x, y) != -1)
return;
uint32 minDistance = 0xFFFFFFFF, distance;
- int x2, y2;
+ int16 adjustedX, adjustedY, x2, y2;
- for (uint rectIndex = 0; rectIndex < _pathRects.size(); rectIndex++) {
+ for (int16 rectIndex = 0; rectIndex < (int16)_pathRects.size(); rectIndex++) {
- if (ABS(x - _pathRects[rectIndex].x) >= ABS((x - (_pathRects[rectIndex].x + _pathRects[rectIndex].width)))) {
- x2 = _pathRects[rectIndex].x + _pathRects[rectIndex].width;
+ if (x >= _pathRects[rectIndex].x1 && x < _pathRects[rectIndex].x2) {
+ x2 = x;
+ } else if (ABS(x - _pathRects[rectIndex].x1) >= ABS(x - _pathRects[rectIndex].x2)) {
+ x2 = _pathRects[rectIndex].x2;
} else {
- x2 = _pathRects[rectIndex].x;
+ x2 = _pathRects[rectIndex].x1;
}
- if (ABS(y - _pathRects[rectIndex].y) >= ABS((y - (_pathRects[rectIndex].y + _pathRects[rectIndex].height)))) {
- y2 = _pathRects[rectIndex].y + _pathRects[rectIndex].height;
+ if (ABS(y - _pathRects[rectIndex].y1) >= ABS(y - _pathRects[rectIndex].y2)) {
+ y2 = _pathRects[rectIndex].y2;
} else {
- y2 = _pathRects[rectIndex].y;
- }
-
- if (x >= _pathRects[rectIndex].x && x < _pathRects[rectIndex].x + _pathRects[rectIndex].width) {
- x2 = x;
+ y2 = _pathRects[rectIndex].y1;
}
distance = ABS(y - y2) + ABS(x - x2);
if (distance < minDistance) {
- if (y >= _pathRects[rectIndex].y && y <= _pathRects[rectIndex].y + _pathRects[rectIndex].height)
- _y = y;
- else
- _y = y2;
- if (x >= _pathRects[rectIndex].x && x <= _pathRects[rectIndex].x + _pathRects[rectIndex].width)
- _x = x;
- else
- _x = x2;
+ if (x >= _pathRects[rectIndex].x1 && x <= _pathRects[rectIndex].x2) {
+ adjustedX = x;
+ } else {
+ adjustedX = x2;
+ }
+ if (y >= _pathRects[rectIndex].y1 && y <= _pathRects[rectIndex].y2) {
+ adjustedY = y;
+ } else {
+ adjustedY = y2;
+ }
minDistance = distance;
}
}
+
+ x = adjustedX;
+ y = adjustedY;
}
-int SegmentMap::findNextPathRect(int srcRectIndex) {
+int16 SegmentMap::findNextPathRect(int16 srcRectIndex, int16 destX, int16 destY) {
- uint v28;
- int result;
- int minDistance, distance;
- int x1, y1, x2, y2;
- int nx1, nx2, nx3;
- int ny, ny2, ny3;
+ int16 result;
+ uint16 minDistance, distance;
+ int16 x1, y1, x2, y2;
+ int16 xmin, xmax, ymax, ymin;
result = -1;
- minDistance = 65535;
-
- x1 = _pathRects[srcRectIndex].x;
- y1 = _pathRects[srcRectIndex].y;
-
- x2 = x1 + _pathRects[srcRectIndex].width;
- y2 = y1 + _pathRects[srcRectIndex].height;
-
- for (uint rectIndex = 0; rectIndex < _pathRects.size(); ++rectIndex) {
-
- if (y1 == _pathRects[rectIndex].height + _pathRects[rectIndex].y && x1 < _pathRects[rectIndex].x + _pathRects[rectIndex].width && x2 > _pathRects[rectIndex].x) {
- ny = y1;
-
-LABEL_28:
- if (x1 >= _pathRects[rectIndex].x) {
- nx1 = x1;
+ minDistance = 0xFFFF;
+
+ x1 = _pathRects[srcRectIndex].x1;
+ y1 = _pathRects[srcRectIndex].y1;
+ x2 = _pathRects[srcRectIndex].x2;
+ y2 = _pathRects[srcRectIndex].y2;
+
+ for (int16 rectIndex = 0; rectIndex < (int16)_pathRects.size(); rectIndex++) {
+
+ int16 nodeX = -1, nodeY = -1;
+
+ // Check if the current rectangle is connected to the source rectangle
+ if (x1 == _pathRects[rectIndex].x2 && y1 < _pathRects[rectIndex].y2 && y2 > _pathRects[rectIndex].y1) {
+ nodeX = x1;
+ } else if (x2 == _pathRects[rectIndex].x1 && y1 < _pathRects[rectIndex].y2 && y2 > _pathRects[rectIndex].y1) {
+ nodeX = x2 - 1;
+ } else if (y1 == _pathRects[rectIndex].y2 && x1 < _pathRects[rectIndex].x2 && x2 > _pathRects[rectIndex].x1) {
+ nodeY = y1;
+ } else if (y2 == _pathRects[rectIndex].y1 && x1 < _pathRects[rectIndex].x2 && x2 > _pathRects[rectIndex].x1) {
+ nodeY = y2 - 1;
+ } else
+ continue;
+
+ if (nodeX == -1) {
+ xmin = MAX<int16>(x1, _pathRects[rectIndex].x1);
+ xmax = MIN<int16>(x2, _pathRects[rectIndex].x2) - 1;
+ if (destX > xmin && destX < xmax) {
+ nodeX = destX;
+ } else if (ABS(destX - xmin) >= ABS(destX - xmax)) {
+ nodeX = xmax - 1;
} else {
- nx1 = _pathRects[rectIndex].x;
+ nodeX = xmin;
}
- if (x2 <= _pathRects[rectIndex].x + _pathRects[rectIndex].width) {
- nx2 = x2 - 1;
- } else {
- nx2 = _pathRects[rectIndex].x + _pathRects[rectIndex].width - 1;
- }
- if (ABS(_x - nx1) >= ABS(_x - nx2)) {
- nx3 = nx2 - 1;
+ }
+
+ if (nodeY == -1) {
+ ymin = MAX<int16>(y1, _pathRects[rectIndex].y1);
+ ymax = MIN<int16>(y2, _pathRects[rectIndex].y2) - 1;
+ if (destY > ymin && destY < ymax) {
+ nodeY = destY;
+ } else if (ABS(destY - ymin) >= ABS(destY - ymax)) {
+ nodeY = ymax - 1;
} else {
- nx3 = nx1;
- }
- if (_x > nx1 && _x < nx2) {
- nx3 = _x;
+ nodeY = ymin;
}
- goto LABEL_55;
}
- if (y2 == _pathRects[rectIndex].y && x1 < _pathRects[rectIndex].x + _pathRects[rectIndex].width && x2 > _pathRects[rectIndex].x) {
- ny = y2 - 1;
- goto LABEL_28;
- }
- if (x1 == _pathRects[rectIndex].x + _pathRects[rectIndex].width && y1 < _pathRects[rectIndex].y + _pathRects[rectIndex].height && y2 > _pathRects[rectIndex].y) {
- nx3 = x1;
- } else {
- if (x2 != _pathRects[rectIndex].x || y1 >= _pathRects[rectIndex].y + _pathRects[rectIndex].height || y2 <= _pathRects[rectIndex].y)
- continue;
- nx3 = x2 - 1;
- }
- if (y1 >= _pathRects[rectIndex].y) {
- ny3 = y1;
- } else {
- ny3 = _pathRects[rectIndex].y;
- }
- if (y2 <= _pathRects[rectIndex].y + _pathRects[rectIndex].height) {
- ny2 = y2 - 1;
- } else {
- ny2 = _pathRects[rectIndex].y + _pathRects[rectIndex].height - 1;
- }
- if (ABS(_y - ny3) >= ABS(_y - ny2)) {
- ny = ny2 - 1;
- } else {
- ny = ny3;
- }
- if (_y > ny3 && _y < ny2) {
- ny = _y;
- }
-
-LABEL_55:
- distance = ABS(_x - nx3) + ABS(_y - ny);
- v28 = 0;
- while (v28 < _rectIndexArray2Count) {
- if (rectIndex == _rectIndexArray2[v28]) {
+
+ distance = ABS(destX - nodeX) + ABS(destY - nodeY);
+
+ for (uint i = 0; i < _closedPathRectsCount; i++) {
+ if (rectIndex == _closedPathRects[i]) {
distance = minDistance;
break;
}
- ++v28;
}
- v28 = 0;
- while (v28 < _rectIndexArray1Count) {
- if (rectIndex == _rectIndexArray1[v28]) {
+ for (uint i = 0; i < _deadEndPathRectsCount; i++) {
+ if (rectIndex == _deadEndPathRects[i]) {
distance = minDistance;
break;
}
- ++v28;
}
if (distance < minDistance) {
result = rectIndex;
minDistance = distance;
- _pointsArray[_pointsCount].y = ny;
- _pointsArray[_pointsCount].x = nx3;
+ _pathNodes[_pathNodesCount].x = nodeX;
+ _pathNodes[_pathNodesCount].y = nodeY;
}
}
@@ -309,68 +289,58 @@ void plotProc(int x, int y, int color, void *data) {
ld->surf[x + y * ld->pitch] = color;
}
-void SegmentMap::findPath(int16 *pointsArray, int destX, int destY, int x, int y) {
+void SegmentMap::findPath(int16 *pointsArray, int16 destX, int16 destY, int16 sourceX, int16 sourceY) {
- int index;
- int sourceRectIndex, destRectIndex;
- int pointsCount;
+ // TODO: Writes to pointsArray aren't endian-safe yet
- pointsCount = 2;
- index = 0;
+ int16 currentRectIndex, destRectIndex;
+ int16 pointsCount;
- debug(0, "SegmentMap::findPath(fromX: %d; fromY: %d; toX: %d; toY: %d)", x, y, destX, destY);
+ debug(0, "SegmentMap::findPath(fromX: %d; fromY: %d; toX: %d; toY: %d)", sourceX, sourceY, destX, destY);
- sourceRectIndex = findPathRectAtPoint(x, y);
- if (sourceRectIndex == -1) {
- adjustPathPoint(x, y);
- x = _x;
- y = _y;
- }
+ _deadEndPathRectsCount = 0;
+ _closedPathRectsCount = 0;
+ _pathNodesCount = 0;
- _rectIndexArray1Count = 0;
- _rectIndexArray2Count = 0;
- _pointsCount = 0;
+ pointsCount = 2;
+
+ adjustPathPoint(sourceX, sourceY);
+ currentRectIndex = findPathRectAtPoint(sourceX, sourceY);
- _x = destX;
- _y = destY;
+ adjustPathPoint(destX, destY);
+ destRectIndex = findPathRectAtPoint(destX, destY);
- adjustPathPoint(_x, _y);
- destRectIndex = findPathRectAtPoint(_x, _y);
- sourceRectIndex = findPathRectAtPoint(x, y);
- if (sourceRectIndex != -1) {
- if (destRectIndex != sourceRectIndex) {
+ if (currentRectIndex != -1) {
+ if (destRectIndex != currentRectIndex) {
while (1) {
do {
- _rectIndexArray2[_rectIndexArray2Count++] = sourceRectIndex;
- sourceRectIndex = findNextPathRect(sourceRectIndex);
- _pointsCount++;
- } while (sourceRectIndex != -1 && sourceRectIndex != destRectIndex);
- if (sourceRectIndex != -1 && sourceRectIndex == destRectIndex)
+ _closedPathRects[_closedPathRectsCount++] = currentRectIndex;
+ currentRectIndex = findNextPathRect(currentRectIndex, destX, destY);
+ _pathNodesCount++;
+ } while (currentRectIndex != -1 && currentRectIndex != destRectIndex);
+ if (currentRectIndex != -1 && currentRectIndex == destRectIndex)
break;
- _rectIndexArray1[_rectIndexArray1Count++] = _rectIndexArray2[--_rectIndexArray2Count];
- _pointsCount -= 2;
- sourceRectIndex = _rectIndexArray2[--_rectIndexArray2Count];
+ _deadEndPathRects[_deadEndPathRectsCount++] = _closedPathRects[--_closedPathRectsCount];
+ _pathNodesCount -= 2;
+ currentRectIndex = _closedPathRects[--_closedPathRectsCount];
}
- sourceRectIndex = 0;
- while (sourceRectIndex < _pointsCount) {
- pointsArray[pointsCount++] = _pointsArray[sourceRectIndex].y;
- pointsArray[pointsCount++] = _pointsArray[sourceRectIndex].x;
- index++;
- sourceRectIndex++;
+ for (int16 i = 0; i < _pathNodesCount; i++) {
+ pointsArray[pointsCount++] = _pathNodes[i].y;
+ pointsArray[pointsCount++] = _pathNodes[i].x;
}
}
- pointsArray[pointsCount++] = _y;
- pointsArray[pointsCount++] = _x;
+ pointsArray[pointsCount++] = destY;
+ pointsArray[pointsCount++] = destX;
pointsArray[0] = 0;
- pointsArray[1] = index + 1;
+ pointsArray[1] = _pathNodesCount + 1;
}
debug(0, "SegmentMap::findPath() count = %d", pointsArray[1]);
- /*
- int sx = x, sy = y;
+#if 0 // DEBUG: Draw the path we found
+ int sx = sourceX, sy = sourceY;
LineData ld;
ld.pitch = _vm->_sceneWidth;
ld.surf = _vm->_screen->_backScreen;
@@ -380,7 +350,7 @@ void SegmentMap::findPath(int16 *pointsArray, int destX, int destY, int x, int y
sx = pointsArray[3+i];
sy = pointsArray[2+i];
}
- */
+#endif
}
@@ -390,8 +360,9 @@ int8 SegmentMap::getScalingAtPoint(int16 x, int16 y) {
if (_infoRects[i].id == 0 &&
y >= _infoRects[i].y && y <= _infoRects[i].y + _infoRects[i].height &&
x >= _infoRects[i].x && x <= _infoRects[i].x + _infoRects[i].width) {
- char topScaling = (char)_infoRects[i].b;
- char bottomScaling = (char)_infoRects[i].c;
+
+ int8 topScaling = (int8)_infoRects[i].b;
+ int8 bottomScaling = (int8)_infoRects[i].c;
if (y - _infoRects[i].y > 0) {
scaling = (ABS(y - _infoRects[i].y) * (bottomScaling - topScaling) / _infoRects[i].height) + topScaling;
}
@@ -527,7 +498,7 @@ void SegmentMap::debugDrawRects(Graphics::Surface *surf) {
for (uint16 i = 0; i < _pathRects.size(); i++) {
SegmapPathRect pathRect = _pathRects[i];
surf->frameRect(
- Common::Rect(pathRect.x, pathRect.y, pathRect.x + pathRect.width, pathRect.y + pathRect.height),
+ Common::Rect(pathRect.x1, pathRect.y1, pathRect.x2, pathRect.y2),
255);
}
}
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index 7ec7cfb..a625c84 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -63,10 +63,10 @@ public:
void load(byte *source);
- int findPathRectAtPoint(int x, int y);
- void adjustPathPoint(int x, int y);
+ int16 findPathRectAtPoint(int16 x, int16 y);
+ void adjustPathPoint(int16 &x, int16 &y);
- void findPath(int16 *pointsArray, int destX, int destY, int x, int y);
+ void findPath(int16 *pointsArray, int16 destX, int16 destY, int16 sourceX, int16 sourceY);
int8 getScalingAtPoint(int16 x, int16 y);
void getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byte &g, byte &b);
@@ -87,8 +87,11 @@ public: // for debugging purposes
};
struct SegmapPathRect {
+ /*
int16 y, x;
int16 height, width;
+ */
+ int16 x1, y1, x2, y2;
};
struct SegmapInfoRect {
@@ -114,18 +117,16 @@ public: // for debugging purposes
SegmapPathRectArray _pathRects;
SegmapInfoRectArray _infoRects;
- int _rectIndexArray1[1000];
- uint _rectIndexArray1Count;
+ int16 _deadEndPathRects[1000];
+ uint _deadEndPathRectsCount;
- int _rectIndexArray2[1000];
- uint _rectIndexArray2Count;
+ int16 _closedPathRects[1000];
+ uint _closedPathRectsCount;
- PathPoint _pointsArray[1000];
- int16 _pointsCount;
+ PathPoint _pathNodes[1000];
+ int16 _pathNodesCount;
- int _x, _y;
-
- int findNextPathRect(int srcRectIndex);
+ int16 findNextPathRect(int16 srcRectIndex, int16 destX, int16 destY);
};
Commit: 21f6dad09a5f773fb4869f604f47e84ac266585c
https://github.com/scummvm/scummvm/commit/21f6dad09a5f773fb4869f604f47e84ac266585c
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: - Renamed some variables & functions
- Mouse cursor is hidden/shown when _mouseDisabled variable is set via script
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/script.h
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 73c78e8..0b27e8a 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -73,10 +73,10 @@ void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
void ScriptInterpreter::runScript(uint slotIndex) {
- _switchStack1 = true;
- _switchStack2 = false;
- _switchStack3 = false;
- _scriptFlag01 = false;
+ _switchLocalDataNear = true;
+ _switchLocalDataFar = false;
+ _switchLocalDataToStack = false;
+ _cmpBitTest = false;
_regs.reg0 = 0;
_regs.reg1 = 0;
@@ -95,21 +95,21 @@ void ScriptInterpreter::runScript(uint slotIndex) {
if (_vm->_movieSceneFlag)
_vm->_input->_mouseButton = 0;
- if (_switchStack1) {
- _switchStack1 = false;
+ if (_switchLocalDataNear) {
+ _switchLocalDataNear = false;
_localData = getSlotData(_regs.reg4);
}
- if (_switchStack2) {
- _switchStack2 = false;
+ if (_switchLocalDataFar) {
+ _switchLocalDataFar = false;
_localData = getSlotData(_regs.reg5);
- _switchStack1 = true;
+ _switchLocalDataNear = true;
}
- if (_switchStack3) {
- _switchStack3 = false;
+ if (_switchLocalDataToStack) {
+ _switchLocalDataToStack = false;
_localData = _stack + 2;
- _switchStack1 = true;
+ _switchLocalDataNear = true;
}
byte opcode = readByte();
@@ -273,25 +273,25 @@ void ScriptInterpreter::execOpcode(byte opcode) {
localWrite16(_regs.reg3, localRead16(_regs.reg3) - 1);
break;
case 32:
- _switchStack2 = true;
+ _switchLocalDataFar = true;
break;
case 33:
- _switchStack3 = true;
+ _switchLocalDataToStack = true;
break;
case 34:
- push16(_regs.reg0);
+ pushInt16(_regs.reg0);
debug(1, "pushw reg0");
break;
case 35:
- push16(_regs.reg1);
+ pushInt16(_regs.reg1);
debug(1, "pushw reg1");
break;
case 36:
- _regs.reg1 = pop16();
+ _regs.reg1 = popInt16();
debug(1, "popw reg1");
break;
case 37:
- _regs.reg0 = pop16();
+ _regs.reg0 = popInt16();
debug(1, "popw reg0");
break;
case 38:
@@ -299,19 +299,19 @@ void ScriptInterpreter::execOpcode(byte opcode) {
break;
case 39:
_regs.reg8 = readInt16();
- _scriptFlag01 = false;
+ _cmpBitTest = false;
break;
case 40:
_regs.reg8 = _regs.reg0;
- _scriptFlag01 = false;
+ _cmpBitTest = false;
break;
case 41:
_regs.reg8 = readInt16();
- _scriptFlag01 = true;
+ _cmpBitTest = true;
break;
case 42:
_regs.reg8 = _regs.reg0;
- _scriptFlag01 = true;
+ _cmpBitTest = true;
break;
case 43:
debug(1, "retn (slot: %d; ofs: %04X)\n", _regs.reg4, _regs.reg0);
@@ -321,38 +321,38 @@ void ScriptInterpreter::execOpcode(byte opcode) {
debug(1, "retf (slot: %d; ofs: %04X)\n", _regs.reg5, _regs.reg0);
_code = getSlotData(_regs.reg5) + _regs.reg0;
_regs.reg4 = _regs.reg5;
- _switchStack1 = true;
+ _switchLocalDataNear = true;
break;
case 45:
debug(1, "callnear %04X (slot: %d; ofs: %04X)\n", _regs.reg0, _regs.reg4, _regs.reg0);
- push16(_code - getSlotData(_regs.reg4));
- push16(_regs.reg4);
+ pushInt16(_code - getSlotData(_regs.reg4));
+ pushInt16(_regs.reg4);
_code = getSlotData(_regs.reg4) + _regs.reg0;
break;
case 46:
debug(1, "callfar %04X (slot: %d; ofs: %04X)\n", _regs.reg0, _regs.reg5, _regs.reg0);
- push16(_code - getSlotData(_regs.reg4));
- push16(_regs.reg4);
+ pushInt16(_code - getSlotData(_regs.reg4));
+ pushInt16(_regs.reg4);
_code = getSlotData(_regs.reg5) + _regs.reg0;
_regs.reg4 = _regs.reg5;
- _switchStack1 = true;
+ _switchLocalDataNear = true;
break;
case 47:
- _regs.reg4 = pop16();
- ofs = pop16();
+ _regs.reg4 = popInt16();
+ ofs = popInt16();
_code = getSlotData(_regs.reg4) + ofs;
debug(1, "ret (slot: %d; ofs: %04X)\n", _regs.reg4, ofs);
- //_code = getSlotData(_regs.reg4) + pop16();
- _switchStack1 = true;
+ //_code = getSlotData(_regs.reg4) + popInt16();
+ _switchLocalDataNear = true;
break;
case 48:
- _regs.reg4 = pop16();
- ofs = pop16();
+ _regs.reg4 = popInt16();
+ ofs = popInt16();
_code = getSlotData(_regs.reg4) + ofs;
debug(1, "retsp (slot: %d; ofs: %04X)\n", _regs.reg4, ofs);
- //_code = getSlotData(_regs.reg4) + pop16();
+ //_code = getSlotData(_regs.reg4) + popInt16();
_regs.sp += _regs.reg0;
- _switchStack1 = true;
+ _switchLocalDataNear = true;
break;
case 49:
ofs = readByte();
@@ -360,7 +360,7 @@ void ScriptInterpreter::execOpcode(byte opcode) {
_code += ofs;
break;
case 50:
- if (_scriptFlag01) {
+ if (_cmpBitTest) {
_regs.reg1 &= _regs.reg8;
if (_regs.reg1 == 0)
_code += 4;
@@ -371,7 +371,7 @@ void ScriptInterpreter::execOpcode(byte opcode) {
_code++;
break;
case 51:
- if (_scriptFlag01) {
+ if (_cmpBitTest) {
_regs.reg1 &= _regs.reg8;
if (_regs.reg1 != 0)
_code += 4;
@@ -573,7 +573,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
int16 codeOfs = _code - getSlotData(_regs.reg4);
loadScript(arg16(4), arg8(3));
_code = getSlotData(_regs.reg4) + codeOfs;
- _switchStack1 = true;
+ _switchLocalDataNear = true;
break;
}
@@ -1071,6 +1071,7 @@ void ScriptInterpreter::setGameVar(uint variable, int16 value) {
switch (variable) {
case 0:
_vm->_input->_mouseDisabled = value;
+ _vm->_system->showMouse(value == 0);
break;
case 3:
_vm->_input->_mouseButton = value;
@@ -1151,32 +1152,32 @@ int32 ScriptInterpreter::arg32(int16 offset) {
return READ_LE_UINT32(&_subCode[offset]);
}
-void ScriptInterpreter::push8(byte value) {
+void ScriptInterpreter::pushByte(byte value) {
_stack[_regs.sp] = value;
_regs.sp--;
}
-byte ScriptInterpreter::pop8() {
+byte ScriptInterpreter::popByte() {
_regs.sp++;
return _stack[_regs.sp];
}
-void ScriptInterpreter::push16(int16 value) {
+void ScriptInterpreter::pushInt16(int16 value) {
WRITE_LE_UINT16(_stack + _regs.sp, value);
_regs.sp -= 2;
}
-int16 ScriptInterpreter::pop16() {
+int16 ScriptInterpreter::popInt16() {
_regs.sp += 2;
return READ_LE_UINT16(_stack + _regs.sp);
}
-void ScriptInterpreter::push32(int32 value) {
+void ScriptInterpreter::pushInt32(int32 value) {
WRITE_LE_UINT32(_stack + _regs.sp, value);
_regs.sp -= 4;
}
-int32 ScriptInterpreter::pop32() {
+int32 ScriptInterpreter::popInt32() {
_regs.sp += 4;
return READ_LE_UINT32(_stack + _regs.sp);
}
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index 7b91105..d7712a8 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -87,8 +87,8 @@ protected:
byte *_code, *_subCode;
byte *_localData;
- bool _switchStack1, _switchStack2, _switchStack3;
- bool _scriptFlag01;
+ bool _switchLocalDataNear, _switchLocalDataFar, _switchLocalDataToStack;
+ bool _cmpBitTest;
ScriptSlot _slots[kMaxScriptSlots];
@@ -109,12 +109,12 @@ protected:
int16 arg16(int16 offset);
int32 arg32(int16 offset);
- void push8(byte value);
- byte pop8();
- void push16(int16 value);
- int16 pop16();
- void push32(int32 value);
- int32 pop32();
+ void pushByte(byte value);
+ byte popByte();
+ void pushInt16(int16 value);
+ int16 popInt16();
+ void pushInt32(int32 value);
+ int32 popInt32();
void localWrite8(int16 offset, byte value);
byte localRead8(int16 offset);
Commit: dd5567613f4e733b62760c981cb547fe9656fced
https://github.com/scummvm/scummvm/commit/dd5567613f4e733b62760c981cb547fe9656fced
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: - Renamed stuff and cleanups
- Beginnings of the saveload system (incomplete)
Changed paths:
A engines/toltecs/saveload.cpp
engines/toltecs/animation.cpp
engines/toltecs/animation.h
engines/toltecs/input.cpp
engines/toltecs/module.mk
engines/toltecs/palette.cpp
engines/toltecs/palette.h
engines/toltecs/screen.cpp
engines/toltecs/screen.h
engines/toltecs/script.cpp
engines/toltecs/script.h
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
index 2ecc12b..bd8fd7f 100644
--- a/engines/toltecs/animation.cpp
+++ b/engines/toltecs/animation.cpp
@@ -34,6 +34,7 @@
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
+#include "toltecs/palette.h"
#include "toltecs/screen.h"
namespace Toltecs {
@@ -55,7 +56,7 @@ void AnimationPlayer::start(uint resIndex) {
_height = _vm->_arc->readUint16LE();
_width = _vm->_arc->readUint16LE();
_frameCount = _vm->_arc->readUint16LE();
- _vm->_arc->read(_palette, 768);
+ _vm->_arc->read(_vm->_palette->getAnimPalette(), 768);
_curFrameSize = _vm->_arc->readUint32LE();
_nextFrameOffset = _curFrameSize + 782;
_vm->_arc->read(_animBuffer, _curFrameSize);
@@ -136,4 +137,23 @@ void AnimationPlayer::unpackFrame() {
_vm->_screen->unpackRle(_animBuffer, _vm->_screen->_backScreen, _width, _height);
}
+void AnimationPlayer::saveState(Common::WriteStream *out) {
+ out->writeUint16LE(_resIndex);
+ // NOTE: The original engine doesn't save width/height, but we do
+ out->writeUint16LE(_width);
+ out->writeUint16LE(_height);
+ out->writeUint16LE(_frameCount);
+ out->writeUint16LE(_frameNumber);
+ out->writeUint32LE(_keepFrameCounter);
+ out->writeUint32LE(_curFrameSize);
+ out->writeUint32LE(_nextFrameSize);
+ out->writeUint32LE(_nextFrameOffset);
+ out->writeUint32LE(_firstCurFrameSize);
+ out->writeUint32LE(_firstNextFrameSize);
+ out->writeUint32LE(_firstNextFrameOffset);
+}
+
+void AnimationPlayer::loadState(Common::ReadStream *in) {
+}
+
} // End of namespace Toltecs
diff --git a/engines/toltecs/animation.h b/engines/toltecs/animation.h
index a8bef1f..03aa18c 100644
--- a/engines/toltecs/animation.h
+++ b/engines/toltecs/animation.h
@@ -57,6 +57,9 @@ public:
int16 getStatus();
uint16 getFrameNumber() const { return _frameNumber; }
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
+
//protected:
public:
ToltecsEngine *_vm;
@@ -65,7 +68,6 @@ public:
byte *_animBuffer;
uint _resIndex;
- byte _palette[768];
uint16 _width, _height;
uint16 _frameNumber, _frameCount;
diff --git a/engines/toltecs/input.cpp b/engines/toltecs/input.cpp
index ca09a9b..b658c62 100644
--- a/engines/toltecs/input.cpp
+++ b/engines/toltecs/input.cpp
@@ -64,6 +64,20 @@ void Input::update() {
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
+
+ // FIXME: This is just for debugging
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_F6:
+ _vm->savegame("toltecs.001");
+ break;
+ case Common::KEYCODE_F9:
+ _vm->loadgame("toltecs.001");
+ break;
+ default:
+ break;
+ }
+
+ break;
case Common::EVENT_QUIT:
break;
case Common::EVENT_MOUSEMOVE:
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
index 63a8043..1f249a8 100644
--- a/engines/toltecs/module.mk
+++ b/engines/toltecs/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS = \
palette.o \
toltecs.o \
resource.o \
+ saveload.o \
screen.o \
script.o \
segmap.o
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 7c882f1..0f08694 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -42,6 +42,8 @@ Palette::Palette(ToltecsEngine *vm) : _vm(vm) {
clearFragments();
+ memset(_colorTransTable, 0, sizeof(_colorTransTable));
+
}
Palette::~Palette() {
@@ -59,6 +61,16 @@ void Palette::setFullPalette(byte *palette) {
_vm->_system->updateScreen();
}
+void Palette::getFullPalette(byte *palette) {
+ byte colors[1024];
+ _vm->_system->grabPalette(colors, 0, 256);
+ for (int i = 0; i < 256; i++) {
+ palette[i * 3 + 0] = colors[i * 4 + 0] >> 2;
+ palette[i * 3 + 1] = colors[i * 4 + 1] >> 2;
+ palette[i * 3 + 2] = colors[i * 4 + 2] >> 2;
+ }
+}
+
void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex) {
byte colors[1024];
@@ -154,4 +166,32 @@ void Palette::clearFragments() {
_fragments.clear();
}
+void Palette::saveState(Common::WriteStream *out) {
+
+ // Save currently active palette
+ byte palette[768];
+ getFullPalette(palette);
+ out->write(palette, 768);
+
+ out->write(_mainPalette, 768);
+ out->write(_animPalette, 768);
+ out->write(_colorTransTable, 256);
+
+ uint16 fragmentCount = _fragments.size();
+ out->writeUint16LE(fragmentCount);
+ for (PaletteFragmentArray::iterator iter = _fragments.begin(); iter != _fragments.end(); iter++) {
+ PaletteFragment fragment = *iter;
+ out->writeUint16LE(fragment.id);
+ out->writeByte(fragment.index);
+ out->writeByte(fragment.count);
+ }
+ out->writeByte(_fragmentIndex);
+
+
+}
+
+void Palette::loadState(Common::ReadStream *in) {
+}
+
+
} // End of namespace Toltecs
diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h
index 339ff8d..acc3407 100644
--- a/engines/toltecs/palette.h
+++ b/engines/toltecs/palette.h
@@ -29,6 +29,7 @@
#include "common/util.h"
#include "common/file.h"
#include "common/savefile.h"
+#include "common/stream.h"
#include "common/system.h"
#include "common/hash-str.h"
#include "common/events.h"
@@ -53,6 +54,7 @@ public:
~Palette();
void setFullPalette(byte *palette);
+ void getFullPalette(byte *palette);
void setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex);
void loadAddPalette(uint resIndex, byte startIndex);
@@ -63,6 +65,10 @@ public:
void clearFragments();
byte *getMainPalette() { return _mainPalette; }
+ byte *getAnimPalette() { return _animPalette; }
+
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
protected:
@@ -76,6 +82,8 @@ protected:
ToltecsEngine *_vm;
byte _mainPalette[768];
+ byte _animPalette[768];
+ byte _colorTransTable[256];
PaletteFragmentArray _fragments;
byte _fragmentIndex;
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
new file mode 100644
index 0000000..52325b9
--- /dev/null
+++ b/engines/toltecs/saveload.cpp
@@ -0,0 +1,114 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/animation.h"
+#include "toltecs/input.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+#include "toltecs/script.h"
+#include "toltecs/screen.h"
+#include "toltecs/segmap.h"
+
+namespace Toltecs {
+
+// TODO: Saveload is not working yet
+
+void ToltecsEngine::savegame(const char *filename) {
+
+ Common::OutSaveFile *out;
+ if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
+ warning("Can't create file '%s', game not saved", filename);
+ }
+
+ // Save game variables
+ for (uint variable = 0; variable < 22; variable++) {
+ int16 value = _script->getGameVar(variable);
+ out->writeUint16LE(value);
+ }
+
+ _palette->saveState(out);
+ _script->saveState(out);
+ _anim->saveState(out);
+
+ // Save GUI
+ {
+
+ }
+
+/*
+case 0: return "mouseDisabled";
+case 1: return "mouseY";
+case 2: return "mouseX";
+case 3: return "mouseButton";
+case 4: return "verbLineY";
+case 5: return "verbLineX";
+case 6: return "verbLineWidth";
+case 7: return "verbLineCount";
+case 8: return "verbLineNum";
+case 9: return "talkTextItemNum";
+case 10: return "talkTextY";
+case 11: return "talkTextX";
+case 12: return "talkTextFontColor";
+case 13: return "cameraY";
+case 14: return "cameraX";
+case 15: return "walkSpeedY";
+case 16: return "walkSpeedX";
+case 17: return "flag01";
+case 18: return "sceneResIndex";
+case 19: return "cameraTop";
+case 20: return "sceneHeight";
+case 21: return "sceneWidth";
+*/
+
+/*
+PersistentGameVarRef <offset _sceneHeight, 2>
+PersistentGameVarRef <offset _sceneWidth, 2>
+PersistentGameVarRef <offset screenFlag01, 2>
+PersistentGameVarRef <offset currentSequenceResIndex, 4>
+PersistentGameVarRef <offset currentSequenceLoopCount, 4>
+PersistentGameVarRef <offset sequenceVolume, 4>
+PersistentGameVarRef <offset dword_99AC0, 4>
+PersistentGameVarRef <offset verbLineNum, 22h>
+*/
+
+ delete out;
+
+}
+
+void ToltecsEngine::loadgame(const char *filename) {
+}
+
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 779513a..a11022c 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -963,6 +963,17 @@ void Screen::drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch,
}
+void Screen::saveState(Common::WriteStream *out) {
+ for (int i = 0; i < 8; i++) {
+ out->writeUint16LE(_verbLineItems[i].slotIndex);
+ out->writeUint16LE(_verbLineItems[i].slotOffset);
+ }
+}
+
+void Screen::loadState(Common::ReadStream *in) {
+}
+
+
/*
void Screen::update() {
}
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 156e4e1..c34f44d 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -327,6 +327,9 @@ public:
void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color);
void drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color);
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
+
//protected:
public:
@@ -348,6 +351,7 @@ public:
uint _fontResIndexArray[10];
byte _fontColor1, _fontColor2;
+ // TODO: Remove this _tempXXX stuff
byte _tempString[100];
byte _tempStringLen1, _tempStringLen2;
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 0b27e8a..fa38219 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -21,6 +21,8 @@
*
*/
+// TODO: Clean up game variable handling and move it to ToltecsEngine
+
#include "common/events.h"
#include "common/keyboard.h"
#include "common/file.h"
@@ -45,7 +47,7 @@ namespace Toltecs {
ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) {
- _stack = new byte[4096 + 4];
+ _stack = new byte[kScriptStackSize];
memset(_slots, 0, sizeof(_slots));
@@ -550,7 +552,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 14:// ok
{
debug(0, "o2_setDeltaPalette(animPalette, %d, %d, %d, %d)", arg8(6), arg8(5), arg8(4), arg8(3));
- _vm->_palette->setDeltaPalette(_vm->_anim->_palette, arg8(6), (char)arg8(5), arg8(4), arg8(3));
+ _vm->_palette->setDeltaPalette(_vm->_palette->getAnimPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
break;
}
@@ -604,8 +606,8 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 22:// ok
{
- debug(0, "o2_setCameraTop(%d)", arg8(3));
- _vm->setCameraTop(arg8(3));
+ debug(0, "o2_setGuiHeight(%d)", arg8(3));
+ _vm->setGuiHeight(arg8(3));
break;
}
@@ -926,7 +928,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
}
-ScriptInterpreter::VarType ScriptInterpreter::getGameVarType(uint variable) {
+VarType ScriptInterpreter::getGameVarType(uint variable) {
switch (variable) {
case 0: return vtByte;
case 1: return vtWord;
@@ -976,7 +978,7 @@ const char *getVarName(uint variable) {
case 16: return "walkSpeedX";
case 17: return "flag01";
case 18: return "sceneResIndex";
- case 19: return "cameraTop";
+ case 19: return "guiHeight";
case 20: return "sceneHeight";
case 21: return "sceneWidth";
}
@@ -1047,7 +1049,7 @@ int16 ScriptInterpreter::getGameVar(uint variable) {
value = _vm->_sceneResIndex;
break;
case 19:
- value = _vm->_cameraTop;
+ value = _vm->_guiHeight;
break;
case 20:
value = _vm->_sceneHeight;
@@ -1122,7 +1124,7 @@ void ScriptInterpreter::setGameVar(uint variable, int16 value) {
_vm->_sceneResIndex = value;
break;
case 19:
- _vm->_cameraTop = value;
+ _vm->_guiHeight = value;
break;
case 20:
_vm->_sceneHeight = value;
@@ -1217,4 +1219,34 @@ byte *ScriptInterpreter::localPtr(int16 offset) {
return &_localData[offset];
}
+void ScriptInterpreter::saveState(Common::WriteStream *out) {
+
+ // Save registers
+ out->writeUint16LE(_regs.reg0);
+ out->writeUint16LE(_regs.reg1);
+ out->writeUint16LE(_regs.reg2);
+ out->writeUint16LE(_regs.reg3);
+ out->writeUint16LE(_regs.reg4);
+ out->writeUint16LE(_regs.reg5);
+ out->writeUint16LE(_regs.reg6);
+ out->writeUint16LE(_regs.sp);
+ out->writeUint16LE(_regs.reg8);
+
+ // Save slots
+ for (int slot = 0; slot < kMaxScriptSlots; slot++) {
+ out->writeUint32LE(_slots[slot].size);
+ out->writeUint16LE(_slots[slot].resIndex);
+ if (_slots[slot].size > 0)
+ out->write(_slots[slot].data, _slots[slot].size);
+ }
+
+ // Save stack
+ out->write(_stack, kScriptStackSize);
+ out->writeUint16LE(_savedSp);
+
+}
+
+void ScriptInterpreter::loadState(Common::ReadStream *in) {
+}
+
} // End of namespace Toltecs
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index d7712a8..eacd116 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -45,6 +45,12 @@
namespace Toltecs {
const int kMaxScriptSlots = 50;
+const int kScriptStackSize = 4096 + 4;
+
+enum VarType {
+ vtByte,
+ vtWord
+};
class ScriptInterpreter {
public:
@@ -56,12 +62,14 @@ public:
byte *getSlotData(int slotIndex) const { return _slots[slotIndex].data; }
-protected:
+ VarType getGameVarType(uint variable);
+ int16 getGameVar(uint variable);
+ void setGameVar(uint variable, int16 value);
- enum VarType {
- vtByte,
- vtWord
- };
+ void saveState(Common::WriteStream *out);
+ void loadState(Common::ReadStream *in);
+
+protected:
struct ScriptRegs {
int16 reg0;
@@ -101,10 +109,6 @@ protected:
void execOpcode(byte opcode);
void execKernelOpcode(uint16 kernelOpcode);
- VarType getGameVarType(uint variable);
- int16 getGameVar(uint variable);
- void setGameVar(uint variable, int16 value);
-
byte arg8(int16 offset);
int16 arg16(int16 offset);
int32 arg32(int16 offset);
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 73de88f..f1b531f 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -98,7 +98,7 @@ int ToltecsEngine::go() {
_cameraY = 0;
_newCameraX = 0;
_newCameraY = 0;
- _cameraTop = 26;
+ _guiHeight = 26;
_cameraHeight = 0;
_yetAnotherX = 0;
@@ -227,11 +227,11 @@ void ToltecsEngine::setCamera(int16 x, int16 y) {
}
-void ToltecsEngine::setCameraTop(int16 top) {
- if (top != _cameraTop) {
- _cameraTop = top;
- _cameraHeight = 400 - _cameraTop;
- debug(0, "ToltecsEngine::setCameraTop() _cameraTop = %d; _cameraHeight = %d", _cameraTop, _cameraHeight);
+void ToltecsEngine::setGuiHeight(int16 guiHeight) {
+ if (guiHeight != _guiHeight) {
+ _guiHeight = guiHeight;
+ _cameraHeight = 400 - _guiHeight;
+ debug(0, "ToltecsEngine::setGuiHeight() _guiHeight = %d; _cameraHeight = %d", _guiHeight, _cameraHeight);
// TODO: clearScreen();
}
}
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 1d5a394..11ce767 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -80,7 +80,7 @@ public:
void updateScreen();
void setCamera(int16 x, int16 y);
- void setCameraTop(int16 top);
+ void setGuiHeight(int16 guiHeight);
void scrollCameraUp(int16 delta);
void scrollCameraDown(int16 delta);
void scrollCameraLeft(int16 delta);
@@ -94,6 +94,9 @@ public:
int16 findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize);
+ void savegame(const char *filename);
+ void loadgame(const char *filename);
+
public:
AnimationPlayer *_anim;
ArchiveReader *_arc;
@@ -116,7 +119,7 @@ public:
// TODO: Move camera stuff into own Scene class
int16 _cameraX, _cameraY;
int16 _newCameraX, _newCameraY;
- int16 _cameraTop, _cameraHeight;
+ int16 _guiHeight, _cameraHeight;
int16 _yetAnotherX;
bool _doSpeech, _doText;
Commit: 51214a461a94e2bc2456f3fea885445f38d2f84f
https://github.com/scummvm/scummvm/commit/51214a461a94e2bc2456f3fea885445f38d2f84f
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Saving/loading is working; it still needs work but will suffice to make debugging somewhat easier.
Changed paths:
engines/toltecs/animation.cpp
engines/toltecs/palette.cpp
engines/toltecs/saveload.cpp
engines/toltecs/screen.cpp
engines/toltecs/script.cpp
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
index bd8fd7f..5d60144 100644
--- a/engines/toltecs/animation.cpp
+++ b/engines/toltecs/animation.cpp
@@ -154,6 +154,20 @@ void AnimationPlayer::saveState(Common::WriteStream *out) {
}
void AnimationPlayer::loadState(Common::ReadStream *in) {
+
+ _resIndex = in->readUint16LE();
+ _width = in->readUint16LE();
+ _height = in->readUint16LE();
+ _frameCount = in->readUint16LE();
+ _frameNumber = in->readUint16LE();
+ _keepFrameCounter = in->readUint32LE();
+ _curFrameSize = in->readUint32LE();
+ _nextFrameSize = in->readUint32LE();
+ _nextFrameOffset = in->readUint32LE();
+ _firstCurFrameSize = in->readUint32LE();
+ _firstNextFrameSize = in->readUint32LE();
+ _firstNextFrameOffset = in->readUint32LE();
+
}
} // End of namespace Toltecs
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 0f08694..9692538 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -187,10 +187,30 @@ void Palette::saveState(Common::WriteStream *out) {
}
out->writeByte(_fragmentIndex);
-
}
void Palette::loadState(Common::ReadStream *in) {
+
+ // Save currently active palette
+ byte palette[768];
+ in->read(palette, 768);
+ setFullPalette(palette);
+
+ in->read(_mainPalette, 768);
+ in->read(_animPalette, 768);
+ in->read(_colorTransTable, 256);
+
+ uint16 fragmentCount = in->readUint16LE();
+ _fragments.clear();
+ for (uint16 i = 0; i < fragmentCount; i++) {
+ PaletteFragment fragment;
+ fragment.id = in->readUint16LE();
+ fragment.index = in->readByte();
+ fragment.count = in->readByte();
+ _fragments.push_back(fragment);
+ }
+ _fragmentIndex = in->readByte();
+
}
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 52325b9..42ef4a3 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -43,64 +43,61 @@
namespace Toltecs {
-// TODO: Saveload is not working yet
+/* TODO:
+ - Saveload is working so far but only one slot is supported until the game menu is implemented
+ - Save with F6; Load with F9
+ - Saving during an animation (AnimationPlayer) is not working correctly yet
+ - Maybe switch to SCUMM/Tinsel serialization approach?
+*/
+
+#define SAVEGAME_VERSION 0 // 0 is dev version until in official SVN
void ToltecsEngine::savegame(const char *filename) {
Common::OutSaveFile *out;
if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
warning("Can't create file '%s', game not saved", filename);
+ return;
}
- // Save game variables
- for (uint variable = 0; variable < 22; variable++) {
- int16 value = _script->getGameVar(variable);
- out->writeUint16LE(value);
- }
+ out->writeUint32LE(SAVEGAME_VERSION);
+
+ out->writeUint16LE(_cameraX);
+ out->writeUint16LE(_cameraY);
+ out->writeUint16LE(_cameraHeight);
+
+ out->writeUint16LE(_guiHeight);
+
+ out->writeUint16LE(_sceneWidth);
+ out->writeUint16LE(_sceneHeight);
+ out->writeUint32LE(_sceneResIndex);
+
+ out->writeUint16LE(_walkSpeedX);
+ out->writeUint16LE(_walkSpeedY);
+
+ out->writeUint32LE(_counter01);
+ out->writeUint32LE(_counter02);
+ out->writeByte(_movieSceneFlag ? 1 : 0);
+ out->writeByte(_flag01);
_palette->saveState(out);
_script->saveState(out);
_anim->saveState(out);
-
- // Save GUI
- {
-
- }
+ _screen->saveState(out);
/*
case 0: return "mouseDisabled";
case 1: return "mouseY";
case 2: return "mouseX";
case 3: return "mouseButton";
-case 4: return "verbLineY";
-case 5: return "verbLineX";
-case 6: return "verbLineWidth";
-case 7: return "verbLineCount";
-case 8: return "verbLineNum";
-case 9: return "talkTextItemNum";
-case 10: return "talkTextY";
-case 11: return "talkTextX";
-case 12: return "talkTextFontColor";
-case 13: return "cameraY";
-case 14: return "cameraX";
-case 15: return "walkSpeedY";
-case 16: return "walkSpeedX";
-case 17: return "flag01";
-case 18: return "sceneResIndex";
-case 19: return "cameraTop";
-case 20: return "sceneHeight";
-case 21: return "sceneWidth";
*/
/*
-PersistentGameVarRef <offset _sceneHeight, 2>
-PersistentGameVarRef <offset _sceneWidth, 2>
PersistentGameVarRef <offset screenFlag01, 2>
PersistentGameVarRef <offset currentSequenceResIndex, 4>
PersistentGameVarRef <offset currentSequenceLoopCount, 4>
PersistentGameVarRef <offset sequenceVolume, 4>
PersistentGameVarRef <offset dword_99AC0, 4>
-PersistentGameVarRef <offset verbLineNum, 22h>
*/
delete out;
@@ -108,7 +105,50 @@ PersistentGameVarRef <offset verbLineNum, 22h>
}
void ToltecsEngine::loadgame(const char *filename) {
-}
+ Common::InSaveFile *in;
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+ warning("Can't open file '%s', game not loaded", filename);
+ return;
+ }
+
+ uint32 version = in->readUint32LE();
+ if (version != SAVEGAME_VERSION) {
+ warning("Savegame '%s' too old, game not loaded (got v%d, need v%d)", filename, version, SAVEGAME_VERSION);
+ return;
+ }
+
+ _cameraX = in->readUint16LE();
+ _cameraY = in->readUint16LE();
+ _cameraHeight = in->readUint16LE();
+
+ _guiHeight = in->readUint16LE();
+
+ _sceneWidth = in->readUint16LE();
+ _sceneHeight = in->readUint16LE();
+ _sceneResIndex = in->readUint32LE();
+
+ _walkSpeedX = in->readUint16LE();
+ _walkSpeedY = in->readUint16LE();
+
+ _counter01 = in->readUint32LE();
+ _counter02 = in->readUint32LE();
+ _movieSceneFlag = in->readByte() != 0;
+ _flag01 = in->readByte();
+
+ _palette->loadState(in);
+ _script->loadState(in);
+ _anim->loadState(in);
+ _screen->loadState(in);
+
+ delete in;
+
+ loadScene(_sceneResIndex);
+ _screen->clearSprites();
+
+ _newCameraX = _cameraX;
+ _newCameraY = _cameraY;
+
+}
} // End of namespace Toltecs
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index a11022c..2ef4040 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -964,13 +964,105 @@ void Screen::drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch,
}
void Screen::saveState(Common::WriteStream *out) {
+
+ // Save verb line
+ out->writeUint16LE(_verbLineNum);
+ out->writeUint16LE(_verbLineX);
+ out->writeUint16LE(_verbLineY);
+ out->writeUint16LE(_verbLineWidth);
+ out->writeUint16LE(_verbLineCount);
for (int i = 0; i < 8; i++) {
out->writeUint16LE(_verbLineItems[i].slotIndex);
out->writeUint16LE(_verbLineItems[i].slotOffset);
}
+
+ // Save talk text items
+ out->writeUint16LE(_talkTextX);
+ out->writeUint16LE(_talkTextY);
+ out->writeUint16LE(_talkTextMaxWidth);
+ out->writeByte(_talkTextFontColor);
+ out->writeUint16LE(_talkTextItemNum);
+ for (int i = 0; i < 5; i++) {
+ out->writeUint16LE(_talkTextItems[i].duration);
+ out->writeUint16LE(_talkTextItems[i].slotIndex);
+ out->writeUint16LE(_talkTextItems[i].slotOffset);
+ out->writeUint16LE(_talkTextItems[i].fontNum);
+ out->writeByte(_talkTextItems[i].color);
+ out->writeByte(_talkTextItems[i].rectCount);
+ for (int j = 0; j < _talkTextItems[i].rectCount; j++) {
+ out->writeUint16LE(_talkTextItems[i].rects[j].x);
+ out->writeUint16LE(_talkTextItems[i].rects[j].y);
+ out->writeUint16LE(_talkTextItems[i].rects[j].width);
+ out->writeUint16LE(_talkTextItems[i].rects[j].length);
+ }
+ }
+
+ // Save GUI bitmap
+ {
+ byte *gui = _frontScreen + _vm->_cameraHeight * 640;
+ for (int i = 0; i < _vm->_guiHeight; i++) {
+ out->write(gui, 640);
+ gui += 640;
+ }
+ }
+
+ // Save fonts
+ for (int i = 0; i < 10; i++)
+ out->writeUint32LE(_fontResIndexArray[i]);
+ out->writeByte(_fontColor1);
+ out->writeByte(_fontColor2);
+
}
void Screen::loadState(Common::ReadStream *in) {
+
+ // Load verb line
+ _verbLineNum = in->readUint16LE();
+ _verbLineX = in->readUint16LE();
+ _verbLineY = in->readUint16LE();
+ _verbLineWidth = in->readUint16LE();
+ _verbLineCount = in->readUint16LE();
+ for (int i = 0; i < 8; i++) {
+ _verbLineItems[i].slotIndex = in->readUint16LE();
+ _verbLineItems[i].slotOffset = in->readUint16LE();
+ }
+
+ // Load talk text items
+ _talkTextX = in->readUint16LE();
+ _talkTextY = in->readUint16LE();
+ _talkTextMaxWidth = in->readUint16LE();
+ _talkTextFontColor = in->readByte();
+ _talkTextItemNum = in->readUint16LE();
+ for (int i = 0; i < 5; i++) {
+ _talkTextItems[i].duration = in->readUint16LE();
+ _talkTextItems[i].slotIndex = in->readUint16LE();
+ _talkTextItems[i].slotOffset = in->readUint16LE();
+ _talkTextItems[i].fontNum = in->readUint16LE();
+ _talkTextItems[i].color = in->readByte();
+ _talkTextItems[i].rectCount = in->readByte();
+ for (int j = 0; j < _talkTextItems[i].rectCount; j++) {
+ _talkTextItems[i].rects[j].x = in->readUint16LE();
+ _talkTextItems[i].rects[j].y = in->readUint16LE();
+ _talkTextItems[i].rects[j].width = in->readUint16LE();
+ _talkTextItems[i].rects[j].length = in->readUint16LE();
+ }
+ }
+
+ // Load GUI bitmap
+ {
+ byte *gui = _frontScreen + _vm->_cameraHeight * 640;
+ for (int i = 0; i < _vm->_guiHeight; i++) {
+ in->read(gui, 640);
+ gui += 640;
+ }
+ }
+
+ // Load fonts
+ for (int i = 0; i < 10; i++)
+ _fontResIndexArray[i] = in->readUint32LE();
+ _fontColor1 = in->readByte();
+ _fontColor2 = in->readByte();
+
}
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index fa38219..c71d5d2 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -1243,10 +1243,43 @@ void ScriptInterpreter::saveState(Common::WriteStream *out) {
// Save stack
out->write(_stack, kScriptStackSize);
out->writeUint16LE(_savedSp);
+
+ // Save IP
+ out->writeUint16LE((int16)(_code - getSlotData(_regs.reg4)));
}
void ScriptInterpreter::loadState(Common::ReadStream *in) {
+
+ // Load registers
+ _regs.reg0 = in->readUint16LE();
+ _regs.reg1 = in->readUint16LE();
+ _regs.reg2 = in->readUint16LE();
+ _regs.reg3 = in->readUint16LE();
+ _regs.reg4 = in->readUint16LE();
+ _regs.reg5 = in->readUint16LE();
+ _regs.reg6 = in->readUint16LE();
+ _regs.sp = in->readUint16LE();
+ _regs.reg8 = in->readUint16LE();
+
+ // Load slots
+ for (int slot = 0; slot < kMaxScriptSlots; slot++) {
+ _slots[slot].size = in->readUint32LE();
+ _slots[slot].resIndex = in->readUint16LE();
+ _slots[slot].data = NULL;
+ if (_slots[slot].size > 0) {
+ _slots[slot].data = new byte[_slots[slot].size];
+ in->read(_slots[slot].data, _slots[slot].size);
+ }
+ }
+
+ // Load stack
+ in->read(_stack, kScriptStackSize);
+ _savedSp = in->readUint16LE();
+
+ // Load IP
+ _code = getSlotData(_regs.reg4) + in->readUint16LE();
+
}
} // End of namespace Toltecs
Commit: 03cae511297588ccbeba028cab58c7be050ccac2
https://github.com/scummvm/scummvm/commit/03cae511297588ccbeba028cab58c7be050ccac2
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: - Made game "quittable"
- Save/load mouse position and if the cursor is enabled
Changed paths:
engines/toltecs/input.cpp
engines/toltecs/saveload.cpp
diff --git a/engines/toltecs/input.cpp b/engines/toltecs/input.cpp
index b658c62..1748183 100644
--- a/engines/toltecs/input.cpp
+++ b/engines/toltecs/input.cpp
@@ -79,6 +79,8 @@ void Input::update() {
break;
case Common::EVENT_QUIT:
+ // FIXME: Find a nicer way to quit
+ g_system->quit();
break;
case Common::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 42ef4a3..3da15f4 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -80,6 +80,10 @@ void ToltecsEngine::savegame(const char *filename) {
out->writeByte(_movieSceneFlag ? 1 : 0);
out->writeByte(_flag01);
+ out->writeUint16LE(_input->_mouseX);
+ out->writeUint16LE(_input->_mouseY);
+ out->writeUint16LE(_input->_mouseDisabled);
+
_palette->saveState(out);
_script->saveState(out);
_anim->saveState(out);
@@ -136,6 +140,13 @@ void ToltecsEngine::loadgame(const char *filename) {
_movieSceneFlag = in->readByte() != 0;
_flag01 = in->readByte();
+ _input->_mouseX = in->readUint16LE();
+ _input->_mouseY = in->readUint16LE();
+ _input->_mouseDisabled = in->readUint16LE();
+
+ _system->warpMouse(_input->_mouseX, _input->_mouseY);
+ _system->showMouse(_input->_mouseDisabled == 0);
+
_palette->loadState(in);
_script->loadState(in);
_anim->loadState(in);
Commit: d561cb7ae39ec7119c62aa24a093c32d4872a353
https://github.com/scummvm/scummvm/commit/d561cb7ae39ec7119c62aa24a093c32d4872a353
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Fixed tabs.
Changed paths:
engines/toltecs/input.cpp
diff --git a/engines/toltecs/input.cpp b/engines/toltecs/input.cpp
index 1748183..8b1fcf4 100644
--- a/engines/toltecs/input.cpp
+++ b/engines/toltecs/input.cpp
@@ -79,8 +79,8 @@ void Input::update() {
break;
case Common::EVENT_QUIT:
- // FIXME: Find a nicer way to quit
- g_system->quit();
+ // FIXME: Find a nicer way to quit
+ g_system->quit();
break;
case Common::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
Commit: f0c9e489feeed8df564e5eadb32a730ec21e35ba
https://github.com/scummvm/scummvm/commit/f0c9e489feeed8df564e5eadb32a730ec21e35ba
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Minor cleanup.
Changed paths:
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index f1b531f..d4b1a34 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -98,10 +98,10 @@ int ToltecsEngine::go() {
_cameraY = 0;
_newCameraX = 0;
_newCameraY = 0;
- _guiHeight = 26;
_cameraHeight = 0;
- _yetAnotherX = 0;
-
+
+ _guiHeight = 26;
+
_sceneWidth = 0;
_sceneHeight = 0;
@@ -280,36 +280,15 @@ void ToltecsEngine::scrollCameraRight(int16 delta) {
void ToltecsEngine::updateCamera() {
- _yetAnotherX = _newCameraX;
- if (_cameraX != _yetAnotherX) {
+ if (_cameraX != _newCameraX) {
//dirtyFullRefresh = -1;
+ _cameraX = _newCameraX;
}
- _cameraX = _yetAnotherX;
-
+
if (_cameraY != _newCameraY) {
- if (_cameraY < _newCameraY) {
- /*
- drawRequest.resIndex = -(cameraY - anotherY);
- drawRequest.y = cameraHeight + cameraY;
- drawRequest.x = cameraX;
- drawRequest.flags = 640;
- */
- debug(0, "ToltecsEngine::updateCamera() a: (%d, %d, %d, %d)",
- -(_cameraY - _newCameraY), _cameraHeight + _cameraY, _cameraX, 640);
- //dirtyFullRefresh = -1;
- } else {
- /*
- drawRequest.resIndex = cameraY - anotherY;
- drawRequest.y = anotherY;
- drawRequest.x = cameraX;
- drawRequest.flags = 640;
- */
- debug(0, "ToltecsEngine::updateCamera() b: (%d, %d, %d, %d)",
- _cameraY - _newCameraY, _newCameraY, _cameraX, 640);
- //dirtyFullRefresh = -1;
- }
+ //dirtyFullRefresh = -1;
+ _cameraY = _newCameraY;
}
- _cameraY = _newCameraY;
debug(0, "ToltecsEngine::checkCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 11ce767..3b5bd67 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -109,7 +109,6 @@ public:
uint _sceneResIndex;
int16 _sceneWidth, _sceneHeight;
- //byte _scenePalette[768];
bool _quitGame;
int _counter01, _counter02;
@@ -119,8 +118,8 @@ public:
// TODO: Move camera stuff into own Scene class
int16 _cameraX, _cameraY;
int16 _newCameraX, _newCameraY;
- int16 _guiHeight, _cameraHeight;
- int16 _yetAnotherX;
+ int16 _cameraHeight;
+ int16 _guiHeight;
bool _doSpeech, _doText;
Commit: 98ac7885acb82ae77b6eccbf2380d4326f758f28
https://github.com/scummvm/scummvm/commit/98ac7885acb82ae77b6eccbf2380d4326f758f28
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Merged drawChar and drawChar2
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 2ef4040..7bee7da 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -799,7 +799,8 @@ void Screen::drawTalkTextItems() {
if (ch == 0x20) {
x += font.getWidth();
} else {
- drawChar2(font, _frontScreen, x, item->rects[j].y, ch, item->color);
+ //drawChar2(font, _frontScreen, x, item->rects[j].y, ch, item->color);
+ drawChar(font, _frontScreen, x, item->rects[j].y, ch, item->color, true);
x += font.getCharWidth(ch) + font.getSpacing() - 1;
}
}
@@ -891,7 +892,8 @@ void Screen::drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint
if (ch <= 0x20) {
x += font.getWidth();
} else {
- drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color);
+ //drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color);
+ drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color, false);
x += font.getCharWidth(ch) + font.getSpacing() - 1;
yadd = -yadd;
}
@@ -899,9 +901,7 @@ void Screen::drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint
}
-// TODO: Merge drawChar and drawChar2
-
-void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color) {
+void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline) {
int16 charWidth, charHeight;
byte *charData;
@@ -919,43 +919,13 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
byte flags = charData[0] & 0xF0;
charData++;
lineWidth -= count;
- if (!(flags & 0x80) && (flags & 0x10)) {
- memset(dest, color, count);
- }
- dest += count;
- }
- dest += 640 - charWidth;
- }
-
-}
-
-void Screen::drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color) {
-
- int16 charWidth, charHeight;
- byte *charData;
-
- dest += x + (y * 640);
-
- charWidth = font.getCharWidth(ch);
- charHeight = font.getHeight() - 2;
- charData = font.getCharData(ch);
-
- while (charHeight--) {
- byte lineWidth = charWidth;
- while (lineWidth > 0) {
- byte count = charData[0] & 0x0F;
- byte flags = charData[0] & 0xF0;
- charData++;
- lineWidth -= count;
-
if ((flags & 0x80) == 0) {
- if ((flags & 0x10) == 0) {
- memset(dest, 0, count);
- } else {
+ if (flags & 0x10) {
memset(dest, color, count);
+ } else if (outline) {
+ memset(dest, 0, count);
}
}
-
dest += count;
}
dest += 640 - charWidth;
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index c34f44d..9ee5b86 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -324,9 +324,7 @@ public:
void printText(byte *textData);
void preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len);
void drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex);
- void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color);
- void drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color);
-
+ void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline);
void saveState(Common::WriteStream *out);
void loadState(Common::ReadStream *in);
Commit: 5660ff514852fbc8e09e223355c1d46270c5db41
https://github.com/scummvm/scummvm/commit/5660ff514852fbc8e09e223355c1d46270c5db41
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Implemented buildColorTransTable (still TODO) and shadow sprite drawing.
Changed paths:
engines/toltecs/palette.cpp
engines/toltecs/palette.h
engines/toltecs/screen.cpp
engines/toltecs/screen.h
engines/toltecs/script.cpp
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 9692538..2fb2f87 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -166,6 +166,51 @@ void Palette::clearFragments() {
_fragments.clear();
}
+void Palette::buildColorTransTable(byte limit, char deltaValue, byte mask) {
+
+ // TODO
+
+ byte r, g, b;
+
+ mask &= 7;
+
+ for (int i = 0; i < 256; i++) {
+
+ if (deltaValue < 0) {
+ // TODO
+ } else {
+ r = _mainPalette[i * 3 + 0];
+ g = _mainPalette[i * 3 + 1];
+ b = _mainPalette[i * 3 + 2];
+ if (MAX(r, MAX(b, g)) >= limit) {
+ if ((mask & 1) && r >= deltaValue)
+ r -= deltaValue;
+ if ((mask & 2) && g >= deltaValue)
+ g -= deltaValue;
+ if ((mask & 4) && b >= deltaValue)
+ b -= deltaValue;
+ }
+ }
+
+ int bestIndex = 0;
+ uint16 bestMatch = 0xFFFF;
+
+ for (int j = 0; j < 256; j++) {
+ byte distance = ABS(_mainPalette[j * 3 + 0] - r) + ABS(_mainPalette[j * 3 + 1] - g) + ABS(_mainPalette[j * 3 + 2] - b);
+ byte maxColor = MAX(_mainPalette[j * 3 + 0], MAX(_mainPalette[j * 3 + 1], _mainPalette[j * 3 + 2]));
+ uint16 match = (distance << 8) | maxColor;
+ if (match < bestMatch) {
+ bestMatch = match;
+ bestIndex = j;
+ }
+ }
+
+ _colorTransTable[i] = bestIndex;
+
+ }
+
+}
+
void Palette::saveState(Common::WriteStream *out) {
// Save currently active palette
diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h
index acc3407..6a2bb59 100644
--- a/engines/toltecs/palette.h
+++ b/engines/toltecs/palette.h
@@ -64,6 +64,9 @@ public:
uint16 findFragment(int16 id);
void clearFragments();
+ void buildColorTransTable(byte limit, char deltaValue, byte mask);
+ byte getColorTransPixel(byte pixel) const { return _colorTransTable[pixel]; }
+
byte *getMainPalette() { return _mainPalette; }
byte *getAnimPalette() { return _animPalette; }
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 7bee7da..e4bba63 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -500,6 +500,15 @@ void Screen::drawSprite(SpriteDrawItem *sprite) {
if (sprite->flags & 0x40) {
// TODO: Shadow sprites
+ if (sprite->flags & 1) {
+ SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else if (sprite->flags & 2) {
+ SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else {
+ drawSpriteCore(dest, spriteReader, sprite);
+ }
} else if (sprite->flags & 0x10) {
// 256 color sprite
drawSpriteCore(dest, spriteReader, sprite);
@@ -556,16 +565,25 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
}
}
- if (((sprite->flags & 0x10) && (packet.pixel != 0xFF)) || !(sprite->flags & 0x10) && (packet.pixel != 0)) {
+ if (((sprite->flags & 0x40) && (packet.pixel != 0)) ||
+ ((sprite->flags & 0x10) && (packet.pixel != 0xFF)) ||
+ !(sprite->flags & 0x10) && (packet.pixel != 0))
+ {
if (sprite->flags & 0x40) {
- } else if (sprite->flags & 0x10) {
- packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
+ while (packet.count--) {
+ *dest = _vm->_palette->getColorTransPixel(*dest);
+ dest += destInc;
+ }
} else {
- packet.pixel += sprite->baseColor - 1;
- }
- while (packet.count--) {
- *dest = packet.pixel;
- dest += destInc;
+ if (sprite->flags & 0x10) {
+ packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
+ } else {
+ packet.pixel += sprite->baseColor - 1;
+ }
+ while (packet.count--) {
+ *dest = packet.pixel;
+ dest += destInc;
+ }
}
} else {
dest += packet.count * destInc;
@@ -799,12 +817,12 @@ void Screen::drawTalkTextItems() {
if (ch == 0x20) {
x += font.getWidth();
} else {
- //drawChar2(font, _frontScreen, x, item->rects[j].y, ch, item->color);
drawChar(font, _frontScreen, x, item->rects[j].y, ch, item->color, true);
x += font.getCharWidth(ch) + font.getSpacing() - 1;
}
}
}
+
}
}
@@ -892,7 +910,6 @@ void Screen::drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint
if (ch <= 0x20) {
x += font.getWidth();
} else {
- //drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color);
drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color, false);
x += font.getCharWidth(ch) + font.getSpacing() - 1;
yadd = -yadd;
@@ -918,7 +935,6 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
byte count = charData[0] & 0x0F;
byte flags = charData[0] & 0xF0;
charData++;
- lineWidth -= count;
if ((flags & 0x80) == 0) {
if (flags & 0x10) {
memset(dest, color, count);
@@ -927,6 +943,7 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
}
}
dest += count;
+ lineWidth -= count;
}
dest += 640 - charWidth;
}
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 9ee5b86..8bc6407 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -136,10 +136,20 @@ public:
_curHeight = _sprite->origHeight;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
- if ((_sprite->flags & 0x40) || (_sprite->flags & 0x10)) {
+ if (_sprite->flags & 0x40) {
+ // shadow sprite
+ packet.count = _source[0] & 0x7F;
+ if (_source[0] & 0x80)
+ packet.pixel = 1;
+ else
+ packet.pixel = 0;
+ _source++;
+ } else if (_sprite->flags & 0x10) {
+ // 256-color sprite
packet.pixel = *_source++;
packet.count = *_source++;
} else {
+ // 16-color sprite
packet.count = _source[0] & 0x0F;
packet.pixel = (_source[0] & 0xF0) >> 4;
_source++;
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index c71d5d2..481c8a8 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -556,9 +556,10 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
break;
}
- case 16:// TODO
+ case 16:// ok
{
- debug(0, "o2_makeTransColorTable");
+ debug(0, "o2_buildColorTransTable(%d, %d, %d)", arg8(4), (char)arg8(3), arg8(5));
+ _vm->_palette->buildColorTransTable(arg8(4), (char)arg8(3), arg8(5));
break;
}
Commit: 74c05f6aa889290e5dde753206c6ae6c84b4d679
https://github.com/scummvm/scummvm/commit/74c05f6aa889290e5dde753206c6ae6c84b4d679
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: - Merged input.cpp with toltecs.cpp
- Kernel function 5 returns a random value; use ScummVM's RNG
Changed paths:
engines/toltecs/module.mk
engines/toltecs/saveload.cpp
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
index 1f249a8..541bf6b 100644
--- a/engines/toltecs/module.mk
+++ b/engines/toltecs/module.mk
@@ -3,7 +3,6 @@ MODULE := engines/toltecs
MODULE_OBJS = \
animation.o \
detection.o \
- input.o \
palette.o \
toltecs.o \
resource.o \
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 3da15f4..18dd237 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -34,7 +34,6 @@
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
-#include "toltecs/input.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
#include "toltecs/script.h"
@@ -80,9 +79,9 @@ void ToltecsEngine::savegame(const char *filename) {
out->writeByte(_movieSceneFlag ? 1 : 0);
out->writeByte(_flag01);
- out->writeUint16LE(_input->_mouseX);
- out->writeUint16LE(_input->_mouseY);
- out->writeUint16LE(_input->_mouseDisabled);
+ out->writeUint16LE(_mouseX);
+ out->writeUint16LE(_mouseY);
+ out->writeUint16LE(_mouseDisabled);
_palette->saveState(out);
_script->saveState(out);
@@ -140,12 +139,12 @@ void ToltecsEngine::loadgame(const char *filename) {
_movieSceneFlag = in->readByte() != 0;
_flag01 = in->readByte();
- _input->_mouseX = in->readUint16LE();
- _input->_mouseY = in->readUint16LE();
- _input->_mouseDisabled = in->readUint16LE();
+ _mouseX = in->readUint16LE();
+ _mouseY = in->readUint16LE();
+ _mouseDisabled = in->readUint16LE();
- _system->warpMouse(_input->_mouseX, _input->_mouseY);
- _system->showMouse(_input->_mouseDisabled == 0);
+ _system->warpMouse(_mouseX, _mouseY);
+ _system->showMouse(_mouseDisabled == 0);
_palette->loadState(in);
_script->loadState(in);
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 481c8a8..495b981 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -36,7 +36,6 @@
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
-#include "toltecs/input.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
#include "toltecs/script.h"
@@ -95,7 +94,7 @@ void ScriptInterpreter::runScript(uint slotIndex) {
while (1) {
if (_vm->_movieSceneFlag)
- _vm->_input->_mouseButton = 0;
+ _vm->_mouseButton = 0;
if (_switchLocalDataNear) {
_switchLocalDataNear = false;
@@ -459,9 +458,9 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
return;
if (!_vm->_movieSceneFlag)
- _vm->_input->update();
+ _vm->updateInput();
else
- _vm->_input->_mouseButton = 0;
+ _vm->_mouseButton = 0;
// TODO? Check keyb
@@ -486,8 +485,8 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 5:// ok
{
- debug(0, "o2_mouseDeltaStuff(%d)", arg16(3));
- localWrite16(arg16(5), _vm->_input->getMouseDeltaStuff(arg16(3)));
+ debug(0, "o2_getRandomNumber(%d)", arg16(3));
+ localWrite16(arg16(5), _vm->_rnd->getRandomNumber(arg16(3) - 1));
break;
}
@@ -616,10 +615,10 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
{
debug(0, "o2_findMouseInRectIndex1(offset: %d; slot: %d; elemSize: %d; var: %d; index: %d)", arg16(3), arg16(5), arg16(7), arg16(9), arg16(11));
int16 index = -1;
- if (_vm->_input->_mouseY < _vm->_cameraHeight) {
+ if (_vm->_mouseY < _vm->_cameraHeight) {
index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
- _vm->_input->_mouseX + _vm->_cameraX,
- _vm->_input->_mouseY + _vm->_cameraY,
+ _vm->_mouseX + _vm->_cameraX,
+ _vm->_mouseY + _vm->_cameraY,
arg16(11) + 1, arg16(7));
}
localWrite16(arg16(9), index);
@@ -631,7 +630,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
debug(0, "o2_findMouseInRectIndex2(offset: %d, slot: %d, elemSize: %d, var: %d)", arg16(3), arg16(5), arg16(7), arg16(9));
int16 index = -1;
- debug(0, "_vm->_input->_mouseDisabled = %d", _vm->_input->_mouseDisabled);
+ debug(0, "_vm->_mouseDisabled = %d", _vm->_mouseDisabled);
/* FIXME: This opcode is called after the Revistronic logo at the beginning,
but at the slot/offset there's bytecode and not a rect array as expected.
@@ -640,10 +639,10 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
Needs some more checking.
*/
if (_vm->_sceneResIndex != 215) {
- if (_vm->_input->_mouseY < _vm->_cameraHeight) {
+ if (_vm->_mouseY < _vm->_cameraHeight) {
index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
- _vm->_input->_mouseX + _vm->_cameraX,
- _vm->_input->_mouseY + _vm->_cameraY,
+ _vm->_mouseX + _vm->_cameraX,
+ _vm->_mouseY + _vm->_cameraY,
0, arg16(7));
}
}
@@ -993,16 +992,16 @@ int16 ScriptInterpreter::getGameVar(uint variable) {
switch (variable) {
case 0:
- value = _vm->_input->_mouseDisabled;
+ value = _vm->_mouseDisabled;
break;
case 1:
- value = _vm->_input->_mouseY;
+ value = _vm->_mouseY;
break;
case 2:
- value = _vm->_input->_mouseX;
+ value = _vm->_mouseX;
break;
case 3:
- value = _vm->_input->_mouseButton;
+ value = _vm->_mouseButton;
break;
case 4:
value = _vm->_screen->_verbLineY;
@@ -1073,11 +1072,11 @@ void ScriptInterpreter::setGameVar(uint variable, int16 value) {
switch (variable) {
case 0:
- _vm->_input->_mouseDisabled = value;
+ _vm->_mouseDisabled = value;
_vm->_system->showMouse(value == 0);
break;
case 3:
- _vm->_input->_mouseButton = value;
+ _vm->_mouseButton = value;
break;
case 4:
_vm->_screen->_verbLineY = value;
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index d4b1a34..9aa5ad3 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -39,7 +39,6 @@
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
-#include "toltecs/input.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
#include "toltecs/script.h"
@@ -111,6 +110,15 @@ int ToltecsEngine::go() {
_walkSpeedY = 5;
_walkSpeedX = 1;
+ _mouseX = 0;
+ _mouseY = 0;
+ _mouseCounter = 0;
+ _mouseButtonPressedFlag = false;
+ _mouseButton = 0;
+ _mouseDisabled = 0;
+ _leftButtonDown = false;
+ _rightButtonDown = false;
+
_arc = new ArchiveReader();
_arc->openArchive("WESTERN");
@@ -122,7 +130,6 @@ int ToltecsEngine::go() {
_anim = new AnimationPlayer(this);
_palette = new Palette(this);
_segmap = new SegmentMap(this);
- _input = new Input(this);
_system->showMouse(true);
@@ -140,7 +147,6 @@ int ToltecsEngine::go() {
delete _anim;
delete _palette;
delete _segmap;
- delete _input;
return 0;
}
@@ -203,6 +209,90 @@ void ToltecsEngine::updateScreen() {
updateCamera();
}
+void ToltecsEngine::updateInput() {
+
+ Common::Event event;
+ Common::EventManager *eventMan = _system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+
+ // FIXME: This is just for debugging
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_F6:
+ savegame("toltecs.001");
+ break;
+ case Common::KEYCODE_F9:
+ loadgame("toltecs.001");
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case Common::EVENT_QUIT:
+ // FIXME: Find a nicer way to quit
+ _system->quit();
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _leftButtonDown = true;
+ break;
+ case Common::EVENT_LBUTTONUP:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _leftButtonDown = false;
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _rightButtonDown = true;
+ break;
+ case Common::EVENT_RBUTTONUP:
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ _rightButtonDown = false;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (_mouseDisabled == 0) {
+
+ if (_mouseCounter > 0)
+ _mouseCounter--;
+
+ byte mouseButtons = 0;
+ if (_leftButtonDown)
+ mouseButtons |= 1;
+ if (_rightButtonDown)
+ mouseButtons |= 2;
+
+ if (mouseButtons != 0) {
+ if (!_mouseButtonPressedFlag) {
+ _mouseButton = mouseButtons;
+ if (_mouseCounter != 0)
+ _mouseButton |= 0x80;
+ _mouseCounter = 30; // maybe TODO
+ _mouseButtonPressedFlag = true;
+ } else {
+ _mouseButton = 0;
+ }
+ } else {
+ _mouseButtonPressedFlag = false;
+ _mouseButton = 0;
+ }
+
+ }
+
+}
+
void ToltecsEngine::setCamera(int16 x, int16 y) {
// TODO font_sub_4B5BB()
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 3b5bd67..3b38baf 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -78,6 +78,7 @@ public:
void loadScene(uint resIndex);
void updateScreen();
+ void updateInput();
void setCamera(int16 x, int16 y);
void setGuiHeight(int16 guiHeight);
@@ -125,6 +126,13 @@ public:
int16 _walkSpeedY, _walkSpeedX;
+ int16 _mouseX, _mouseY;
+ int16 _mouseCounter;
+ bool _mouseButtonPressedFlag;
+ byte _mouseButton;
+ int16 _mouseDisabled;
+ bool _leftButtonDown, _rightButtonDown;
+
};
} // End of namespace Toltecs
Commit: 32d958508b781eac110bd3a974a84ae08a2a7cfe
https://github.com/scummvm/scummvm/commit/32d958508b781eac110bd3a974a84ae08a2a7cfe
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Deleted obsolete files.
Changed paths:
R engines/toltecs/input.cpp
R engines/toltecs/input.h
diff --git a/engines/toltecs/input.cpp b/engines/toltecs/input.cpp
deleted file mode 100644
index 8b1fcf4..0000000
--- a/engines/toltecs/input.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- */
-
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
-#include "sound/mixer.h"
-
-#include "toltecs/toltecs.h"
-#include "toltecs/input.h"
-#include "toltecs/palette.h"
-#include "toltecs/resource.h"
-
-namespace Toltecs {
-
-Input::Input(ToltecsEngine *vm) : _vm(vm) {
-
- _mouseX = 0;
- _mouseY = 0;
- _mousePosDelta = 0;
- _mouseCounter = 0;
- _mouseButtonPressedFlag = false;
- _mouseButton = 0;
- _mouseDisabled = 0;
-
- _leftButtonDown = false;
- _rightButtonDown = false;
-
-}
-
-Input::~Input() {
-}
-
-void Input::update() {
-
- Common::Event event;
- Common::EventManager *eventMan = _vm->_system->getEventManager();
- while (eventMan->pollEvent(event)) {
- switch (event.type) {
- case Common::EVENT_KEYDOWN:
-
- // FIXME: This is just for debugging
- switch (event.kbd.keycode) {
- case Common::KEYCODE_F6:
- _vm->savegame("toltecs.001");
- break;
- case Common::KEYCODE_F9:
- _vm->loadgame("toltecs.001");
- break;
- default:
- break;
- }
-
- break;
- case Common::EVENT_QUIT:
- // FIXME: Find a nicer way to quit
- g_system->quit();
- break;
- case Common::EVENT_MOUSEMOVE:
- _mouseX = event.mouse.x;
- _mouseY = event.mouse.y;
- break;
- case Common::EVENT_LBUTTONDOWN:
- _mouseX = event.mouse.x;
- _mouseY = event.mouse.y;
- _leftButtonDown = true;
- break;
- case Common::EVENT_LBUTTONUP:
- _mouseX = event.mouse.x;
- _mouseY = event.mouse.y;
- _leftButtonDown = false;
- break;
- case Common::EVENT_RBUTTONDOWN:
- _mouseX = event.mouse.x;
- _mouseY = event.mouse.y;
- _rightButtonDown = true;
- break;
- case Common::EVENT_RBUTTONUP:
- _mouseX = event.mouse.x;
- _mouseY = event.mouse.y;
- _rightButtonDown = false;
- break;
- default:
- break;
- }
- }
-
- if (_mouseDisabled == 0) {
- _mousePosDelta = _mousePosDelta + _mouseY - _mouseX;
-
- if (_mouseCounter > 0)
- _mouseCounter--;
-
- byte mouseButtons = 0;
- if (_leftButtonDown)
- mouseButtons |= 1;
- if (_rightButtonDown)
- mouseButtons |= 2;
-
- if (mouseButtons != 0) {
- if (!_mouseButtonPressedFlag) {
- _mouseButton = mouseButtons;
- if (_mouseCounter != 0)
- _mouseButton |= 0x80;
- _mouseCounter = 30; // maybe TODO
- _mouseButtonPressedFlag = true;
- } else {
- _mouseButton = 0;
- }
- } else {
- _mouseButtonPressedFlag = false;
- _mouseButton = 0;
- }
-
- }
-
-}
-
-int16 Input::getMouseDeltaStuff(int16 divisor) {
- return ABS(_mousePosDelta % divisor);
-}
-
-} // End of namespace Toltecs
diff --git a/engines/toltecs/input.h b/engines/toltecs/input.h
deleted file mode 100644
index 06196b8..0000000
--- a/engines/toltecs/input.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- */
-
-#ifndef TOLTECS_INPUT_H
-#define TOLTECS_INPUT_H
-
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/array.h"
-
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
-#include "engines/engine.h"
-
-namespace Toltecs {
-
-class Input {
-public:
- Input(ToltecsEngine *vm);
- ~Input();
-
- void update();
-
- void enableMouse();
- void disableMouse();
-
- int16 getMouseDeltaStuff(int16 divisor);
-
-//protected:
-public:
- ToltecsEngine *_vm;
-
- int16 _mouseX, _mouseY;
- int16 _mousePosDelta;
- int16 _mouseCounter;
- bool _mouseButtonPressedFlag;
- byte _mouseButton;
- int16 _mouseDisabled;
-
- bool _leftButtonDown, _rightButtonDown;
-
-};
-
-} // End of namespace Toltecs
-
-#endif /* TOLTECS_INPUT_H */
Commit: c82349c1b825048a8a1b3a2397e443bcb63e215c
https://github.com/scummvm/scummvm/commit/c82349c1b825048a8a1b3a2397e443bcb63e215c
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Finished sprite clipping.
Changed paths:
engines/toltecs/screen.cpp
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index e4bba63..5964e53 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -271,7 +271,7 @@ void Screen::clearSprites() {
void Screen::addDrawRequest(const DrawRequest &drawRequest) {
int16 scaleValueX, scaleValueY;
- int16 spriteDraw_X, spriteDraw_Y;
+ int16 xoffs, yoffs;
byte *spriteData;
int16 frameNum;
@@ -290,6 +290,10 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
spriteData = _vm->_res->load(drawRequest.resIndex);
+ if (drawRequest.flags & 0x1000) {
+ sprite.flags |= 4;
+ }
+
if (drawRequest.flags & 0x2000) {
sprite.flags |= 0x10;
}
@@ -316,12 +320,12 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.origHeight = spriteFrameEntry.h;
if (drawRequest.flags & 0x1000) {
- spriteDraw_X = spriteFrameEntry.w - spriteFrameEntry.x;
+ xoffs = spriteFrameEntry.w - spriteFrameEntry.x;
} else {
- spriteDraw_X = spriteFrameEntry.x;
+ xoffs = spriteFrameEntry.x;
}
- spriteDraw_Y = spriteFrameEntry.y;
+ yoffs = spriteFrameEntry.y;
// If the sprite should be scaled we need to initialize some values now
@@ -341,22 +345,22 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.flags |= 2;
sprite.width = sprite.origWidth + scaleValueX;
sprite.height = sprite.origHeight + scaleValueY;
- spriteDraw_X += (spriteDraw_X * scaleValue) / 100;
- spriteDraw_Y += (spriteDraw_Y * scaleValue) / 100;
+ xoffs += (xoffs * scaleValue) / 100;
+ yoffs += (yoffs * scaleValue) / 100;
} else {
sprite.flags |= 1;
sprite.width = sprite.origWidth - scaleValueX;
sprite.height = sprite.origHeight - 1 - scaleValueY;
if (sprite.width <= 0 || sprite.height <= 0)
return;
- spriteDraw_X -= (spriteDraw_X * scaleValue) / 100;
- spriteDraw_Y -= (spriteDraw_Y * scaleValue) / 100;
+ xoffs -= (xoffs * scaleValue) / 100;
+ yoffs -= (yoffs * scaleValue) / 100;
}
}
- sprite.x -= spriteDraw_X;
- sprite.y -= spriteDraw_Y;
+ sprite.x -= xoffs;
+ sprite.y -= yoffs;
sprite.yerror = sprite.ydelta;
@@ -435,7 +439,6 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (drawRequest.flags & 0x1000) {
// Left border
- sprite.flags |= 4;
if (sprite.x - _vm->_cameraX < 0) {
sprite.width -= ABS(sprite.x - _vm->_cameraX);
if (sprite.width <= 0)
@@ -551,6 +554,9 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
byte *destp = dest;
int16 skipX = sprite->value1;
+ int16 w = sprite->width;
+ int16 h = sprite->height;
+
do {
status = reader.readPacket(packet);
@@ -565,6 +571,11 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
}
}
+ if (w - packet.count < 0)
+ packet.count = w;
+
+ w -= packet.count;
+
if (((sprite->flags & 0x40) && (packet.pixel != 0)) ||
((sprite->flags & 0x10) && (packet.pixel != 0xFF)) ||
!(sprite->flags & 0x10) && (packet.pixel != 0))
@@ -589,13 +600,20 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
dest += packet.count * destInc;
}
- if (status == kSrsEndOfLine) {
+ if (status == kSrsEndOfLine || w == 0) {
+ if (w == 0) {
+ while (status != kSrsEndOfLine) {
+ status = reader.readPacket(packet);
+ }
+ }
dest = destp + 640;
destp = dest;
skipX = sprite->value1;
+ w = sprite->width;
+ h--;
}
- } while (status != kSrsEndOfSprite);
+ } while (status != kSrsEndOfSprite && h > 0);
}
Commit: 59bbad2ac8c7851117130ae04c58120d5b49b866
https://github.com/scummvm/scummvm/commit/59bbad2ac8c7851117130ae04c58120d5b49b866
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Fixed clipping (the clipping of the right border with flipped sprites was buggy)
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 5964e53..569ed2e 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -136,8 +136,6 @@ void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
debug(0, "Screen::drawGuiImage() x = %d; y = %d; w = %d; h = %d; resIndex = %d", x, y, width, height, resIndex);
- //_vm->_arc->dump(resIndex, "gui");
-
while (workHeight > 0) {
int count = 1;
byte pixel = *imageData++;
@@ -435,43 +433,38 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (sprite.height <= 0)
return;
- sprite.value1 = 0;
-
+ sprite.skipX = 0;
+
if (drawRequest.flags & 0x1000) {
// Left border
if (sprite.x - _vm->_cameraX < 0) {
sprite.width -= ABS(sprite.x - _vm->_cameraX);
- if (sprite.width <= 0)
- return;
sprite.x = _vm->_cameraX;
}
// Right border
if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
sprite.flags |= 8;
- sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
- if (sprite.width <= 0)
- return;
- sprite.value1 = sprite.x + sprite.width - _vm->_cameraX - 640;
+ sprite.skipX = sprite.x + sprite.width - _vm->_cameraX - 640;
+ sprite.width -= sprite.skipX;
}
} else {
// Left border
if (sprite.x - _vm->_cameraX < 0) {
sprite.flags |= 8;
- sprite.width -= ABS(sprite.x - _vm->_cameraX);
- if (sprite.width <= 0)
- return;
- sprite.value1 = ABS(sprite.x - _vm->_cameraX);
+ sprite.skipX = ABS(sprite.x - _vm->_cameraX);
+ sprite.width -= sprite.skipX;
sprite.x = _vm->_cameraX;
}
// Right border
if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
sprite.flags |= 8;
sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
- if (sprite.width <= 0)
- return;
}
}
+ if (sprite.width <= 0)
+ return;
+
// Add sprite sorted by priority
Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin();
while (iter != _spriteDrawList.end() && (*iter).ybottom <= sprite.ybottom) {
@@ -492,13 +485,6 @@ void Screen::drawSprite(SpriteDrawItem *sprite) {
byte *source = _vm->_res->load(sprite->resIndex) + sprite->offset;
byte *dest = _frontScreen + (sprite->x - _vm->_cameraX) + (sprite->y - _vm->_cameraY) * 640;
- // FIXME: Temporary hack until proper clipping is implemented
- /*
- int16 dx = sprite->x - _vm->_cameraX, dy = sprite->y - _vm->_cameraY;
- if (dx < 0 || dy < 0 || dx + sprite->width >= 640 || dy + sprite->height >= 400)
- return;
- */
-
SpriteReader spriteReader(source, sprite);
if (sprite->flags & 0x40) {
@@ -536,23 +522,18 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
int16 destInc;
- /*
- if ((sprite->flags & 8))
- return;
- */
-
if (sprite->flags & 4) {
destInc = -1;
dest += sprite->width;
} else {
destInc = 1;
}
-
+
SpriteReaderStatus status;
PixelPacket packet;
byte *destp = dest;
- int16 skipX = sprite->value1;
+ int16 skipX = sprite->skipX;
int16 w = sprite->width;
int16 h = sprite->height;
@@ -600,15 +581,15 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
dest += packet.count * destInc;
}
- if (status == kSrsEndOfLine || w == 0) {
- if (w == 0) {
- while (status != kSrsEndOfLine) {
+ if (status == kSrsEndOfLine || w <= 0) {
+ if (w <= 0) {
+ while (status == kSrsPixelsLeft) {
status = reader.readPacket(packet);
}
}
dest = destp + 640;
destp = dest;
- skipX = sprite->value1;
+ skipX = sprite->skipX;
w = sprite->width;
h--;
}
@@ -708,8 +689,6 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
item->fontNum = 0;
item->color = _talkTextFontColor;
- //debug(0, "## _talkTextMaxWidth = %d", _talkTextMaxWidth);
-
x = CLIP<int16>(_talkTextX - _vm->_cameraX, 120, _talkTextMaxWidth);
y = CLIP<int16>(_talkTextY - _vm->_cameraY, 4, _vm->_cameraHeight - 16);
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 8bc6407..bb6da76 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -63,7 +63,7 @@ struct SpriteDrawItem {
uint32 offset;
int16 xdelta, ydelta;
uint16 flags;
- int16 value1, yerror;
+ int16 skipX, yerror;
int16 ybottom;
int16 baseColor;
};
Commit: e2b3a35486fb5261a2773f097d906d3e1b918f56
https://github.com/scummvm/scummvm/commit/e2b3a35486fb5261a2773f097d906d3e1b918f56
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Corrected debug output.
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 9aa5ad3..d85df45 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -380,7 +380,7 @@ void ToltecsEngine::updateCamera() {
_cameraY = _newCameraY;
}
- debug(0, "ToltecsEngine::checkCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
+ debug(0, "ToltecsEngine::updateCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
}
Commit: 2930003864ee02f675948a5e35cbf8ac8c4d744b
https://github.com/scummvm/scummvm/commit/2930003864ee02f675948a5e35cbf8ac8c4d744b
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Fixed a script bug (compare opcodes work on unsigned values). So far this caused one error I noticed when climbing up the ladder in the barn where the camera didn't scroll up properly, but now it's all fine.
Changed paths:
engines/toltecs/script.cpp
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 495b981..8f20b62 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -357,7 +357,6 @@ void ScriptInterpreter::execOpcode(byte opcode) {
break;
case 49:
ofs = readByte();
- debug(0, "49, len = %d", ofs);
_code += ofs;
break;
case 50:
@@ -383,22 +382,22 @@ void ScriptInterpreter::execOpcode(byte opcode) {
_code++;
break;
case 52:
- if (_regs.reg1 >= _regs.reg8)
+ if ((uint16)_regs.reg1 >= (uint16)_regs.reg8)
_code += 4;
_code++;
break;
case 53:
- if (_regs.reg1 <= _regs.reg8)
+ if ((uint16)_regs.reg1 <= (uint16)_regs.reg8)
_code += 4;
_code++;
break;
case 54:
- if (_regs.reg1 < _regs.reg8)
+ if ((uint16)_regs.reg1 < (uint16)_regs.reg8)
_code += 4;
_code++;
break;
case 55:
- if (_regs.reg1 > _regs.reg8)
+ if ((uint16)_regs.reg1 > (uint16)_regs.reg8)
_code += 4;
_code++;
break;
Commit: b287588149b796f28570b99af1f83ebd814bcde1
https://github.com/scummvm/scummvm/commit/b287588149b796f28570b99af1f83ebd814bcde1
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Clear the text duration first in updateTalkText before adding text lines (else the durations add up and the text stays on screen a really long time)
Changed paths:
engines/toltecs/screen.cpp
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 569ed2e..13e490b 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -719,6 +719,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
width = 0;
length = 0;
+ item->duration = 0;
item->rectCount = 0;
Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
Commit: bbf882016afb3fc47e161f4c8fc95101b89ca407
https://github.com/scummvm/scummvm/commit/bbf882016afb3fc47e161f4c8fc95101b89ca407
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:05-08:00
Commit Message:
TOLTECS: Fixed text command parsing in updateVerbLine
Changed paths:
engines/toltecs/screen.cpp
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 13e490b..3c73ca9 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -707,8 +707,8 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
durationModifier = textData[1];
textData += 2;
} else if (*textData < 0x0A) {
- item->fontNum = textData[1];
- textData += 2;
+ item->fontNum = textData[0];
+ textData += 1;
} else
break;
}
Commit: 3c326b5c40e0eb25f7d069fc809176874795b5a7
https://github.com/scummvm/scummvm/commit/3c326b5c40e0eb25f7d069fc809176874795b5a7
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Fixed bug in anim frame displaying.
Changed paths:
engines/toltecs/animation.cpp
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
index 5d60144..34a1848 100644
--- a/engines/toltecs/animation.cpp
+++ b/engines/toltecs/animation.cpp
@@ -64,6 +64,9 @@ void AnimationPlayer::start(uint resIndex) {
_vm->_arc->closeResource();
debug(1, "AnimationPlayer::start() width = %d; height = %d; frameCount = %d", _width, _height, _frameCount);
+
+ _vm->_sceneWidth = _width;
+ _vm->_sceneHeight = _height;
unpackFrame();
Commit: 367be5b3453a86aece7c259cacfa42cfaa07de74
https://github.com/scummvm/scummvm/commit/367be5b3453a86aece7c259cacfa42cfaa07de74
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Merged text drawing routines into drawString
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 3c73ca9..cad29dd 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -589,9 +589,9 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
}
dest = destp + 640;
destp = dest;
- skipX = sprite->skipX;
- w = sprite->width;
- h--;
+ skipX = sprite->skipX;
+ w = sprite->width;
+ h--;
}
} while (status != kSrsEndOfSprite && h > 0);
@@ -651,7 +651,7 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
byte ch = *sourceString--;
_tempStringLen1--;
len--;
- charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
+ charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
width -= charWidth;
}
width += charWidth;
@@ -659,9 +659,9 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
_tempStringLen1 -= len;
_tempStringLen2 = len + 1;
- drawString(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+ drawStringEx(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
- destString = _tempString;
+ destString = _tempString;
width = 0;
preprocessText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
@@ -674,7 +674,7 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
_tempStringLen1 -= len;
_tempStringLen2 = len;
- drawString(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+ drawStringEx(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
}
@@ -719,7 +719,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
width = 0;
length = 0;
- item->duration = 0;
+ item->duration = 0;
item->rectCount = 0;
Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
@@ -792,8 +792,6 @@ void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16
void Screen::drawTalkTextItems() {
- //debug(0, "## _talkTextItemNum = %d", _talkTextItemNum);
-
for (int16 i = 0; i <= _talkTextItemNum; i++) {
TalkTextItem *item = &_talkTextItems[i];
byte *text = _vm->_script->getSlotData(item->slotIndex) + item->slotOffset;
@@ -805,20 +803,10 @@ void Screen::drawTalkTextItems() {
if (item->duration < 0)
item->duration = 0;
- Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
for (byte j = 0; j < item->rectCount; j++) {
- int16 x = item->rects[j].x;
- for (byte pos = 0; pos < item->rects[j].length; pos++) {
- byte ch = *text++;
- if (ch < 0x20)
- continue;
- if (ch == 0x20) {
- x += font.getWidth();
- } else {
- drawChar(font, _frontScreen, x, item->rects[j].y, ch, item->color, true);
- x += font.getCharWidth(ch) + font.getSpacing() - 1;
- }
- }
+ drawString(item->rects[j].x, item->rects[j].y, item->color, _fontResIndexArray[item->fontNum],
+ text, item->rects[j].length, NULL, true);
+ text += item->rects[j].length;
}
}
@@ -862,7 +850,7 @@ void Screen::printText(byte *textData) {
int width = 0;
_tempStringLen1 = 0;
preprocessText(_fontResIndexArray[1], 640, width, textData, destString, _tempStringLen2);
- drawString(x - width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1]);
+ drawStringEx(x - width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1]);
}
} while (*textData != 0xFF);
@@ -889,31 +877,46 @@ void Screen::preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&
}
}
-void Screen::drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex) {
+void Screen::drawStringEx(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex) {
+
+ debug(0, "Screen::drawStringEx(%d, %d, %d, %d, %d) _tempStringLen1 = %d; _tempStringLen2 = %d", x, y, fontColor1, fontColor2, fontResIndex, _tempStringLen1, _tempStringLen2);
+
+ int16 ywobble = 1;
+
+ x = drawString(x + 1, y + _vm->_cameraHeight, fontColor1, fontResIndex, _tempString, _tempStringLen1, &ywobble, false);
+ x = drawString(x, y + _vm->_cameraHeight, fontColor2, fontResIndex, _tempString + _tempStringLen1, _tempStringLen2, &ywobble, false);
+
+}
- debug(0, "Screen::drawString(%d, %d, %d, %d, %d) _tempStringLen1 = %d; _tempStringLen2 = %d", x, y, fontColor1, fontColor2, fontResIndex, _tempStringLen1, _tempStringLen2);
+int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len, int16 *ywobble, bool outline) {
+
+ debug(0, "Screen::drawString(%d, %d, %d, %d)", x, y, color, fontResIndex);
Font font(_vm->_res->load(fontResIndex));
- byte color = fontColor1;
- byte *text = _tempString;
- byte len = _tempStringLen1 + _tempStringLen2;
- int16 yadd = 1;
-
- for (byte pos = 0; pos < len; pos++) {
- if (pos == _tempStringLen1) {
- color = fontColor2;
- }
+ if (len == -1)
+ len = strlen((char*)text);
+
+ int16 yadd = 0;
+ if (ywobble)
+ yadd = *ywobble;
+
+ while (len--) {
byte ch = *text++;
if (ch <= 0x20) {
x += font.getWidth();
} else {
- drawChar(font, _frontScreen, x + 1, y + _vm->_cameraHeight - yadd, ch, color, false);
+ drawChar(font, _frontScreen, x, y - yadd, ch, color, outline);
x += font.getCharWidth(ch) + font.getSpacing() - 1;
yadd = -yadd;
}
}
-
+
+ if (ywobble)
+ *ywobble = yadd;
+
+ return x;
+
}
void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline) {
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index bb6da76..cc0cc00 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -333,8 +333,11 @@ public:
void registerFont(uint fontIndex, uint resIndex);
void printText(byte *textData);
void preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len);
- void drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex);
+ void drawStringEx(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex);
+
+ int16 drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len = -1, int16 *ywobble = NULL, bool outline = false);
void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline);
+
void saveState(Common::WriteStream *out);
void loadState(Common::ReadStream *in);
Commit: 6a83d7d85136158329e3df2a705f09d189ee9e05
https://github.com/scummvm/scummvm/commit/6a83d7d85136158329e3df2a705f09d189ee9e05
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Cancel all talkText items when camera position is changed (fixes some crashes and odd behaviour)
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/screen.h
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index cad29dd..c74b4c5 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -817,6 +817,12 @@ int16 Screen::getTalkTextDuration() {
return _talkTextItems[_talkTextItemNum].duration;
}
+void Screen::finishTextDrawItems() {
+ for (int16 i = 0; i <= _talkTextItemNum; i++) {
+ _talkTextItems[i].duration = 0;
+ }
+}
+
void Screen::registerFont(uint fontIndex, uint resIndex) {
_fontResIndexArray[fontIndex] = resIndex;
}
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index cc0cc00..a30c863 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -328,6 +328,7 @@ public:
void addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item);
void drawTalkTextItems();
int16 getTalkTextDuration();
+ void finishTextDrawItems();
// Font/text
void registerFont(uint fontIndex, uint resIndex);
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index d85df45..6bc1340 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -188,8 +188,11 @@ void ToltecsEngine::loadScene(uint resIndex) {
}
void ToltecsEngine::updateScreen() {
- // TODO
+ // FIXME: Quick hack, sometimes cameraY was negative (the code in updateCamera was at fault)
+ if (_cameraY < 0) _cameraY = 0;
+
+ // TODO: Optimize redraw by using dirty rectangles
byte *destp = _screen->_frontScreen;
byte *srcp = _screen->_backScreen + _cameraX + _cameraY * _sceneWidth;
for (uint y = 0; y < MIN<uint>(_cameraHeight, 400); y++) {
@@ -295,13 +298,17 @@ void ToltecsEngine::updateInput() {
void ToltecsEngine::setCamera(int16 x, int16 y) {
- // TODO font_sub_4B5BB()
-
+ _screen->finishTextDrawItems();
+
+ /*
+ // TODO: Fix checks; sometimes cameraY ended up being negative
+
if (x > _sceneWidth)
x = _sceneWidth;
if (y > _sceneHeight - _cameraHeight)
y = _sceneHeight - _cameraHeight;
+ */
// TODO DirtyRect clearing stuff
@@ -332,7 +339,7 @@ void ToltecsEngine::scrollCameraUp(int16 delta) {
_newCameraY = 0;
else
_newCameraY -= delta;
- // TODO: font_sub_4B5BB();
+ _screen->finishTextDrawItems();
}
}
@@ -343,7 +350,7 @@ void ToltecsEngine::scrollCameraDown(int16 delta) {
delta += (_sceneHeight - _cameraHeight) - (delta + _newCameraY);
_newCameraY += delta;
debug(0, "ToltecsEngine::scrollCameraDown() _newCameraY = %d; delta = %d", _newCameraY, delta);
- // TODO: font_sub_4B5BB();
+ _screen->finishTextDrawItems();
}
}
@@ -353,7 +360,7 @@ void ToltecsEngine::scrollCameraLeft(int16 delta) {
_newCameraX = 0;
else
_newCameraX -= delta;
- // TODO: font_sub_4B5BB();
+ _screen->finishTextDrawItems();
}
}
@@ -364,7 +371,7 @@ void ToltecsEngine::scrollCameraRight(int16 delta) {
delta += (_sceneWidth - 640) - (delta + _newCameraX);
_newCameraX += delta;
debug(0, "ToltecsEngine::scrollCameraRight() _newCameraX = %d; delta = %d", _newCameraY, delta);
- // TODO: font_sub_4B5BB();
+ _screen->finishTextDrawItems();
}
}
Commit: a94503765df942411d8ec6cf87fb26ead1e904db
https://github.com/scummvm/scummvm/commit/a94503765df942411d8ec6cf87fb26ead1e904db
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: - Fixed setDeltaPalette (sprites at night now look correct)
- Renamed TalkTextItem.rects/rectCount to lines/lineCount
- Workaround for font glitch in updateTalkText (text sets invalid font number)
Changed paths:
engines/toltecs/palette.cpp
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 2fb2f87..4d0f13f 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -81,31 +81,18 @@ void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 c
count++;
- mask &= 7;
-
_vm->_system->grabPalette(colors, 0, 256);
-
- if (deltaValue < 0) {
- deltaValue = -deltaValue;
- while (count--) {
- rgb = *palPtr++;
- if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
- rgb = *palPtr++;
- if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
- rgb = *palPtr++;
- if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
- index++;
- }
- } else {
- while (count--) {
- rgb = *palPtr++;
- if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
- rgb = *palPtr++;
- if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
- rgb = *palPtr++;
- if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb - deltaValue, deltaValue, 255) << 2;
- index++;
- }
+
+ deltaValue *= -1;
+
+ while (count--) {
+ rgb = *palPtr++;
+ if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ rgb = *palPtr++;
+ if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ rgb = *palPtr++;
+ if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ index++;
}
debug(0, "startIndex = %d; colorCount = %d", startIndex, colorCount);
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index c74b4c5..a80c22a 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -708,6 +708,9 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
textData += 2;
} else if (*textData < 0x0A) {
item->fontNum = textData[0];
+ // FIXME: Some texts request a font which isn't registered so we change it to a font that is
+ if (_fontResIndexArray[item->fontNum] == 0)
+ item->fontNum = 0;
textData += 1;
} else
break;
@@ -720,7 +723,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
length = 0;
item->duration = 0;
- item->rectCount = 0;
+ item->lineCount = 0;
Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
int16 wordLength, wordWidth;
@@ -762,7 +765,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
addTalkTextRect(font, x, y, length, width, item);
- debug(0, "## item->rectCount = %d", item->rectCount);
+ debug(0, "## item->lineCount = %d", item->lineCount);
int16 textDurationMultiplier = item->duration + 8;
// TODO: Check sound/text flags
@@ -776,14 +779,14 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item) {
if (width > 0) {
- TextRect *textRect = &item->rects[item->rectCount];
+ TextRect *textRect = &item->lines[item->lineCount];
width = width + 1 - font.getSpacing();
textRect->width = width;
item->duration += length;
textRect->length = length;
textRect->y = y;
textRect->x = CLIP<int16>(x - width / 2, 0, 640);
- item->rectCount++;
+ item->lineCount++;
}
y += font.getHeight() - 1;
@@ -803,10 +806,10 @@ void Screen::drawTalkTextItems() {
if (item->duration < 0)
item->duration = 0;
- for (byte j = 0; j < item->rectCount; j++) {
- drawString(item->rects[j].x, item->rects[j].y, item->color, _fontResIndexArray[item->fontNum],
- text, item->rects[j].length, NULL, true);
- text += item->rects[j].length;
+ for (byte j = 0; j < item->lineCount; j++) {
+ drawString(item->lines[j].x, item->lines[j].y, item->color, _fontResIndexArray[item->fontNum],
+ text, item->lines[j].length, NULL, true);
+ text += item->lines[j].length;
}
}
@@ -982,12 +985,12 @@ void Screen::saveState(Common::WriteStream *out) {
out->writeUint16LE(_talkTextItems[i].slotOffset);
out->writeUint16LE(_talkTextItems[i].fontNum);
out->writeByte(_talkTextItems[i].color);
- out->writeByte(_talkTextItems[i].rectCount);
- for (int j = 0; j < _talkTextItems[i].rectCount; j++) {
- out->writeUint16LE(_talkTextItems[i].rects[j].x);
- out->writeUint16LE(_talkTextItems[i].rects[j].y);
- out->writeUint16LE(_talkTextItems[i].rects[j].width);
- out->writeUint16LE(_talkTextItems[i].rects[j].length);
+ out->writeByte(_talkTextItems[i].lineCount);
+ for (int j = 0; j < _talkTextItems[i].lineCount; j++) {
+ out->writeUint16LE(_talkTextItems[i].lines[j].x);
+ out->writeUint16LE(_talkTextItems[i].lines[j].y);
+ out->writeUint16LE(_talkTextItems[i].lines[j].width);
+ out->writeUint16LE(_talkTextItems[i].lines[j].length);
}
}
@@ -1033,12 +1036,12 @@ void Screen::loadState(Common::ReadStream *in) {
_talkTextItems[i].slotOffset = in->readUint16LE();
_talkTextItems[i].fontNum = in->readUint16LE();
_talkTextItems[i].color = in->readByte();
- _talkTextItems[i].rectCount = in->readByte();
- for (int j = 0; j < _talkTextItems[i].rectCount; j++) {
- _talkTextItems[i].rects[j].x = in->readUint16LE();
- _talkTextItems[i].rects[j].y = in->readUint16LE();
- _talkTextItems[i].rects[j].width = in->readUint16LE();
- _talkTextItems[i].rects[j].length = in->readUint16LE();
+ _talkTextItems[i].lineCount = in->readByte();
+ for (int j = 0; j < _talkTextItems[i].lineCount; j++) {
+ _talkTextItems[i].lines[j].x = in->readUint16LE();
+ _talkTextItems[i].lines[j].y = in->readUint16LE();
+ _talkTextItems[i].lines[j].width = in->readUint16LE();
+ _talkTextItems[i].lines[j].length = in->readUint16LE();
}
}
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index a30c863..ec90d52 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -291,8 +291,8 @@ struct TalkTextItem {
int16 slotOffset;
int16 fontNum;
byte color;
- byte rectCount;
- TextRect rects[15];
+ byte lineCount;
+ TextRect lines[15];
};
class Screen {
Commit: be69bb986f82043911d160f941b252085cddef92
https://github.com/scummvm/scummvm/commit/be69bb986f82043911d160f941b252085cddef92
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Added TODO/NOTES/BUGS text
Also: The game is completable with this revision! (yay!:)
Changed paths:
A engines/toltecs/TODO.txt
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
new file mode 100644
index 0000000..cf4a199
--- /dev/null
+++ b/engines/toltecs/TODO.txt
@@ -0,0 +1,30 @@
+NOTES
+-------
+
+- The game is completable with revision 20 with some minor glitches (see BUGS).
+
+
+TODO
+------
+
+- Rewrite the resource system to something similar as used by M4
+ - each resource type gets its own class, the resource cache manages the resource instances
+ - generic resource class which has a method that creates a MemoryReadStream
+ - rewrite parts of the engine to use the new resource system
+- Add movie playback functionality (movie format is known, needs implementing)
+- Add sound support (after rewrite of the resource system)
+- Add music support (game seems to use XMIDI, MIDI and headerless music...figure out more)
+- Add game menu
+ - Rewrite from scratch with only minor stuff from the disasm since the original menu is one huge
+ messy function
+- Extend savegame format (savegame version, description, more data)
+- When saving a game, save the whole screen when an animation is playing
+- Implement dirty rectangles (low priority)
+- Optimize segment mask redrawing (only redraw what's neccessary)
+
+BUGS
+------
+
+- Still some clipping issues (walking upstairs in the saloon, when on top of the tower in the hideout)
+- Crashes sometimes on scene changes
+ (I guess because some talktext is still running although the slot used by it has changed)
Commit: 3eb449f236982ac201b30e0d4b939c7d324e8467
https://github.com/scummvm/scummvm/commit/3eb449f236982ac201b30e0d4b939c7d324e8467
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Add Russian version detection which works great.
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 37c1ec4..39915a5 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -67,6 +67,18 @@ static const ToltecsGameDescription gameDescriptions[] = {
},
},
+
+ {
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "ba1742d3193b68ceb9434e2ab7a09a9b", 391462783),
+ Common::RU_RUS,
+ Common::kPlatformPC,
+ Common::ADGF_NO_FLAGS
+ },
+ },
+
{ AD_TABLE_END_MARKER }
};
Commit: aaded0f5465336a1f5f9ea264c1b0efd878187ef
https://github.com/scummvm/scummvm/commit/aaded0f5465336a1f5f9ea264c1b0efd878187ef
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Added Screen::getTextWidth
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index a80c22a..612aaff 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -715,7 +715,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
} else
break;
}
-
+
item->slotIndex = slotIndex;
item->slotOffset = textData - _vm->_script->getSlotData(slotIndex);
@@ -762,7 +762,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
}
}
}
-
+
addTalkTextRect(font, x, y, length, width, item);
debug(0, "## item->lineCount = %d", item->lineCount);
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index ec90d52..655256b 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -103,6 +103,19 @@ public:
byte *getCharData(byte ch) const {
return _fontData + 0x298 + READ_LE_UINT16(&_fontData[0xE0 + (ch - 0x21) * 2]);
}
+ int16 getTextWidth(byte *text) {
+ int16 width = 0;
+ while (*text && *text < 0xF0) {
+ byte ch = *text++;
+ if (ch <= 0x20) {
+ width += getWidth();
+ } else {
+ width += getCharWidth(ch) + getSpacing() - 1;
+ }
+ }
+ return width;
+ }
+
protected:
byte *_fontData;
};
Commit: 398d0daac0c41cdd3db7c7ba8e865a791df170ff
https://github.com/scummvm/scummvm/commit/398d0daac0c41cdd3db7c7ba8e865a791df170ff
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Adjust y position of talk text lines.
Changed paths:
engines/toltecs/screen.cpp
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 612aaff..8427757 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -767,6 +767,14 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
debug(0, "## item->lineCount = %d", item->lineCount);
+ if (item->lineCount > 0) {
+ int16 ysub = (font.getHeight() - 1) * item->lineCount;
+ if (item->lines[0].y - 4 < ysub)
+ ysub = item->lines[0].y - 4;
+ for (int16 l = 0; l < item->lineCount; l++)
+ item->lines[l].y -= ysub;
+ }
+
int16 textDurationMultiplier = item->duration + 8;
// TODO: Check sound/text flags
if (*textData == 0xFE) {
Commit: 20d60e6286fdaa1ffd62bcc5deae3b69e281047d
https://github.com/scummvm/scummvm/commit/20d60e6286fdaa1ffd62bcc5deae3b69e281047d
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Renamed some functions.
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 8427757..988e931 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -488,7 +488,7 @@ void Screen::drawSprite(SpriteDrawItem *sprite) {
SpriteReader spriteReader(source, sprite);
if (sprite->flags & 0x40) {
- // TODO: Shadow sprites
+ // Shadow sprites
if (sprite->flags & 1) {
SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
@@ -640,14 +640,14 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
for (int16 i = 0; i <= _verbLineNum; i++) {
sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
- preprocessText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
+ wrapGuiText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
_tempStringLen1 += len;
}
if (_verbLineCount != 1) {
int16 charWidth;
if (*sourceString < 0xF0) {
- while (*sourceString > 0x20 && *sourceString < 0xF0 && len > 0/*CHECKME, len check added*/) {
+ while (*sourceString > 0x20 && *sourceString < 0xF0 && len > 0) {
byte ch = *sourceString--;
_tempStringLen1--;
len--;
@@ -659,11 +659,11 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
_tempStringLen1 -= len;
_tempStringLen2 = len + 1;
- drawStringEx(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+ drawGuiText(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
destString = _tempString;
width = 0;
- preprocessText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
+ wrapGuiText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
_tempStringLen1 += len;
y += 9;
@@ -674,7 +674,7 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
_tempStringLen1 -= len;
_tempStringLen2 = len;
- drawStringEx(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+ drawGuiText(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
}
@@ -838,7 +838,7 @@ void Screen::registerFont(uint fontIndex, uint resIndex) {
_fontResIndexArray[fontIndex] = resIndex;
}
-void Screen::printText(byte *textData) {
+void Screen::drawGuiTextMulti(byte *textData) {
int16 x = 0, y = 0;
@@ -866,15 +866,15 @@ void Screen::printText(byte *textData) {
byte *destString = _tempString;
int width = 0;
_tempStringLen1 = 0;
- preprocessText(_fontResIndexArray[1], 640, width, textData, destString, _tempStringLen2);
- drawStringEx(x - width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1]);
+ wrapGuiText(_fontResIndexArray[1], 640, width, textData, destString, _tempStringLen2);
+ drawGuiText(x - width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1]);
}
} while (*textData != 0xFF);
}
-void Screen::preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len) {
+void Screen::wrapGuiText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len) {
Font font(_vm->_res->load(fontResIndex));
@@ -894,9 +894,9 @@ void Screen::preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&
}
}
-void Screen::drawStringEx(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex) {
+void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex) {
- debug(0, "Screen::drawStringEx(%d, %d, %d, %d, %d) _tempStringLen1 = %d; _tempStringLen2 = %d", x, y, fontColor1, fontColor2, fontResIndex, _tempStringLen1, _tempStringLen2);
+ debug(0, "Screen::drawGuiText(%d, %d, %d, %d, %d) _tempStringLen1 = %d; _tempStringLen2 = %d", x, y, fontColor1, fontColor2, fontResIndex, _tempStringLen1, _tempStringLen2);
int16 ywobble = 1;
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 655256b..f7adc22 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -345,9 +345,9 @@ public:
// Font/text
void registerFont(uint fontIndex, uint resIndex);
- void printText(byte *textData);
- void preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len);
- void drawStringEx(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex);
+ void drawGuiTextMulti(byte *textData);
+ void wrapGuiText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len);
+ void drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex);
int16 drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len = -1, int16 *ywobble = NULL, bool outline = false);
void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline);
Commit: d09fbbabe66b583d06482a5b25f46b2eebf63d1e
https://github.com/scummvm/scummvm/commit/d09fbbabe66b583d06482a5b25f46b2eebf63d1e
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: - Added menu system prototype (may change later)
- Added movie player (still incomplete, sound is not yet implemented)
Both are not yet hooked to the engine.
- Added code for microtile arrays (from the SEL - Simple DirectMedia Layer Extension Library project), under the LGPL
This will be used as dirty rectangle "manager". This is experimental for now, it may be removed later.
Changed paths:
A engines/toltecs/menu.cpp
A engines/toltecs/menu.h
A engines/toltecs/microtiles.cpp
A engines/toltecs/microtiles.h
A engines/toltecs/movie.cpp
A engines/toltecs/movie.h
engines/toltecs/module.mk
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
new file mode 100644
index 0000000..9061ff5
--- /dev/null
+++ b/engines/toltecs/menu.cpp
@@ -0,0 +1,250 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/menu.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+
+namespace Toltecs {
+
+// This code is very experimental.
+
+Widget::Widget(ToltecsEngine *vm, int x, int y) : _vm(vm) {
+ _rect.left = x;
+ _rect.top = y;
+}
+
+Widget::~Widget() {
+}
+
+void Widget::redraw() {
+}
+
+Widget *Widget::getHoveredWidget(int mouseX, int mouseY) {
+ if (_rect.contains(mouseX, mouseY))
+ return this;
+ else
+ return NULL;
+}
+
+void Widget::calcDimensions() {
+}
+
+void Widget::setRect(Common::Rect rect) {
+ _rect = rect;
+}
+
+void Widget::onMouseEnter() {
+}
+
+void Widget::onMouseLeave() {
+}
+
+void Widget::onMouseMove(int mouseX, int mouseY) {
+}
+
+LabelWidget::LabelWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags) :
+ Widget(vm, x, y), _caption(caption), _flags(flags), _fontColor(kFontColorMenuDefault) {
+
+ calcDimensions();
+
+}
+
+LabelWidget::~LabelWidget() {
+}
+
+void LabelWidget::redraw() {
+ _vm->_screen->drawString(_rect.left, _rect.top, _fontColor, 14, (byte*)_caption.c_str(), -1, NULL, true);
+}
+
+void LabelWidget::calcDimensions() {
+ Font font(_vm->_res->load(14));
+ _rect.setWidth(font.getTextWidth((byte*)_caption.c_str()));
+ _rect.setHeight(font.getHeight());
+}
+
+void LabelWidget::setCaption(Common::String caption) {
+ _caption = caption;
+ calcDimensions();
+}
+
+void LabelWidget::setFontColor(byte fontColor) {
+ _fontColor = fontColor;
+}
+
+void LabelWidget::onMouseEnter() {
+ setFontColor(kFontColorMenuActive);
+}
+
+void LabelWidget::onMouseLeave() {
+ setFontColor(kFontColorMenuDefault);
+}
+
+
+VolumeControlWidget::VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags) :
+ Widget(_vm, x, y), _activeWidget(NULL) {
+
+ _label = new LabelWidget(vm, x, y, caption, flags);
+ _up = new LabelWidget(vm, x + 350, y + 4, "[", flags);
+ _down = new LabelWidget(vm, x + 350 + 24, y + 4, "]", flags);
+ _indicator = new LabelWidget(vm, x + 350 + 24 + 24 + 8, y, "||||||||||", flags);
+
+ _rect.setWidth(350 + 24 + 24 + 8 + 50);
+ _rect.setHeight(20);
+
+}
+
+VolumeControlWidget::~VolumeControlWidget() {
+ delete _label;
+ delete _up;
+ delete _down;
+ delete _indicator;
+}
+
+void VolumeControlWidget::redraw() {
+ _label->redraw();
+ _up->redraw();
+ _down->redraw();
+ _indicator->redraw();
+}
+
+Widget *VolumeControlWidget::getHoveredWidget(int mouseX, int mouseY) {
+ return Widget::getHoveredWidget(mouseX, mouseY);
+}
+
+void VolumeControlWidget::calcDimensions() {
+}
+
+void VolumeControlWidget::onMouseEnter() {
+ _label->setFontColor(kFontColorMenuActive);
+ _indicator->setFontColor(kFontColorMenuActive);
+ _activeWidget = NULL;
+}
+
+void VolumeControlWidget::onMouseLeave() {
+ _label->setFontColor(kFontColorMenuDefault);
+ _up->setFontColor(kFontColorMenuDefault);
+ _down->setFontColor(kFontColorMenuDefault);
+ _indicator->setFontColor(kFontColorMenuDefault);
+}
+
+void VolumeControlWidget::onMouseMove(int mouseX, int mouseY) {
+
+ Widget *hoveredWidget = NULL;
+
+ hoveredWidget = _up->getHoveredWidget(mouseX, mouseY);
+ if (!hoveredWidget)
+ hoveredWidget = _down->getHoveredWidget(mouseX, mouseY);
+
+ if (_activeWidget != hoveredWidget) {
+ _activeWidget = hoveredWidget;
+ if (!_activeWidget) {
+ _up->setFontColor(kFontColorMenuDefault);
+ _down->setFontColor(kFontColorMenuDefault);
+ } else if (_activeWidget == _up) {
+ _up->setFontColor(kFontColorMenuActive);
+ _down->setFontColor(kFontColorMenuDefault);
+ } else if (_activeWidget == _down) {
+ _up->setFontColor(kFontColorMenuDefault);
+ _down->setFontColor(kFontColorMenuActive);
+ }
+ }
+
+}
+
+MenuPage::MenuPage(Common::String caption) {
+}
+
+MenuPage::~MenuPage() {
+ // TODO: Delete widgets
+}
+
+void MenuPage::addWidget(Widget *widget) {
+ _widgets.push_back(widget);
+}
+
+void MenuPage::redraw() {
+ for (WidgetArray::iterator iter = _widgets.begin(); iter != _widgets.end(); iter++) {
+ (*iter)->redraw();
+ }
+}
+
+Widget *MenuPage::getHoveredWidget(int mouseX, int mouseY) {
+ Widget *hoveredWidget = NULL;
+ for (WidgetArray::iterator iter = _widgets.begin(); iter != _widgets.end() && !hoveredWidget; iter++) {
+ hoveredWidget = (*iter)->getHoveredWidget(mouseX, mouseY);
+ }
+ return hoveredWidget;
+}
+
+MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm), _activeWidget(NULL), _oldMouseX(-1), _oldMouseY(-1) {
+ _page = new MenuPage("Welcome");
+ _page->addWidget(new LabelWidget(_vm, 10, 10, "Load game", 0));
+ _page->addWidget(new LabelWidget(_vm, 10, 35, "Save game", 0));
+ _page->addWidget(new VolumeControlWidget(_vm, 10, 60, "Master volume", 0));
+ _page->addWidget(new VolumeControlWidget(_vm, 10, 90, "Some other volume", 0));
+}
+
+MenuSystem::~MenuSystem() {
+ delete _page;
+}
+
+void MenuSystem::update() {
+
+ _page->redraw();
+
+ if (_vm->_mouseX != _oldMouseX || _vm->_mouseY != _oldMouseY) {
+
+ _oldMouseX = _vm->_mouseX;
+ _oldMouseY = _vm->_mouseY;
+
+ Widget *hoveredWidget = _page->getHoveredWidget(_vm->_mouseX, _vm->_mouseY);
+ if (_activeWidget != hoveredWidget) {
+ if (_activeWidget)
+ _activeWidget->onMouseLeave();
+ if (hoveredWidget)
+ hoveredWidget->onMouseEnter();
+ _activeWidget = hoveredWidget;
+ }
+
+ if (_activeWidget) {
+ _activeWidget->onMouseMove(_vm->_mouseX, _vm->_mouseY);
+ }
+
+ }
+
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
new file mode 100644
index 0000000..15b73b7
--- /dev/null
+++ b/engines/toltecs/menu.h
@@ -0,0 +1,140 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_MENU_H
+#define TOLTECS_MENU_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/str.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+const byte kFontColorMenuDefault = 229;
+const byte kFontColorMenuActive = 255;
+
+class Widget {
+public:
+ Widget(ToltecsEngine *vm, int x, int y);
+ virtual ~Widget();
+ virtual void redraw();
+ virtual Widget *getHoveredWidget(int mouseX, int mouseY);
+ virtual void calcDimensions();
+ void setRect(Common::Rect rect);
+ //virtual void setHilighted(bool active);
+ virtual void onMouseEnter();
+ virtual void onMouseLeave();
+ virtual void onMouseMove(int mouseX, int mouseY);
+protected:
+ ToltecsEngine *_vm;
+ Common::Rect _rect;
+ //bool _hilighted;
+};
+
+const int kLabelCentered = 1 << 1;
+const int kLabelHideOnMovie = 1 << 2;
+
+class LabelWidget : public Widget {
+public:
+ LabelWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags);
+ ~LabelWidget();
+ void redraw();
+ void calcDimensions();
+ void setCaption(Common::String caption);
+ void setFontColor(byte fontColor);
+ void onMouseEnter();
+ void onMouseLeave();
+protected:
+ Common::String _caption;
+ uint _flags;
+ byte _fontColor;
+};
+
+class VolumeControlWidget : public Widget {
+public:
+ VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags);
+ ~VolumeControlWidget();
+ void redraw();
+ Widget *getHoveredWidget(int mouseX, int mouseY);
+ void calcDimensions();
+ //void setHilighted(bool active);
+ void onMouseEnter();
+ void onMouseLeave();
+ void onMouseMove(int mouseX, int mouseY);
+protected:
+ uint _flags;
+ LabelWidget *_label, *_up, *_down, *_indicator;
+ Widget *_activeWidget;
+};
+
+class MenuPage {
+public:
+ MenuPage(Common::String caption);
+ ~MenuPage();
+ void addWidget(Widget *widget);
+ void redraw();
+ Widget *getHoveredWidget(int mouseX, int mouseY);
+protected:
+ typedef Common::Array<Widget*> WidgetArray;
+ Common::String _caption;
+ WidgetArray _widgets;
+};
+
+class MenuSystem {
+
+public:
+ MenuSystem(ToltecsEngine *vm);
+ ~MenuSystem();
+
+ void update();
+
+protected:
+ ToltecsEngine *_vm;
+
+ //LabelWidget *label1, *label2;
+ MenuPage *_page;
+
+ Widget *_activeWidget;
+ int16 _oldMouseX, _oldMouseY;
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_MENU_H */
diff --git a/engines/toltecs/microtiles.cpp b/engines/toltecs/microtiles.cpp
new file mode 100644
index 0000000..3cd5fac
--- /dev/null
+++ b/engines/toltecs/microtiles.cpp
@@ -0,0 +1,797 @@
+/*
+ SEL - Simple DirectMedia Layer Extension Library
+ Copyright (C) 2002 Matej Knopp <knopp at users.sf.net>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* microtile arrays implementation */
+
+/*
+ * This is a microtile array implementation similiar to the one
+ * from LibArt_LGPL. First, I wanted to use that one but unfortunately
+ * I fount out that it suffered from a bad design and simply didn't meet
+ * my requirements so I decided to write the implementation on my own.
+ */
+
+#include "toltecs/microtiles.h"
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+
+namespace Toltecs {
+
+typedef struct _GemUta GemUta;
+typedef struct _GemRect GemRect;
+
+typedef uint32 GemUtaBBox;
+
+#define GEM_UTA_BBOX_CONS(x0, y0, x1, y1) (((x0) << 24) | ((y0) << 16) | \
+ ((x1) << 8) | (y1))
+
+#define GEM_UTILE_EMPTY 0x00000000
+#define GEM_UTILE_FULL 0x01012020
+
+#define GEM_UTA_BBOX_X0(ub) ((ub) >> 24)
+#define GEM_UTA_BBOX_Y0(ub) (((ub) >> 16) & 0xff)
+#define GEM_UTA_BBOX_X1(ub) (((ub) >> 8) & 0xff)
+#define GEM_UTA_BBOX_Y1(ub) ((ub) & 0xff)
+
+#define GEM_UTILE_SHIFT 5
+#define GEM_UTILE_SIZE (1 << GEM_UTILE_SHIFT)
+
+#define GEM_MIN(a,b) ((a) < (b) ? (a) : (b))
+#define GEM_MAX(a,b) ((a) > (b) ? (a) : (b))
+
+struct _GemUta {
+ int x;
+ int y;
+ int width; /* number of tiles in one line */
+ int height; /* number of tiles in one row */
+ GemUtaBBox *tiles;
+};
+
+struct _GemRect {
+ int x0;
+ int x1;
+ int y0;
+ int y1;
+};
+
+
+static GemUta * gem_uta_new (int x, int y, int width, int height);
+static GemUta * gem_uta_new_coords (int x, int y, int width, int height);
+static void gem_uta_free (GemUta *uta);
+static void gem_uta_union (GemUta *uta1, const GemUta *uta2);
+static void gem_uta_add_rect (GemUta *uta, const GemRect * rect);
+
+#define GEM_UTA_QUERY_CONTAIN 0
+#define GEM_UTA_QUERY_INTERSECT 1
+
+static int gem_uta_query_rect (const GemUta *uta, const GemRect * rect, int query);
+
+static Common::Rect * gem_uta_get_rects (const GemUta *uta, int * num_rects,
+ int min_x, int min_y, int max_x, int max_y);
+
+/************** UTA IMPLEMENTATION **************/
+
+#define GEM_UTILE_UNION(b1, b2) \
+ { \
+ if (b1 == GEM_UTILE_FULL || b2 == GEM_UTILE_EMPTY) \
+ { } \
+ else if (b1 == GEM_UTILE_EMPTY || b2 == GEM_UTILE_FULL) \
+ { b1 = b2; } \
+ else { \
+ b1 = GEM_UTA_BBOX_CONS ( \
+ GEM_MIN(GEM_UTA_BBOX_X0(b1), \
+ GEM_UTA_BBOX_X0(b2)), \
+ GEM_MIN(GEM_UTA_BBOX_Y0(b1), \
+ GEM_UTA_BBOX_Y0(b2)), \
+ GEM_MAX(GEM_UTA_BBOX_X1(b1), \
+ GEM_UTA_BBOX_X1(b2)), \
+ GEM_MAX(GEM_UTA_BBOX_Y1(b1), \
+ GEM_UTA_BBOX_Y1(b2))); \
+ } \
+ }
+
+static GemUta * gem_uta_new (int x, int y, int width, int height) {
+ GemUta *uta;
+
+ uta = (GemUta *) malloc (sizeof (GemUta));
+ uta->x = x;
+ uta->y = y;
+ uta->width = width;
+ uta->height = height;
+
+ uta->tiles = (GemUtaBBox *)
+ malloc (sizeof (GemUtaBBox) * width * height);
+
+ memset (uta->tiles, 0, sizeof (GemUtaBBox) * width * height);
+
+ return uta;
+}
+
+static GemUta * gem_uta_new_coords (int x, int y, int width, int height) {
+ return gem_uta_new (x >> GEM_UTILE_SHIFT, y >> GEM_UTILE_SHIFT,
+ (width >> GEM_UTILE_SHIFT) + 1,
+ (height >> GEM_UTILE_SHIFT) + 1);
+}
+
+static void gem_uta_free (GemUta *uta) {
+ if (uta) {
+ if (uta->tiles)
+ free (uta->tiles);
+ free(uta);
+ }
+}
+
+static void gem_uta_union (GemUta *uta1, const GemUta *uta2) {
+ int32 x0, y0, x1, y1;
+ int x, y;
+ GemUtaBBox *_b1;
+ const GemUtaBBox *_b2;
+
+ if (!uta1 || !uta2)
+ return;
+
+ x0 = GEM_MAX (uta1->x, uta2->x);
+ y0 = GEM_MAX (uta2->y, uta2->y);
+ x1 = GEM_MIN (uta1->x + uta1->width - 1,
+ uta2->x + uta2->width - 1);
+ y1 = GEM_MIN (uta1->y + uta1->height - 1,
+ uta2->y + uta2->height - 1);
+
+ if (x0 > x1 || y0 > y1)
+ return;
+
+ _b1 = & (uta1->tiles [(y0 - uta1->y) * uta1->width + (x0 - uta1->x)]);
+ _b2 = & (uta2->tiles [(y0 - uta2->y) * uta2->width + (x0 - uta2->x)]);
+
+ for (y = y0; y <= y1; ++y)
+ {
+ GemUtaBBox *b1 = _b1;
+ const GemUtaBBox *b2 = _b2;
+
+ for (x = x0; x <= x1; ++x)
+ {
+ GEM_UTILE_UNION (*b1, *b2);
+
+ b1 ++;
+ b2 ++;
+ }
+ _b1 += uta1->width;
+ _b2 += uta2->width;
+ }
+}
+
+/*
+ * Add a rectangle to the microtile array.
+ * The coordinates of the rectangle are considered absolute.
+ */
+
+static void gem_uta_add_rect (GemUta *uta, const GemRect * _rect) {
+ int xf0, xf1, yf0, yf1;
+ int width, height;
+ int x0, y0, x1, y1;
+ int x, y;
+ GemUtaBBox *_b;
+ GemUtaBBox *b;
+ GemUtaBBox bbox;
+ GemRect rect;
+
+ if (!uta || !_rect)
+ return;
+
+ rect = *_rect;
+
+ rect.x0 -= uta->x << GEM_UTILE_SHIFT;
+ rect.y0 -= uta->y << GEM_UTILE_SHIFT;
+ rect.x1 -= uta->x << GEM_UTILE_SHIFT;
+ rect.y1 -= uta->y << GEM_UTILE_SHIFT;
+
+ if (rect.x0 < 0)
+ rect.x0 = 0;
+ if (rect.y0 < 0)
+ rect.y0 = 0;
+ if (rect.x1 > (uta->width << GEM_UTILE_SHIFT))
+ rect.x1 = (uta->width << GEM_UTILE_SHIFT);
+ if (rect.y1 > (uta->height << GEM_UTILE_SHIFT))
+ rect.y1 = (uta->height << GEM_UTILE_SHIFT);
+
+ if (rect.x0 > rect.x1 || rect.y0 > rect.y1)
+ return;
+
+ width = ((rect.x1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT)
+ - (rect.x0 >> GEM_UTILE_SHIFT);
+ height = ((rect.y1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT)
+ - (rect.y0 >> GEM_UTILE_SHIFT);
+
+ xf0 = rect.x0 % (GEM_UTILE_SIZE);
+ yf0 = rect.y0 % (GEM_UTILE_SIZE);
+ xf1 = rect.x1 % (GEM_UTILE_SIZE);
+ yf1 = rect.y1 % (GEM_UTILE_SIZE);
+
+ x0 = rect.x0 >> GEM_UTILE_SHIFT;
+ y0 = rect.y0 >> GEM_UTILE_SHIFT;
+ x1 = rect.x1 >> GEM_UTILE_SHIFT;
+ y1 = rect.y1 >> GEM_UTILE_SHIFT;
+
+ _b = & (uta->tiles [(y0 * uta->width) + x0]);
+
+ if (width == 1 && height == 1) {
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, yf1 + 1);
+ GEM_UTILE_UNION (*_b, bbox);
+ return;
+ }
+ if (width == 1) {
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1,
+ GEM_UTILE_SIZE);
+ GEM_UTILE_UNION (*_b, bbox);
+ _b += uta->width;
+ if (height > 2) {
+ for (y = y0 + 1; y <= (y1 - 1); ++y) {
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, GEM_UTILE_SIZE);
+ GEM_UTILE_UNION (*_b, bbox);
+ _b += uta->width;
+ }
+ }
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, yf1 + 1);
+ GEM_UTILE_UNION (*_b, bbox);
+ return;
+ } else if (height == 1) {
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, yf1 + 1);
+ GEM_UTILE_UNION (*_b, bbox);
+ ++_b;
+ if (width > 2) {
+ for (x = x0 + 1; x <= (x1 - 1); ++x) {
+ bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, xf1 + 1);
+ GEM_UTILE_UNION (*_b, bbox);
+ ++_b;
+ }
+ }
+ bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, yf1 + 1);
+ GEM_UTILE_UNION (*_b, bbox);
+ return;
+ }
+
+ b = _b;
+
+ /* top-left corner */
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
+ GEM_UTILE_UNION (*b, bbox);
+ ++b;
+
+ /* top edge */
+ if (width > 2) {
+ for (x = x0 + 1; x <= (x1 - 1); ++x) {
+ bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
+ GEM_UTILE_UNION (*b, bbox);
+ ++b;
+ }
+ }
+
+ /* top-right corner */
+ bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE);
+ GEM_UTILE_UNION (*b, bbox);
+
+ _b += uta->width;
+
+ /* left edge, content, right edge */
+ if (height > 2) {
+ for (y = y0 + 1; y <= (y1 - 1); ++y) {
+ b = _b;
+
+ /* left edge */
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
+ GEM_UTILE_UNION (*b, bbox);
+ ++b;
+
+ /* content */
+ if (width > 2) {
+ for (x = x0 + 1; x <= (x1 - 1); ++x) {
+ *b = GEM_UTILE_FULL;
+ ++b;
+ }
+ }
+
+ /* right edge */
+ bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, GEM_UTILE_SIZE);
+ GEM_UTILE_UNION (*b, bbox);
+
+ _b += uta->width;
+ }
+ }
+
+ b = _b;
+
+ /* bottom-left corner */
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, yf1 + 1);
+ GEM_UTILE_UNION (*b, bbox);
+ ++b;
+
+ /* bottom edge */
+ if (width > 2) {
+ for (x = x0 + 1; x <= (x1 - 1); ++x) {
+ bbox = GEM_UTA_BBOX_CONS (1, 1, GEM_UTILE_SIZE, yf1 + 1);
+ GEM_UTILE_UNION (*b, bbox);
+ ++b;
+ }
+ }
+
+ /* bottom-left corner */
+ bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, yf1 + 1);
+ GEM_UTILE_UNION (*b, bbox);
+
+ /* done. */
+}
+
+#define GEM_UTILE_CONTAINS(b1, b2) \
+ ( !(GEM_UTA_BBOX_X0 (b1) > GEM_UTA_BBOX_X0 (b2) || \
+ GEM_UTA_BBOX_Y0 (b1) > GEM_UTA_BBOX_Y0 (b2) || \
+ GEM_UTA_BBOX_X1 (b1) < GEM_UTA_BBOX_X1 (b2) || \
+ GEM_UTA_BBOX_Y1 (b1) < GEM_UTA_BBOX_Y1 (b2)) )
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+static inline int gem_utile_intersects (GemUtaBBox b1, GemUtaBBox b2) {
+ GemUtaBBox b3;
+ b3 = GEM_UTA_BBOX_CONS (
+ MAX (GEM_UTA_BBOX_X0 (b1), GEM_UTA_BBOX_X0 (b2)),
+ MAX (GEM_UTA_BBOX_Y0 (b1), GEM_UTA_BBOX_Y0 (b2)),
+ MIN (GEM_UTA_BBOX_X1 (b1), GEM_UTA_BBOX_X1 (b2)),
+ MIN (GEM_UTA_BBOX_Y1 (b1), GEM_UTA_BBOX_Y1 (b2))
+ );
+ return (GEM_UTA_BBOX_X0 (b3) <= GEM_UTA_BBOX_X1 (b3) &&
+ GEM_UTA_BBOX_Y0 (b3) <= GEM_UTA_BBOX_Y1 (b3));
+}
+
+#define GEM_UTILE_INTERSECTS(b1, b2) \
+ gem_utile_intersects (b1, b2)
+/*
+ * Return if the uta contains the rectangle.
+ */
+
+static int gem_uta_query_rect (const GemUta *uta, const GemRect * _rect, int query) {
+ int xf0, xf1, yf0, yf1;
+ int width, height;
+ int x0, y0, x1, y1;
+ int x, y;
+ GemUtaBBox *_b;
+ GemUtaBBox *b;
+ GemUtaBBox bbox;
+ GemRect rect;
+
+ if (!uta || !_rect)
+ return 0;
+
+ rect = *_rect;
+
+ rect.x0 -= uta->x << GEM_UTILE_SHIFT;
+ rect.y0 -= uta->y << GEM_UTILE_SHIFT;
+ rect.x1 -= uta->x << GEM_UTILE_SHIFT;
+ rect.y1 -= uta->y << GEM_UTILE_SHIFT;
+
+ if (rect.x0 < 0)
+ rect.x0 = 0;
+ if (rect.y0 < 0)
+ rect.y0 = 0;
+ if (rect.x1 > (uta->width << GEM_UTILE_SHIFT))
+ rect.x1 = (uta->width << GEM_UTILE_SHIFT);
+ if (rect.y1 > (uta->height << GEM_UTILE_SHIFT))
+ rect.y1 = (uta->height << GEM_UTILE_SHIFT);
+
+ if (rect.x0 > rect.x1 || rect.y0 > rect.y1)
+ return 0;
+
+ width = ((rect.x1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT)
+ - (rect.x0 >> GEM_UTILE_SHIFT);
+ height = ((rect.y1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT)
+ - (rect.y0 >> GEM_UTILE_SHIFT);
+
+ xf0 = rect.x0 % (GEM_UTILE_SIZE);
+ yf0 = rect.y0 % (GEM_UTILE_SIZE);
+ xf1 = rect.x1 % (GEM_UTILE_SIZE);
+ yf1 = rect.y1 % (GEM_UTILE_SIZE);
+
+ x0 = rect.x0 >> GEM_UTILE_SHIFT;
+ y0 = rect.y0 >> GEM_UTILE_SHIFT;
+ x1 = rect.x1 >> GEM_UTILE_SHIFT;
+ y1 = rect.y1 >> GEM_UTILE_SHIFT;
+
+ _b = & (uta->tiles [(y0 * uta->width) + x0]);
+
+ if (width == 1 && height == 1) {
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, yf1 + 1);
+ if (query == GEM_UTA_QUERY_INTERSECT &&
+ GEM_UTILE_INTERSECTS (*_b, bbox))
+ return 1;
+ else if (query == GEM_UTA_QUERY_CONTAIN &&
+ GEM_UTILE_CONTAINS (*_b, bbox))
+ return 1;
+ return 0;
+
+ }
+#define CHECK(b1,b2) \
+ { \
+ if (query == GEM_UTA_QUERY_INTERSECT && \
+ GEM_UTILE_INTERSECTS (b1, b2)) \
+ return 1; \
+ else if (query == GEM_UTA_QUERY_CONTAIN && \
+ !(GEM_UTILE_CONTAINS (b1, b2))) \
+ return 0; \
+ }
+ if (width == 1) {
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE);
+ CHECK (*_b, bbox);
+ _b += uta->width;
+ if (height > 2) {
+ for (y = y0 + 1; y <= (y1 - 1); ++y) {
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, GEM_UTILE_SIZE);
+ CHECK (*_b, bbox);
+ _b += uta->width;
+ }
+ }
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, yf1 + 1);
+ CHECK (*_b, bbox);
+ if (query == GEM_UTA_QUERY_INTERSECT)
+ return 0;
+ else if (query == GEM_UTA_QUERY_CONTAIN)
+ return 1;
+ } else if (height == 1) {
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, yf1 + 1);
+ CHECK (*_b, bbox);
+ ++_b;
+ if (width > 2) {
+ for (x = x0 + 1; x <= (x1 - 1); ++x) {
+ bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, xf1 + 1);
+ CHECK (*_b, bbox);
+ ++_b;
+ }
+ }
+ bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, yf1 + 1);
+ CHECK (*_b, bbox);
+ if (query == GEM_UTA_QUERY_INTERSECT)
+ return 0;
+ else if (query == GEM_UTA_QUERY_CONTAIN)
+ return 1;
+ }
+
+ b = _b;
+
+ /* top-left corner */
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
+ CHECK (*b, bbox);
+ ++b;
+
+ /* top edge */
+ if (width > 2) {
+ for (x = x0 + 1; x <= (x1 - 1); ++x) {
+ bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
+ CHECK (*b, bbox);
+ ++b;
+ }
+ }
+
+ /* top-right corner */
+ bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE);
+ CHECK (*b, bbox);
+
+ _b += uta->width;
+
+ /* left edge, content, right edge */
+ if (height > 2) {
+ for (y = y0 + 1; y <= (y1 - 1); ++y) {
+ b = _b;
+
+ /* left edge */
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
+ CHECK (*b, bbox);
+ ++b;
+
+ /* content */
+ if (width > 2) {
+ for (x = x0 + 1; x <= (x1 - 1); ++x) {
+ CHECK (*b, GEM_UTILE_FULL);
+ ++b;
+ }
+ }
+
+ /* right edge */
+ bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, GEM_UTILE_SIZE);
+ CHECK (*b, bbox);
+
+ _b += uta->width;
+ }
+ }
+
+ b = _b;
+
+ /* bottom-left corner */
+ bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, yf1 + 1);
+ CHECK (*b, bbox);
+ ++b;
+
+ /* bottom edge */
+ if (width > 2) {
+ for (x = x0 + 1; x <= (x1 - 1); ++x) {
+ bbox = GEM_UTA_BBOX_CONS (1, 1, GEM_UTILE_SIZE, yf1 + 1);
+ CHECK (*b, bbox);
+ ++b;
+ }
+ }
+
+ /* bottom-left corner */
+ bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, yf1 + 1);
+ CHECK (*b, bbox);
+
+#undef CHECK
+
+ /* done. */
+ if (query == GEM_UTA_QUERY_CONTAIN)
+ return 1;
+ return 0;
+}
+
+
+#undef CLAMP
+#define CLAMP(a,min,max) (a = (a < min ? min : (a > max ? max : a)))
+
+static Common::Rect * gem_uta_get_rects (const GemUta *uta, int * num_rects,
+ int min_x, int min_y, int max_x, int max_y) {
+
+#if 1
+
+
+ GemRect *rects = new GemRect[uta->width * uta->height];
+ Common::Rect *result = NULL;
+ int n_rects = 0;
+ int x, y;
+ int x0, y0, x1, y1;
+
+ int *glom = new int[uta->width * uta->height];
+ int i; /* current */
+
+ for (i = 0; i < uta->width * uta->height; ++i)
+ glom [i] = -1;
+
+ i = 0;
+
+ for (y = 0; y < uta->height; ++y) {
+ for (x = 0; x < uta->width; ++x) {
+#define TILE uta->tiles [i]
+ int start;
+ int finish = 0;
+ GemUtaBBox b;
+
+ b = uta->tiles [i];
+
+ if (TILE == GEM_UTILE_EMPTY)
+ goto next;
+
+ x0 = ((uta->x + x) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_X0 (TILE) - 1;
+ y0 = ((uta->y + y) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_Y0 (TILE) - 1;
+ y1 = ((uta->y + y) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_Y1 (TILE) - 1;
+
+ CLAMP (x0, min_x, max_x);
+ CLAMP (y0, min_y, max_y);
+ CLAMP (y1, min_y, max_y);
+
+ start = i;
+
+ if (GEM_UTA_BBOX_X1 (TILE) != GEM_UTILE_SIZE || x == uta->width - 1) {
+ /* the tile does not continue */
+ goto done;
+ }
+
+ while (!finish) {
+ ++x;
+ ++i;
+
+ if (x == uta->width ||
+ GEM_UTA_BBOX_Y0 (TILE) != GEM_UTA_BBOX_Y0 (b) ||
+ GEM_UTA_BBOX_Y1 (TILE) != GEM_UTA_BBOX_Y1 (b) ||
+ GEM_UTA_BBOX_X0 (TILE) != 1)
+ {
+ --x;
+ --i;
+ finish = 1;
+ }
+ }
+
+ done:
+ x1 = ((uta->x + x) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_X1 (TILE) - 1;
+
+ CLAMP (x1, min_x, max_x);
+
+ if (glom [start] != -1 && /* try to glom */
+ rects [glom [start]].x0 == x0 &&
+ rects [glom [start]].x1 == x1 &&
+ rects [glom [start]].y1 == y0 - 1)
+ {
+ rects [glom [start]].y1 = y1;
+ if (y != uta->height - 1) {
+ glom [start + uta->width] = glom [start];
+ }
+ } else {
+ rects [n_rects].x0 = x0;
+ rects [n_rects].y0 = y0;
+ rects [n_rects].x1 = x1;
+ rects [n_rects].y1 = y1;
+ if (y != uta->height - 1) {
+ glom [start + uta->width] = n_rects;
+ }
+ n_rects ++;
+ }
+ next:
+ ++i;
+#undef TILE
+ }
+ }
+
+ result = new Common::Rect[n_rects];
+
+ for (i = 0; i < n_rects; ++i) {
+ result[i].left = rects [i].x0;
+ result[i].top = rects [i].y0;
+ result[i].right = rects[i].x1; // CHECK
+ result[i].bottom = rects[i].y1; // CHECK
+ }
+
+ *num_rects = n_rects;
+
+ delete rects;
+ delete glom;
+
+ return result;
+
+#else
+ return NULL;
+#endif
+
+}
+
+MicroTileArray::MicroTileArray()
+ : m_uta (NULL)
+{
+}
+
+MicroTileArray::MicroTileArray(int x, int y, int w, int h)
+ : m_x (x), m_y (y), m_w (w), m_h (h)
+{
+ m_uta = gem_uta_new_coords (x, y, w, h);
+ if (!m_uta)
+ error("MicroTileArray::MicroTileArray() Out of memory");
+}
+
+MicroTileArray::~MicroTileArray() {
+ if (m_uta)
+ gem_uta_free (m_uta);
+}
+
+void MicroTileArray::clear() {
+ if (!m_uta)
+ return;
+
+ memset (m_uta->tiles, 0, m_uta->width * m_uta->height * sizeof(GemUtaBBox));
+}
+
+void MicroTileArray::init(int x, int y, int w, int h) {
+ if (m_uta)
+ gem_uta_free (m_uta);
+ m_uta = gem_uta_new_coords (x, y, w, h);
+ m_x = x;
+ m_y = y;
+ m_w = w;
+ m_h = h;
+ if (!m_uta)
+ error("Out of memory");
+}
+
+int MicroTileArray::getRectangles(Common::Rect * & rects, int min_x, int max_x, int min_y, int max_y) const {
+ if (!m_uta)
+ return 0;
+
+ int n_rects;
+
+ rects = gem_uta_get_rects (m_uta, &n_rects, min_x, max_x, min_y, max_y);
+
+ return n_rects;
+}
+
+int MicroTileArray::getRectangles(Common::Rect * & rects) const {
+ if (!m_uta)
+ return 0;
+
+ int n_rects;
+
+ rects = gem_uta_get_rects (m_uta, &n_rects,
+ m_x, m_y, m_x + m_w - 1, m_y + m_h - 1);
+
+ return n_rects;
+}
+
+bool MicroTileArray::contains(const Common::Rect & rect) const {
+ if (!m_uta)
+ return false;
+
+ GemRect r;
+ r.x0 = rect.left;
+ r.y0 = rect.top;
+ r.x1 = rect.right; // CHECK
+ r.y1 = rect.bottom; // CHECK
+
+ return gem_uta_query_rect (m_uta, &r, GEM_UTA_QUERY_CONTAIN);
+}
+
+bool MicroTileArray::intersects(const Common::Rect & rect) const {
+ if (!m_uta)
+ return false;
+
+ GemRect r;
+ r.x0 = rect.left;
+ r.y0 = rect.top;
+ r.x1 = rect.right; // CHECK
+ r.y1 = rect.bottom; // CHECK
+
+ return gem_uta_query_rect (m_uta, &r, GEM_UTA_QUERY_INTERSECT);
+}
+
+void MicroTileArray::unite(const Common::Rect & rect) {
+ if (!m_uta || rect.width() == 0 || rect.height() == 0)
+ return;
+
+ GemRect r;
+ r.x0 = rect.left;
+ r.y0 = rect.top;
+ r.x1 = rect.right; // CHECK
+ r.y1 = rect.bottom; // CHECK
+
+ gem_uta_add_rect (m_uta, &r);
+}
+
+MicroTileArray & MicroTileArray::operator += (const Common::Rect & rect) {
+ if (!m_uta || rect.width() == 0 || rect.height() == 0)
+ return *this;
+
+ GemRect r;
+ r.x0 = rect.left;
+ r.y0 = rect.top;
+ r.x1 = rect.right; // CHECK
+ r.y1 = rect.bottom; // CHECK
+
+ gem_uta_add_rect (m_uta, &r);
+
+ return *this;
+}
+
+void MicroTileArray::unite (const MicroTileArray & uta) {
+ if (m_uta)
+ gem_uta_union (m_uta, uta.m_uta);
+}
+
+MicroTileArray & MicroTileArray::operator += (const MicroTileArray & uta) {
+ if (m_uta)
+ gem_uta_union (m_uta, uta.m_uta);
+ return *this;
+}
+
+} // namespace Toltecs
+
diff --git a/engines/toltecs/microtiles.h b/engines/toltecs/microtiles.h
new file mode 100644
index 0000000..21dd5a9
--- /dev/null
+++ b/engines/toltecs/microtiles.h
@@ -0,0 +1,105 @@
+/*
+ SEL - Simple DirectMedia Layer Extension Library
+ Copyright (C) 2002 Matej Knopp <knopp at users.sf.net>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef TOLTECS_MICROTILES_H
+#define TOLTECS_MICROTILES_H
+
+#include "common/rect.h"
+
+namespace Toltecs {
+
+//! Class that represents a microtile array.
+/*!
+ Microtile array is an efficient method of representing regions that
+ need to be redrawn. For more information about the microtile arrays
+ in general visit the LibArt homepage at
+ http://www.levien.com/libart/uta.html .
+
+ Note that this implementation is not the one of LibArt and
+ differs from it.
+ */
+class MicroTileArray {
+public:
+ //! Create an empty unitialized uta.
+ /*
+ \note You must initialize the class using
+ Uta::init() before doing anything with it.
+ */
+ MicroTileArray();
+
+ //! Create a new microtile array with given coordinates.
+ MicroTileArray(int x, int y, int w, int h);
+
+ //! Destroy the microtile array.
+ ~MicroTileArray();
+
+ //! Clear the microtile array.
+ void clear();
+
+ //! Initialize the array.
+ /*
+ You can use this funtion to resize the array as well,
+ but you should be aware that the content of the array
+ will be cleared.
+ */
+ void init(int x, int y, int w, int h);
+
+ //! Return the microtile array as rectangles.
+ /*!
+ The \a rects array should be freed when no longer needed.
+ \return The number of rectangles in \a rects.
+ */
+ int getRectangles(Common::Rect * & rects,
+ int min_x, int max_x, int min_y, int max_y) const;
+
+ //! Return the microtile array as rectangles.
+ /*!
+ The \a rects array should be freed when no longer needed.
+ \return The number of rectangles in \a rects.
+ */
+ int getRectangles(Common::Rect * & rects) const;
+
+ //! Whether the microtile array contains given rectangle.
+ bool contains(const Common::Rect &) const;
+
+ //! Whether the microtile array intersects given rectangle.
+ bool intersects(const Common::Rect &) const;
+
+ //! Unite the microtile array with a rectangle.
+ void unite(const Common::Rect &);
+
+ //! Unite the microtile array with a rectangle.
+ MicroTileArray & operator+=(const Common::Rect &);
+
+ //! Unite the array with another microtile array.
+ void unite(const MicroTileArray &);
+
+ //! Unite the array with another microtile array.
+ MicroTileArray & operator+=(const MicroTileArray &);
+
+protected:
+ typedef struct _GemUta GemUta;
+ GemUta *m_uta;
+ int m_x, m_y, m_w, m_h;
+}; // class Uta
+
+} // namespace Toltecs
+
+
+#endif // TOLTECS_MICROTILES_H
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
index 541bf6b..0d658f6 100644
--- a/engines/toltecs/module.mk
+++ b/engines/toltecs/module.mk
@@ -3,6 +3,9 @@ MODULE := engines/toltecs
MODULE_OBJS = \
animation.o \
detection.o \
+ menu.o \
+ microtiles.o \
+ movie.o \
palette.o \
toltecs.o \
resource.o \
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
new file mode 100644
index 0000000..ef280fa
--- /dev/null
+++ b/engines/toltecs/movie.cpp
@@ -0,0 +1,179 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/movie.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+#include "toltecs/script.h"
+
+namespace Toltecs {
+
+MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm) {
+}
+
+MoviePlayer::~MoviePlayer() {
+}
+
+void MoviePlayer::playMovie(uint resIndex) {
+
+ uint32 chunkCount, frameCount, subtitleSlot;
+ byte moviePalette[768];
+
+ memset(moviePalette, 0, sizeof(moviePalette));
+
+ _vm->_screen->finishTextDrawItems();
+ _vm->_screen->clearSprites();
+
+ _vm->_arc->openResource(resIndex);
+
+ frameCount = _vm->_arc->readUint32LE();
+ chunkCount = _vm->_arc->readUint32LE();
+ subtitleSlot = kMaxScriptSlots - 1;
+
+ // TODO: Read/figure out rest of the header
+ _vm->_arc->seek(0x10, SEEK_CUR);
+ _vm->_sceneWidth = 640;
+ _vm->_sceneHeight = 400;
+ _vm->_cameraHeight = 400;
+ _vm->_cameraX = 0;
+ _vm->_cameraY = 0;
+
+ while (chunkCount--) {
+
+ byte chunkType;
+ uint32 chunkSize;
+ byte *chunkBuffer;
+ uint32 movieOffset;
+
+ chunkType = _vm->_arc->readByte();
+ chunkSize = _vm->_arc->readUint32LE();
+
+ debug(0, "chunkType = %d; chunkSize = %d", chunkType, chunkSize);
+
+ chunkBuffer = new byte[chunkSize];
+ _vm->_arc->read(chunkBuffer, chunkSize);
+
+ movieOffset = _vm->_arc->pos();
+
+ switch (chunkType) {
+ case 0: // image data
+ case 1:
+ unpackRle(chunkBuffer, _vm->_screen->_backScreen);
+ // TODO: Rework this
+ _vm->_screen->updateShakeScreen();
+ _vm->updateInput();
+ _vm->updateScreen();
+ g_system->delayMillis(80);
+ break;
+ case 2: // palette data
+ unpackPalette(chunkBuffer, moviePalette, 256, 3);
+ _vm->_palette->setFullPalette(moviePalette);
+ break;
+ //case 3: -- what is this type
+ case 4: // audio data
+ // TODO: Handle audio data
+ break;
+ case 5:
+ // TODO: Check if the text is a subtitle (last character == 0xFE).
+ // If so, don't show it if text display is disabled.
+ memcpy(_vm->_script->getSlotData(subtitleSlot), chunkBuffer, chunkSize);
+ _vm->_screen->updateTalkText(subtitleSlot, 0);
+ break;
+ case 6: // start/stop shakescreen effect
+ if (chunkBuffer[0] == 0xFF)
+ _vm->_screen->stopShakeScreen();
+ else
+ _vm->_screen->startShakeScreen(chunkBuffer[0]);
+ break;
+ case 7: // setup subtitle parameters
+ _vm->_screen->_talkTextY = READ_LE_UINT16(&chunkBuffer[0]);
+ _vm->_screen->_talkTextX = READ_LE_UINT16(&chunkBuffer[2]);
+ _vm->_screen->_talkTextFontColor = chunkBuffer[4];
+ debug(0, "_talkTextX = %d; _talkTextY = %d; _talkTextFontColor = %d",
+ _vm->_screen->_talkTextX, _vm->_screen->_talkTextY, _vm->_screen->_talkTextFontColor);
+ break;
+ case 8: // stop subtitles
+ _vm->_script->getSlotData(subtitleSlot)[0] = 0xFF;
+ _vm->_screen->finishTextDrawItems();
+ break;
+ default:
+ error("Unknown chunk type %d at %08X", chunkType, _vm->_arc->pos() - 5 - chunkSize);
+ }
+
+ delete[] chunkBuffer;
+
+ _vm->_arc->seek(movieOffset, SEEK_SET);
+
+ }
+
+ _vm->_arc->closeResource();
+
+}
+
+void MoviePlayer::unpackPalette(byte *source, byte *dest, int elemCount, int elemSize) {
+ int ofs = 0, size = elemCount * elemSize;
+ while (ofs < size) {
+ byte len;
+ len = *source++;
+ if (len == 0) {
+ len = *source++;
+ } else {
+ byte value = *source++;
+ memset(dest, value, len);
+ }
+ ofs += len;
+ dest += len;
+ }
+}
+
+void MoviePlayer::unpackRle(byte *source, byte *dest) {
+ int size = 256000;
+ while (size > 0) {
+ byte a = *source++;
+ byte b = *source++;
+ if (a == 0) {
+ dest += b;
+ size -= b;
+ } else {
+ memset(dest, b, a);
+ dest += a;
+ size -= a;
+ }
+ }
+}
+
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
new file mode 100644
index 0000000..9ab5435
--- /dev/null
+++ b/engines/toltecs/movie.h
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_MOVIE_H
+#define TOLTECS_MOVIE_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+class MoviePlayer {
+
+public:
+ MoviePlayer(ToltecsEngine *vm);
+ ~MoviePlayer();
+
+ void playMovie(uint resIndex);
+
+protected:
+ ToltecsEngine *_vm;
+
+ void unpackPalette(byte *source, byte *dest, int elemCount, int elemSize);
+ void unpackRle(byte *source, byte *dest);
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_MOVIE_H */
Commit: 3b89304dd970f2e29e48b6c28fac293c40a5a88d
https://github.com/scummvm/scummvm/commit/3b89304dd970f2e29e48b6c28fac293c40a5a88d
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Forgot script.cpp.
And some tests for menu & movie player in toltecs.cpp.
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 8f20b62..6f155b2 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -52,17 +52,20 @@ ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) {
_savedSp = 0;
+ _slots[kMaxScriptSlots - 1].size = 1024;
+ _slots[kMaxScriptSlots - 1].data = new byte[_slots[kMaxScriptSlots - 1].size];
+
}
ScriptInterpreter::~ScriptInterpreter() {
delete[] _stack;
+ for (int i = 0; i < kMaxScriptSlots; i++)
+ delete[] _slots[i].data;
}
void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
- if (_slots[slotIndex].data) {
- delete[] _slots[slotIndex].data;
- }
+ delete[] _slots[slotIndex].data;
_slots[slotIndex].resIndex = resIndex;
byte *scriptData = _vm->_res->load(resIndex);
@@ -134,13 +137,6 @@ int16 ScriptInterpreter::readInt16() {
return value;
}
-void look(byte *code) {
- char ln[256];
- snprintf(ln, 256, "\t\t\t%02X %02X %02X %02X %02X %02X %02X %02X",
- code[0], code[1], code[2], code[3], code[4], code[5], code[6], code[7]);
- debug(1, "%s", ln);
-}
-
void ScriptInterpreter::execOpcode(byte opcode) {
#if 0
@@ -491,8 +487,8 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 6:// ok
{
- debug(0, "o2_printText()");
- _vm->_screen->printText((byte*)localPtr(arg16(3)));
+ debug(0, "o2_drawGuiTextMulti()");
+ _vm->_screen->drawGuiTextMulti((byte*)localPtr(arg16(3)));
break;
}
@@ -636,6 +632,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
To avoid crashes we skip searching the rectangle index for now when scene 215 is active.
I don't know yet whether this is a bug in the original engine as well or just here.
Needs some more checking.
+ Annoyingly scene 215 is the map which becomes unusable with this hack.
*/
if (_vm->_sceneResIndex != 215) {
if (_vm->_mouseY < _vm->_cameraHeight) {
@@ -914,6 +911,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 65:// TODO
{
debug(0, "o2_playMovie(%d, %d)", arg16(3), arg16(5));
+ // TODO: Enable once the player is ready: _vm->_moviePlayer->playMovie()
break;
}
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 6bc1340..b6d9633 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -39,12 +39,16 @@
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
+#include "toltecs/menu.h"
+#include "toltecs/movie.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
#include "toltecs/script.h"
#include "toltecs/screen.h"
#include "toltecs/segmap.h"
+#include "toltecs/microtiles.h"
+
namespace Toltecs {
struct GameSettings {
@@ -130,14 +134,54 @@ int ToltecsEngine::go() {
_anim = new AnimationPlayer(this);
_palette = new Palette(this);
_segmap = new SegmentMap(this);
+ _moviePlayer = new MoviePlayer(this);
+ _menuSystem = new MenuSystem(this);
_system->showMouse(true);
-#if 1
+//#define TEST_MOVIE
+#ifdef TEST_MOVIE
+ _screen->registerFont(0, 0x0D);
+ _screen->registerFont(1, 0x0E);
+ _moviePlayer->playMovie(0x000012D8);
+#endif
+
+//#define TEST_MENU
+#ifdef TEST_MENU
+ _screen->registerFont(0, 0x0D);
+ _screen->registerFont(1, 0x0E);
+ _screen->loadMouseCursor(12);
+ _palette->loadAddPalette(9, 224);
+ _palette->setDeltaPalette(_palette->getMainPalette(), 7, 0, 31, 224);
+ _screen->finishTextDrawItems();
+ _screen->clearSprites();
+ while (1) {
+ updateInput();
+ _menuSystem->update();
+ updateScreen();
+ }
+#endif
+//#define TEST_MICROTILES
+#ifdef TEST_MICROTILES
+ MicroTileArray *uta = new MicroTileArray(0, 0, 640, 480);
+ uta->unite(Common::Rect(10, 10, 50, 50));
+ uta->unite(Common::Rect(45, 45, 60, 60));
+ Common::Rect *rects;
+ int n_rects;
+ n_rects = uta->getRectangles(rects);
+ printf("n_rects = %d\n", n_rects); fflush(stdout);
+ for (int i = 0; i < n_rects; i++) {
+ printf("%d, %d, %d, %d\n", rects[i].left, rects[i].top, rects[i].right, rects[i].bottom);
+ fflush(stdout);
+ }
+ _system->quit();
+ delete uta;
+#endif
+
+#if 1
_script->loadScript(0, 0);
_script->runScript(0);
-
#endif
delete _arc;
@@ -147,6 +191,8 @@ int ToltecsEngine::go() {
delete _anim;
delete _palette;
delete _segmap;
+ delete _moviePlayer;
+ delete _menuSystem;
return 0;
}
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 3b38baf..7c7e3ea 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -52,6 +52,8 @@ struct ToltecsGameDescription;
class AnimationPlayer;
class ArchiveReader;
class Input;
+class MenuSystem;
+class MoviePlayer;
class Palette;
class ResourceCache;
class ScriptInterpreter;
@@ -102,6 +104,8 @@ public:
AnimationPlayer *_anim;
ArchiveReader *_arc;
Input *_input;
+ MenuSystem *_menuSystem;
+ MoviePlayer *_moviePlayer;
Palette *_palette;
ResourceCache *_res;
ScriptInterpreter *_script;
Commit: 3c479146487893c3e88dc09ead4fb1810ed817c2
https://github.com/scummvm/scummvm/commit/3c479146487893c3e88dc09ead4fb1810ed817c2
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Removed _tempString etc. and replaced it with GuiTextWrapState
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 988e931..8989638 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -627,54 +627,54 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
y += 18;
}
- int width = 0;
- byte *sourceString;
- byte *destString;
- byte len;
+ GuiTextWrapState wrapState;
+ wrapState.width = 0;
+ wrapState.destString = wrapState.textBuffer;
+ wrapState.len = 0;
+ wrapState.len1 = 0;
+ wrapState.len2 = 0;
- _tempStringLen1 = 0;
- destString = _tempString;
y = _verbLineY;
- memset(_tempString, 0, sizeof(_tempString));
+ memset(wrapState.textBuffer, 0, sizeof(wrapState.textBuffer));
for (int16 i = 0; i <= _verbLineNum; i++) {
- sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
- wrapGuiText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
- _tempStringLen1 += len;
+ wrapState.sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
+ wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
+ wrapState.len1 += wrapState.len;
}
if (_verbLineCount != 1) {
int16 charWidth;
- if (*sourceString < 0xF0) {
- while (*sourceString > 0x20 && *sourceString < 0xF0 && len > 0) {
- byte ch = *sourceString--;
- _tempStringLen1--;
- len--;
+ if (*wrapState.sourceString < 0xF0) {
+ while (*wrapState.sourceString > 0x20 && *wrapState.sourceString < 0xF0 && wrapState.len > 0) {
+ byte ch = *wrapState.sourceString--;
+ wrapState.len1--;
+ wrapState.len--;
charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
- width -= charWidth;
+ wrapState.width -= charWidth;
}
- width += charWidth;
- sourceString++;
- _tempStringLen1 -= len;
- _tempStringLen2 = len + 1;
+ wrapState.width += charWidth;
+ wrapState.sourceString++;
+ wrapState.len1 -= wrapState.len;
+ wrapState.len2 = wrapState.len + 1;
- drawGuiText(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+ drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
- destString = _tempString;
- width = 0;
- wrapGuiText(_fontResIndexArray[0], _verbLineWidth, width, sourceString, destString, len);
+ wrapState.destString = wrapState.textBuffer;
+ wrapState.width = 0;
+ wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
+ wrapState.len1 += wrapState.len;
- _tempStringLen1 += len;
y += 9;
}
y += 9;
}
- _tempStringLen1 -= len;
- _tempStringLen2 = len;
+ wrapState.len1 -= wrapState.len;
+ wrapState.len2 = wrapState.len;
- drawGuiText(_verbLineX - 1 - (width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0]);
+ drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
}
@@ -850,58 +850,62 @@ void Screen::drawGuiTextMulti(byte *textData) {
return;
}
+ GuiTextWrapState wrapState;
+ wrapState.sourceString = textData;
+
do {
- if (*textData == 0x0A) {
+ if (*wrapState.sourceString == 0x0A) {
// Set text position
- y = textData[1];
- x = READ_LE_UINT32(textData + 2);
- textData += 4;
- } else if (*textData == 0x0B) {
+ y = wrapState.sourceString[1];
+ x = READ_LE_UINT32(wrapState.sourceString + 2);
+ wrapState.sourceString += 4;
+ } else if (*wrapState.sourceString == 0x0B) {
// Inc text position
- y += textData[1]; // CHECKME: Maybe these are signed?
- x += textData[2];
- textData += 3;
+ y += wrapState.sourceString[1]; // CHECKME: Maybe these are signed?
+ x += wrapState.sourceString[2];
+ wrapState.sourceString += 3;
} else {
- byte *destString = _tempString;
- int width = 0;
- _tempStringLen1 = 0;
- wrapGuiText(_fontResIndexArray[1], 640, width, textData, destString, _tempStringLen2);
- drawGuiText(x - width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1]);
+ wrapState.destString = wrapState.textBuffer;
+ wrapState.width = 0;
+ wrapGuiText(_fontResIndexArray[1], 640, wrapState);
+ wrapState.len1 = 0;
+ wrapState.len2 = wrapState.len;
+ drawGuiText(x - wrapState.width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1], wrapState);
}
- } while (*textData != 0xFF);
+ } while (*wrapState.sourceString != 0xFF);
}
-void Screen::wrapGuiText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len) {
+void Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState) {
Font font(_vm->_res->load(fontResIndex));
- len = 0;
- while (*sourceString >= 0x20 && *sourceString < 0xF0) {
- byte ch = *sourceString;
+ wrapState.len = 0;
+ while (*wrapState.sourceString >= 0x20 && *wrapState.sourceString < 0xF0) {
+ byte ch = *wrapState.sourceString;
byte charWidth;
if (ch <= 0x20)
charWidth = font.getWidth();
else
charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
- if (width + charWidth >= maxWidth)
+ if (wrapState.width + charWidth >= maxWidth)
break;
- len++;
- width += charWidth;
- *destString++ = *sourceString++;
+ wrapState.len++;
+ wrapState.width += charWidth;
+ *wrapState.destString++ = *wrapState.sourceString++;
}
}
-void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex) {
+void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex, GuiTextWrapState &wrapState) {
- debug(0, "Screen::drawGuiText(%d, %d, %d, %d, %d) _tempStringLen1 = %d; _tempStringLen2 = %d", x, y, fontColor1, fontColor2, fontResIndex, _tempStringLen1, _tempStringLen2);
+ debug(0, "Screen::drawGuiText(%d, %d, %d, %d, %d) wrapState.len1 = %d; wrapState.len2 = %d", x, y, fontColor1, fontColor2, fontResIndex, wrapState.len1, wrapState.len2);
int16 ywobble = 1;
- x = drawString(x + 1, y + _vm->_cameraHeight, fontColor1, fontResIndex, _tempString, _tempStringLen1, &ywobble, false);
- x = drawString(x, y + _vm->_cameraHeight, fontColor2, fontResIndex, _tempString + _tempStringLen1, _tempStringLen2, &ywobble, false);
+ x = drawString(x + 1, y + _vm->_cameraHeight, fontColor1, fontResIndex, wrapState.textBuffer, wrapState.len1, &ywobble, false);
+ x = drawString(x, y + _vm->_cameraHeight, fontColor2, fontResIndex, wrapState.textBuffer + wrapState.len1, wrapState.len2, &ywobble, false);
}
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index f7adc22..fa7cad9 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -308,6 +308,14 @@ struct TalkTextItem {
TextRect lines[15];
};
+struct GuiTextWrapState {
+ int16 len, len1, len2;
+ byte *sourceString;
+ byte *destString;
+ int16 width;
+ byte textBuffer[100];
+};
+
class Screen {
public:
Screen(ToltecsEngine *vm);
@@ -346,8 +354,8 @@ public:
// Font/text
void registerFont(uint fontIndex, uint resIndex);
void drawGuiTextMulti(byte *textData);
- void wrapGuiText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len);
- void drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex);
+ void wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState);
+ void drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex, GuiTextWrapState &wrapState);
int16 drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len = -1, int16 *ywobble = NULL, bool outline = false);
void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline);
@@ -376,10 +384,6 @@ public:
uint _fontResIndexArray[10];
byte _fontColor1, _fontColor2;
- // TODO: Remove this _tempXXX stuff
- byte _tempString[100];
- byte _tempStringLen1, _tempStringLen2;
-
// Screen shaking
bool _shakeActive;
int16 _shakeCounterInit, _shakeCounter;
Commit: ca49ded9b346e702538a560ed9de391c3c532b9d
https://github.com/scummvm/scummvm/commit/ca49ded9b346e702538a560ed9de391c3c532b9d
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: More changes to wrapGuiText
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 8989638..4f7efaa 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -628,9 +628,9 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
}
GuiTextWrapState wrapState;
+ int16 len;
wrapState.width = 0;
wrapState.destString = wrapState.textBuffer;
- wrapState.len = 0;
wrapState.len1 = 0;
wrapState.len2 = 0;
@@ -640,39 +640,39 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
for (int16 i = 0; i <= _verbLineNum; i++) {
wrapState.sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
- wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
- wrapState.len1 += wrapState.len;
+ len = wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
+ wrapState.len1 += len;
}
if (_verbLineCount != 1) {
int16 charWidth;
if (*wrapState.sourceString < 0xF0) {
- while (*wrapState.sourceString > 0x20 && *wrapState.sourceString < 0xF0 && wrapState.len > 0) {
+ while (*wrapState.sourceString > 0x20 && *wrapState.sourceString < 0xF0 && len > 0) {
byte ch = *wrapState.sourceString--;
wrapState.len1--;
- wrapState.len--;
+ len--;
charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
wrapState.width -= charWidth;
}
wrapState.width += charWidth;
wrapState.sourceString++;
- wrapState.len1 -= wrapState.len;
- wrapState.len2 = wrapState.len + 1;
+ wrapState.len1 -= len;
+ wrapState.len2 = len + 1;
drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
wrapState.destString = wrapState.textBuffer;
wrapState.width = 0;
- wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
- wrapState.len1 += wrapState.len;
+ len = wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
+ wrapState.len1 += len;
y += 9;
}
y += 9;
}
- wrapState.len1 -= wrapState.len;
- wrapState.len2 = wrapState.len;
+ wrapState.len1 -= len;
+ wrapState.len2 = len;
drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
@@ -868,9 +868,8 @@ void Screen::drawGuiTextMulti(byte *textData) {
} else {
wrapState.destString = wrapState.textBuffer;
wrapState.width = 0;
- wrapGuiText(_fontResIndexArray[1], 640, wrapState);
wrapState.len1 = 0;
- wrapState.len2 = wrapState.len;
+ wrapState.len2 = wrapGuiText(_fontResIndexArray[1], 640, wrapState);
drawGuiText(x - wrapState.width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1], wrapState);
}
@@ -878,11 +877,11 @@ void Screen::drawGuiTextMulti(byte *textData) {
}
-void Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState) {
+int16 Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState) {
Font font(_vm->_res->load(fontResIndex));
-
- wrapState.len = 0;
+ int16 len = 0;
+
while (*wrapState.sourceString >= 0x20 && *wrapState.sourceString < 0xF0) {
byte ch = *wrapState.sourceString;
byte charWidth;
@@ -892,10 +891,13 @@ void Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrap
charWidth = font.getCharWidth(ch) + font.getSpacing() - 1;
if (wrapState.width + charWidth >= maxWidth)
break;
- wrapState.len++;
+ len++;
wrapState.width += charWidth;
*wrapState.destString++ = *wrapState.sourceString++;
}
+
+ return len;
+
}
void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex, GuiTextWrapState &wrapState) {
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index fa7cad9..6050257 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -309,7 +309,7 @@ struct TalkTextItem {
};
struct GuiTextWrapState {
- int16 len, len1, len2;
+ int16 len1, len2;
byte *sourceString;
byte *destString;
int16 width;
@@ -354,7 +354,7 @@ public:
// Font/text
void registerFont(uint fontIndex, uint resIndex);
void drawGuiTextMulti(byte *textData);
- void wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState);
+ int16 wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState);
void drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex, GuiTextWrapState &wrapState);
int16 drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len = -1, int16 *ywobble = NULL, bool outline = false);
Commit: ade8eec8cf853c8f5fe16cbf410440e76e0ac23e
https://github.com/scummvm/scummvm/commit/ade8eec8cf853c8f5fe16cbf410440e76e0ac23e
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Moved sprite drawing code to sprite.cpp
Changed paths:
A engines/toltecs/sprite.cpp
engines/toltecs/module.mk
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
index 0d658f6..3cf8855 100644
--- a/engines/toltecs/module.mk
+++ b/engines/toltecs/module.mk
@@ -12,7 +12,8 @@ MODULE_OBJS = \
saveload.o \
screen.o \
script.o \
- segmap.o
+ segmap.o \
+ sprite.o
# This module can be built as a plugin
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 4f7efaa..fc981db 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -266,346 +266,6 @@ void Screen::clearSprites() {
}
-void Screen::addDrawRequest(const DrawRequest &drawRequest) {
-
- int16 scaleValueX, scaleValueY;
- int16 xoffs, yoffs;
- byte *spriteData;
- int16 frameNum;
-
- SpriteDrawItem sprite;
- memset(&sprite, 0, sizeof(SpriteDrawItem));
-
- if (drawRequest.flags == 0xFFFF)
- return;
-
- sprite.flags = 0;
- sprite.baseColor = drawRequest.baseColor;
- sprite.x = drawRequest.x;
- sprite.y = drawRequest.y;
- sprite.ybottom = drawRequest.y;
- sprite.resIndex = drawRequest.resIndex;
-
- spriteData = _vm->_res->load(drawRequest.resIndex);
-
- if (drawRequest.flags & 0x1000) {
- sprite.flags |= 4;
- }
-
- if (drawRequest.flags & 0x2000) {
- sprite.flags |= 0x10;
- }
-
- if (drawRequest.flags & 0x4000) {
- sprite.flags |= 0x40;
- }
-
- frameNum = drawRequest.flags & 0x0FFF;
-
- // First initialize the sprite item with the values from the sprite resource
-
- SpriteFrameEntry spriteFrameEntry(spriteData + frameNum * 12);
-
- if (spriteFrameEntry.w == 0 || spriteFrameEntry.h == 0)
- return;
-
- sprite.offset = spriteFrameEntry.offset;
-
- sprite.width = spriteFrameEntry.w;
- sprite.height = spriteFrameEntry.h;
-
- sprite.origWidth = spriteFrameEntry.w;
- sprite.origHeight = spriteFrameEntry.h;
-
- if (drawRequest.flags & 0x1000) {
- xoffs = spriteFrameEntry.w - spriteFrameEntry.x;
- } else {
- xoffs = spriteFrameEntry.x;
- }
-
- yoffs = spriteFrameEntry.y;
-
- // If the sprite should be scaled we need to initialize some values now
-
- if (drawRequest.scaling != 0) {
-
- byte scaleValue = ABS(drawRequest.scaling);
-
- scaleValueX = scaleValue * sprite.origWidth;
- sprite.xdelta = (10000 * sprite.origWidth) / scaleValueX;
- scaleValueX /= 100;
-
- scaleValueY = scaleValue * sprite.origHeight;
- sprite.ydelta = (10000 * sprite.origHeight) / scaleValueY;
- scaleValueY /= 100;
-
- if (drawRequest.scaling > 0) {
- sprite.flags |= 2;
- sprite.width = sprite.origWidth + scaleValueX;
- sprite.height = sprite.origHeight + scaleValueY;
- xoffs += (xoffs * scaleValue) / 100;
- yoffs += (yoffs * scaleValue) / 100;
- } else {
- sprite.flags |= 1;
- sprite.width = sprite.origWidth - scaleValueX;
- sprite.height = sprite.origHeight - 1 - scaleValueY;
- if (sprite.width <= 0 || sprite.height <= 0)
- return;
- xoffs -= (xoffs * scaleValue) / 100;
- yoffs -= (yoffs * scaleValue) / 100;
- }
-
- }
-
- sprite.x -= xoffs;
- sprite.y -= yoffs;
-
- sprite.yerror = sprite.ydelta;
-
- // Now we check if the sprite needs to be clipped
-
- // Clip Y
- if (sprite.y - _vm->_cameraY < 0) {
-
- int16 clipHeight = ABS(sprite.y - _vm->_cameraY);
- int16 chopHeight, skipHeight, lineWidth;
- byte *spriteFrameData;
-
- sprite.height -= clipHeight;
- if (sprite.height <= 0)
- return;
-
- sprite.y = _vm->_cameraY;
-
- // If the sprite is scaled
- if (sprite.flags & 3) {
- chopHeight = sprite.ydelta;
- skipHeight = clipHeight;
- if ((sprite.flags & 2) == 0) {
- do {
- chopHeight -= 100;
- if (chopHeight <= 0) {
- skipHeight++;
- chopHeight += sprite.ydelta;
- } else {
- clipHeight--;
- }
- } while (clipHeight > 0);
- } else {
- do {
- chopHeight -= 100;
- if (chopHeight < 0) {
- skipHeight--;
- chopHeight += sprite.ydelta + 100;
- }
- clipHeight--;
- } while (clipHeight > 0);
- }
- sprite.yerror = chopHeight;
- }
-
- spriteFrameData = spriteData + sprite.offset;
-
- // Now the sprite's offset is adjusted to point to the starting line
- if ((sprite.flags & 0x10) == 0) {
- while (clipHeight--) {
- lineWidth = 0;
- while (lineWidth </*CHECKME was != */ sprite.origWidth) {
- sprite.offset++;
- lineWidth += (*spriteFrameData++) & 0x0F;
- }
- }
- } else {
- lineWidth = 0;
- while (clipHeight--) {
- while (lineWidth < sprite.origWidth) {
- sprite.offset += 2;
- spriteFrameData++;
- lineWidth += *spriteFrameData++;
- }
- }
- }
-
- }
-
- if (sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight > 0)
- sprite.height -= sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight;
- if (sprite.height <= 0)
- return;
-
- sprite.skipX = 0;
-
- if (drawRequest.flags & 0x1000) {
- // Left border
- if (sprite.x - _vm->_cameraX < 0) {
- sprite.width -= ABS(sprite.x - _vm->_cameraX);
- sprite.x = _vm->_cameraX;
- }
- // Right border
- if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
- sprite.flags |= 8;
- sprite.skipX = sprite.x + sprite.width - _vm->_cameraX - 640;
- sprite.width -= sprite.skipX;
- }
- } else {
- // Left border
- if (sprite.x - _vm->_cameraX < 0) {
- sprite.flags |= 8;
- sprite.skipX = ABS(sprite.x - _vm->_cameraX);
- sprite.width -= sprite.skipX;
- sprite.x = _vm->_cameraX;
- }
- // Right border
- if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
- sprite.flags |= 8;
- sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
- }
- }
-
- if (sprite.width <= 0)
- return;
-
- // Add sprite sorted by priority
- Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin();
- while (iter != _spriteDrawList.end() && (*iter).ybottom <= sprite.ybottom) {
- iter++;
- }
- _spriteDrawList.insert(iter, sprite);
-
-}
-
-void Screen::drawSprite(SpriteDrawItem *sprite) {
-
- debug(0, "Screen::drawSprite() x = %d; y = %d; flags = %04X; resIndex = %d; offset = %08X; drawX = %d; drawY = %d",
- sprite->x, sprite->y, sprite->flags, sprite->resIndex, sprite->offset,
- sprite->x - _vm->_cameraX, sprite->y - _vm->_cameraY);
- debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
- sprite->width, sprite->height, sprite->origWidth, sprite->origHeight);
-
- byte *source = _vm->_res->load(sprite->resIndex) + sprite->offset;
- byte *dest = _frontScreen + (sprite->x - _vm->_cameraX) + (sprite->y - _vm->_cameraY) * 640;
-
- SpriteReader spriteReader(source, sprite);
-
- if (sprite->flags & 0x40) {
- // Shadow sprites
- if (sprite->flags & 1) {
- SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
- drawSpriteCore(dest, spriteScaler, sprite);
- } else if (sprite->flags & 2) {
- SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
- drawSpriteCore(dest, spriteScaler, sprite);
- } else {
- drawSpriteCore(dest, spriteReader, sprite);
- }
- } else if (sprite->flags & 0x10) {
- // 256 color sprite
- drawSpriteCore(dest, spriteReader, sprite);
- } else {
- // 16 color sprite
- if (sprite->flags & 1) {
- SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
- drawSpriteCore(dest, spriteScaler, sprite);
- } else if (sprite->flags & 2) {
- SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
- drawSpriteCore(dest, spriteScaler, sprite);
- } else {
- drawSpriteCore(dest, spriteReader, sprite);
- }
- }
-
- debug(0, "Screen::drawSprite() ok");
-
-}
-
-void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite) {
-
- int16 destInc;
-
- if (sprite->flags & 4) {
- destInc = -1;
- dest += sprite->width;
- } else {
- destInc = 1;
- }
-
- SpriteReaderStatus status;
- PixelPacket packet;
-
- byte *destp = dest;
- int16 skipX = sprite->skipX;
-
- int16 w = sprite->width;
- int16 h = sprite->height;
-
- do {
- status = reader.readPacket(packet);
-
- if (skipX > 0) {
- while (skipX > 0) {
- skipX -= packet.count;
- if (skipX < 0) {
- packet.count = ABS(skipX);
- break;
- }
- status = reader.readPacket(packet);
- }
- }
-
- if (w - packet.count < 0)
- packet.count = w;
-
- w -= packet.count;
-
- if (((sprite->flags & 0x40) && (packet.pixel != 0)) ||
- ((sprite->flags & 0x10) && (packet.pixel != 0xFF)) ||
- !(sprite->flags & 0x10) && (packet.pixel != 0))
- {
- if (sprite->flags & 0x40) {
- while (packet.count--) {
- *dest = _vm->_palette->getColorTransPixel(*dest);
- dest += destInc;
- }
- } else {
- if (sprite->flags & 0x10) {
- packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
- } else {
- packet.pixel += sprite->baseColor - 1;
- }
- while (packet.count--) {
- *dest = packet.pixel;
- dest += destInc;
- }
- }
- } else {
- dest += packet.count * destInc;
- }
-
- if (status == kSrsEndOfLine || w <= 0) {
- if (w <= 0) {
- while (status == kSrsPixelsLeft) {
- status = reader.readPacket(packet);
- }
- }
- dest = destp + 640;
- destp = dest;
- skipX = sprite->skipX;
- w = sprite->width;
- h--;
- }
-
- } while (status != kSrsEndOfSprite && h > 0);
-
-}
-
-void Screen::drawSprites() {
- for (Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin(); iter != _spriteDrawList.end(); iter++) {
- SpriteDrawItem *sprite = &(*iter);
- drawSprite(sprite);
- _vm->_segmap->restoreMasksBySprite(sprite);
- }
-}
-
void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
debug(0, "Screen::updateVerbLine() _verbLineNum = %d; _verbLineX = %d; _verbLineY = %d; _verbLineWidth = %d; _verbLineCount = %d",
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 6050257..0e18860 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -120,8 +120,6 @@ protected:
byte *_fontData;
};
-//*BEGIN*TEST*CODE********************************************************************************************
-
struct PixelPacket {
byte count;
byte pixel;
@@ -142,157 +140,6 @@ protected:
SpriteDrawItem *_sprite;
};
-class SpriteReader : public SpriteFilter {
-public:
- SpriteReader(byte *source, SpriteDrawItem *sprite) : SpriteFilter(sprite), _source(source) {
- _curWidth = _sprite->origWidth;
- _curHeight = _sprite->origHeight;
- }
- SpriteReaderStatus readPacket(PixelPacket &packet) {
- if (_sprite->flags & 0x40) {
- // shadow sprite
- packet.count = _source[0] & 0x7F;
- if (_source[0] & 0x80)
- packet.pixel = 1;
- else
- packet.pixel = 0;
- _source++;
- } else if (_sprite->flags & 0x10) {
- // 256-color sprite
- packet.pixel = *_source++;
- packet.count = *_source++;
- } else {
- // 16-color sprite
- packet.count = _source[0] & 0x0F;
- packet.pixel = (_source[0] & 0xF0) >> 4;
- _source++;
- }
- _curWidth -= packet.count;
- if (_curWidth <= 0) {
- _curHeight--;
- if (_curHeight == 0) {
- return kSrsEndOfSprite;
- } else {
- _curWidth = _sprite->origWidth;
- return kSrsEndOfLine;
- }
- } else {
- return kSrsPixelsLeft;
- }
- }
- byte *getSource() {
- return _source;
- }
- void setSource(byte *source) {
- _source = source;
- _curHeight++;
- }
-protected:
- byte *_source;
- int16 _curWidth, _curHeight;
-};
-
-class SpriteFilterScaleDown : public SpriteFilter {
-public:
- SpriteFilterScaleDown(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
- _height = _sprite->height;
- _yerror = _sprite->yerror;
- _origHeight = _sprite->origHeight;
- _scalerStatus = 0;
- }
- SpriteReaderStatus readPacket(PixelPacket &packet) {
- SpriteReaderStatus status;
- if (_scalerStatus == 0) {
- _xerror = _sprite->xdelta;
- _yerror -= 100;
- while (_yerror <= 0) {
- do {
- status = _reader->readPacket(packet);
- } while (status == kSrsPixelsLeft);
- _yerror += _sprite->ydelta - 100;
- }
- if (status == kSrsEndOfSprite)
- return kSrsEndOfSprite;
- _scalerStatus = 1;
- }
- if (_scalerStatus == 1) {
- status = _reader->readPacket(packet);
- byte updcount = packet.count;
- while (updcount--) {
- _xerror -= 100;
- if (_xerror <= 0) {
- if (packet.count > 0)
- packet.count--;
- _xerror += _sprite->xdelta;
- }
- }
- if (status == kSrsEndOfLine) {
- if (--_height == 0)
- return kSrsEndOfSprite;
- _scalerStatus = 0;
- return kSrsEndOfLine;
- }
- }
- return kSrsPixelsLeft;
- }
-protected:
- SpriteReader *_reader;
- int16 _xerror, _yerror;
- int16 _height;
- int16 _origHeight;
- int _scalerStatus;
-};
-
-class SpriteFilterScaleUp : public SpriteFilter {
-public:
- SpriteFilterScaleUp(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
- _height = _sprite->height;
- _yerror = _sprite->yerror;
- _origHeight = _sprite->origHeight;
- _scalerStatus = 0;
- }
- SpriteReaderStatus readPacket(PixelPacket &packet) {
- SpriteReaderStatus status;
- if (_scalerStatus == 0) {
- _xerror = _sprite->xdelta;
- _sourcep = _reader->getSource();
- _scalerStatus = 1;
- }
- if (_scalerStatus == 1) {
- status = _reader->readPacket(packet);
- byte updcount = packet.count;
- while (updcount--) {
- _xerror -= 100;
- if (_xerror <= 0) {
- packet.count++;
- _xerror += _sprite->xdelta;
- }
- }
- if (status == kSrsEndOfLine) {
- if (--_height == 0)
- return kSrsEndOfSprite;
- _yerror -= 100;
- if (_yerror <= 0) {
- _reader->setSource(_sourcep);
- _yerror += _sprite->ydelta + 100;
- }
- _scalerStatus = 0;
- return kSrsEndOfLine;
- }
- }
- return kSrsPixelsLeft;
- }
-protected:
- SpriteReader *_reader;
- byte *_sourcep;
- int16 _xerror, _yerror;
- int16 _height;
- int16 _origHeight;
- int _scalerStatus;
-};
-
-//*END*TEST*CODE**********************************************************************************************
-
struct TextRect {
int16 x, y;
int16 width, length;
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
new file mode 100644
index 0000000..b9f8ffe
--- /dev/null
+++ b/engines/toltecs/sprite.cpp
@@ -0,0 +1,535 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "graphics/cursorman.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/palette.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+#include "toltecs/script.h"
+#include "toltecs/segmap.h"
+
+namespace Toltecs {
+
+class SpriteReader : public SpriteFilter {
+public:
+ SpriteReader(byte *source, SpriteDrawItem *sprite) : SpriteFilter(sprite), _source(source) {
+ _curWidth = _sprite->origWidth;
+ _curHeight = _sprite->origHeight;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ if (_sprite->flags & 0x40) {
+ // shadow sprite
+ packet.count = _source[0] & 0x7F;
+ if (_source[0] & 0x80)
+ packet.pixel = 1;
+ else
+ packet.pixel = 0;
+ _source++;
+ } else if (_sprite->flags & 0x10) {
+ // 256-color sprite
+ packet.pixel = *_source++;
+ packet.count = *_source++;
+ } else {
+ // 16-color sprite
+ packet.count = _source[0] & 0x0F;
+ packet.pixel = (_source[0] & 0xF0) >> 4;
+ _source++;
+ }
+ _curWidth -= packet.count;
+ if (_curWidth <= 0) {
+ _curHeight--;
+ if (_curHeight == 0) {
+ return kSrsEndOfSprite;
+ } else {
+ _curWidth = _sprite->origWidth;
+ return kSrsEndOfLine;
+ }
+ } else {
+ return kSrsPixelsLeft;
+ }
+ }
+ byte *getSource() {
+ return _source;
+ }
+ void setSource(byte *source) {
+ _source = source;
+ _curHeight++;
+ }
+protected:
+ byte *_source;
+ int16 _curWidth, _curHeight;
+};
+
+class SpriteFilterScaleDown : public SpriteFilter {
+public:
+ SpriteFilterScaleDown(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ _height = _sprite->height;
+ _yerror = _sprite->yerror;
+ _origHeight = _sprite->origHeight;
+ _scalerStatus = 0;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ SpriteReaderStatus status;
+ if (_scalerStatus == 0) {
+ _xerror = _sprite->xdelta;
+ _yerror -= 100;
+ while (_yerror <= 0) {
+ do {
+ status = _reader->readPacket(packet);
+ } while (status == kSrsPixelsLeft);
+ _yerror += _sprite->ydelta - 100;
+ }
+ if (status == kSrsEndOfSprite)
+ return kSrsEndOfSprite;
+ _scalerStatus = 1;
+ }
+ if (_scalerStatus == 1) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ if (packet.count > 0)
+ packet.count--;
+ _xerror += _sprite->xdelta;
+ }
+ }
+ if (status == kSrsEndOfLine) {
+ if (--_height == 0)
+ return kSrsEndOfSprite;
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
+ }
+ }
+ return kSrsPixelsLeft;
+ }
+protected:
+ SpriteReader *_reader;
+ int16 _xerror, _yerror;
+ int16 _height;
+ int16 _origHeight;
+ int _scalerStatus;
+};
+
+class SpriteFilterScaleUp : public SpriteFilter {
+public:
+ SpriteFilterScaleUp(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ _height = _sprite->height;
+ _yerror = _sprite->yerror;
+ _origHeight = _sprite->origHeight;
+ _scalerStatus = 0;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ SpriteReaderStatus status;
+ if (_scalerStatus == 0) {
+ _xerror = _sprite->xdelta;
+ _sourcep = _reader->getSource();
+ _scalerStatus = 1;
+ }
+ if (_scalerStatus == 1) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ packet.count++;
+ _xerror += _sprite->xdelta;
+ }
+ }
+ if (status == kSrsEndOfLine) {
+ if (--_height == 0)
+ return kSrsEndOfSprite;
+ _yerror -= 100;
+ if (_yerror <= 0) {
+ _reader->setSource(_sourcep);
+ _yerror += _sprite->ydelta + 100;
+ }
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
+ }
+ }
+ return kSrsPixelsLeft;
+ }
+protected:
+ SpriteReader *_reader;
+ byte *_sourcep;
+ int16 _xerror, _yerror;
+ int16 _height;
+ int16 _origHeight;
+ int _scalerStatus;
+};
+
+void Screen::addDrawRequest(const DrawRequest &drawRequest) {
+
+ int16 scaleValueX, scaleValueY;
+ int16 xoffs, yoffs;
+ byte *spriteData;
+ int16 frameNum;
+
+ SpriteDrawItem sprite;
+ memset(&sprite, 0, sizeof(SpriteDrawItem));
+
+ if (drawRequest.flags == 0xFFFF)
+ return;
+
+ sprite.flags = 0;
+ sprite.baseColor = drawRequest.baseColor;
+ sprite.x = drawRequest.x;
+ sprite.y = drawRequest.y;
+ sprite.ybottom = drawRequest.y;
+ sprite.resIndex = drawRequest.resIndex;
+
+ spriteData = _vm->_res->load(drawRequest.resIndex);
+
+ if (drawRequest.flags & 0x1000) {
+ sprite.flags |= 4;
+ }
+
+ if (drawRequest.flags & 0x2000) {
+ sprite.flags |= 0x10;
+ }
+
+ if (drawRequest.flags & 0x4000) {
+ sprite.flags |= 0x40;
+ }
+
+ frameNum = drawRequest.flags & 0x0FFF;
+
+ // First initialize the sprite item with the values from the sprite resource
+
+ SpriteFrameEntry spriteFrameEntry(spriteData + frameNum * 12);
+
+ if (spriteFrameEntry.w == 0 || spriteFrameEntry.h == 0)
+ return;
+
+ sprite.offset = spriteFrameEntry.offset;
+
+ sprite.width = spriteFrameEntry.w;
+ sprite.height = spriteFrameEntry.h;
+
+ sprite.origWidth = spriteFrameEntry.w;
+ sprite.origHeight = spriteFrameEntry.h;
+
+ if (drawRequest.flags & 0x1000) {
+ xoffs = spriteFrameEntry.w - spriteFrameEntry.x;
+ } else {
+ xoffs = spriteFrameEntry.x;
+ }
+
+ yoffs = spriteFrameEntry.y;
+
+ // If the sprite should be scaled we need to initialize some values now
+
+ if (drawRequest.scaling != 0) {
+
+ byte scaleValue = ABS(drawRequest.scaling);
+
+ scaleValueX = scaleValue * sprite.origWidth;
+ sprite.xdelta = (10000 * sprite.origWidth) / scaleValueX;
+ scaleValueX /= 100;
+
+ scaleValueY = scaleValue * sprite.origHeight;
+ sprite.ydelta = (10000 * sprite.origHeight) / scaleValueY;
+ scaleValueY /= 100;
+
+ if (drawRequest.scaling > 0) {
+ sprite.flags |= 2;
+ sprite.width = sprite.origWidth + scaleValueX;
+ sprite.height = sprite.origHeight + scaleValueY;
+ xoffs += (xoffs * scaleValue) / 100;
+ yoffs += (yoffs * scaleValue) / 100;
+ } else {
+ sprite.flags |= 1;
+ sprite.width = sprite.origWidth - scaleValueX;
+ sprite.height = sprite.origHeight - 1 - scaleValueY;
+ if (sprite.width <= 0 || sprite.height <= 0)
+ return;
+ xoffs -= (xoffs * scaleValue) / 100;
+ yoffs -= (yoffs * scaleValue) / 100;
+ }
+
+ }
+
+ sprite.x -= xoffs;
+ sprite.y -= yoffs;
+
+ sprite.yerror = sprite.ydelta;
+
+ // Now we check if the sprite needs to be clipped
+
+ // Clip Y
+ if (sprite.y - _vm->_cameraY < 0) {
+
+ int16 clipHeight = ABS(sprite.y - _vm->_cameraY);
+ int16 chopHeight, skipHeight, lineWidth;
+ byte *spriteFrameData;
+
+ sprite.height -= clipHeight;
+ if (sprite.height <= 0)
+ return;
+
+ sprite.y = _vm->_cameraY;
+
+ // If the sprite is scaled
+ if (sprite.flags & 3) {
+ chopHeight = sprite.ydelta;
+ skipHeight = clipHeight;
+ if ((sprite.flags & 2) == 0) {
+ do {
+ chopHeight -= 100;
+ if (chopHeight <= 0) {
+ skipHeight++;
+ chopHeight += sprite.ydelta;
+ } else {
+ clipHeight--;
+ }
+ } while (clipHeight > 0);
+ } else {
+ do {
+ chopHeight -= 100;
+ if (chopHeight < 0) {
+ skipHeight--;
+ chopHeight += sprite.ydelta + 100;
+ }
+ clipHeight--;
+ } while (clipHeight > 0);
+ }
+ sprite.yerror = chopHeight;
+ }
+
+ spriteFrameData = spriteData + sprite.offset;
+
+ // Now the sprite's offset is adjusted to point to the starting line
+ if ((sprite.flags & 0x10) == 0) {
+ while (clipHeight--) {
+ lineWidth = 0;
+ while (lineWidth </*CHECKME was != */ sprite.origWidth) {
+ sprite.offset++;
+ lineWidth += (*spriteFrameData++) & 0x0F;
+ }
+ }
+ } else {
+ lineWidth = 0;
+ while (clipHeight--) {
+ while (lineWidth < sprite.origWidth) {
+ sprite.offset += 2;
+ spriteFrameData++;
+ lineWidth += *spriteFrameData++;
+ }
+ }
+ }
+
+ }
+
+ if (sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight > 0)
+ sprite.height -= sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight;
+ if (sprite.height <= 0)
+ return;
+
+ sprite.skipX = 0;
+
+ if (drawRequest.flags & 0x1000) {
+ // Left border
+ if (sprite.x - _vm->_cameraX < 0) {
+ sprite.width -= ABS(sprite.x - _vm->_cameraX);
+ sprite.x = _vm->_cameraX;
+ }
+ // Right border
+ if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
+ sprite.flags |= 8;
+ sprite.skipX = sprite.x + sprite.width - _vm->_cameraX - 640;
+ sprite.width -= sprite.skipX;
+ }
+ } else {
+ // Left border
+ if (sprite.x - _vm->_cameraX < 0) {
+ sprite.flags |= 8;
+ sprite.skipX = ABS(sprite.x - _vm->_cameraX);
+ sprite.width -= sprite.skipX;
+ sprite.x = _vm->_cameraX;
+ }
+ // Right border
+ if (sprite.x + sprite.width - _vm->_cameraX - 640 > 0) {
+ sprite.flags |= 8;
+ sprite.width -= sprite.x + sprite.width - _vm->_cameraX - 640;
+ }
+ }
+
+ if (sprite.width <= 0)
+ return;
+
+ // Add sprite sorted by priority
+ Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin();
+ while (iter != _spriteDrawList.end() && (*iter).ybottom <= sprite.ybottom) {
+ iter++;
+ }
+ _spriteDrawList.insert(iter, sprite);
+
+}
+
+void Screen::drawSprite(SpriteDrawItem *sprite) {
+
+ debug(0, "Screen::drawSprite() x = %d; y = %d; flags = %04X; resIndex = %d; offset = %08X; drawX = %d; drawY = %d",
+ sprite->x, sprite->y, sprite->flags, sprite->resIndex, sprite->offset,
+ sprite->x - _vm->_cameraX, sprite->y - _vm->_cameraY);
+ debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
+ sprite->width, sprite->height, sprite->origWidth, sprite->origHeight);
+
+ byte *source = _vm->_res->load(sprite->resIndex) + sprite->offset;
+ byte *dest = _frontScreen + (sprite->x - _vm->_cameraX) + (sprite->y - _vm->_cameraY) * 640;
+
+ SpriteReader spriteReader(source, sprite);
+
+ if (sprite->flags & 0x40) {
+ // Shadow sprites
+ if (sprite->flags & 1) {
+ SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else if (sprite->flags & 2) {
+ SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else {
+ drawSpriteCore(dest, spriteReader, sprite);
+ }
+ } else if (sprite->flags & 0x10) {
+ // 256 color sprite
+ drawSpriteCore(dest, spriteReader, sprite);
+ } else {
+ // 16 color sprite
+ if (sprite->flags & 1) {
+ SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else if (sprite->flags & 2) {
+ SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
+ drawSpriteCore(dest, spriteScaler, sprite);
+ } else {
+ drawSpriteCore(dest, spriteReader, sprite);
+ }
+ }
+
+ debug(0, "Screen::drawSprite() ok");
+
+}
+
+void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite) {
+
+ int16 destInc;
+
+ if (sprite->flags & 4) {
+ destInc = -1;
+ dest += sprite->width;
+ } else {
+ destInc = 1;
+ }
+
+ SpriteReaderStatus status;
+ PixelPacket packet;
+
+ byte *destp = dest;
+ int16 skipX = sprite->skipX;
+
+ int16 w = sprite->width;
+ int16 h = sprite->height;
+
+ do {
+ status = reader.readPacket(packet);
+
+ if (skipX > 0) {
+ while (skipX > 0) {
+ skipX -= packet.count;
+ if (skipX < 0) {
+ packet.count = ABS(skipX);
+ break;
+ }
+ status = reader.readPacket(packet);
+ }
+ }
+
+ if (w - packet.count < 0)
+ packet.count = w;
+
+ w -= packet.count;
+
+ if (((sprite->flags & 0x40) && (packet.pixel != 0)) ||
+ ((sprite->flags & 0x10) && (packet.pixel != 0xFF)) ||
+ !(sprite->flags & 0x10) && (packet.pixel != 0))
+ {
+ if (sprite->flags & 0x40) {
+ while (packet.count--) {
+ *dest = _vm->_palette->getColorTransPixel(*dest);
+ dest += destInc;
+ }
+ } else {
+ if (sprite->flags & 0x10) {
+ packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
+ } else {
+ packet.pixel += sprite->baseColor - 1;
+ }
+ while (packet.count--) {
+ *dest = packet.pixel;
+ dest += destInc;
+ }
+ }
+ } else {
+ dest += packet.count * destInc;
+ }
+
+ if (status == kSrsEndOfLine || w <= 0) {
+ if (w <= 0) {
+ while (status == kSrsPixelsLeft) {
+ status = reader.readPacket(packet);
+ }
+ }
+ dest = destp + 640;
+ destp = dest;
+ skipX = sprite->skipX;
+ w = sprite->width;
+ h--;
+ }
+
+ } while (status != kSrsEndOfSprite && h > 0);
+
+}
+
+void Screen::drawSprites() {
+ for (Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin(); iter != _spriteDrawList.end(); iter++) {
+ SpriteDrawItem *sprite = &(*iter);
+ drawSprite(sprite);
+ _vm->_segmap->restoreMasksBySprite(sprite);
+ }
+}
+
+} // End of namespace Toltecs
Commit: 150e555953d8efae73d1275e138586c91f655809
https://github.com/scummvm/scummvm/commit/150e555953d8efae73d1275e138586c91f655809
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Renamed ybottom to priority
Changed paths:
engines/toltecs/screen.h
engines/toltecs/segmap.cpp
engines/toltecs/segmap.h
engines/toltecs/sprite.cpp
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 0e18860..e886631 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -64,7 +64,7 @@ struct SpriteDrawItem {
int16 xdelta, ydelta;
uint16 flags;
int16 skipX, yerror;
- int16 ybottom;
+ int16 priority;
int16 baseColor;
};
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index f0b3082..28965ce 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -75,10 +75,10 @@ void SegmentMap::load(byte *source) {
maskRect.width = READ_LE_UINT16(source + 6);
maskRect.maskOffset = READ_LE_UINT16(source + 8);
maskRect.maskOffset -= maskRectDataSize;
- maskRect.ybottom = READ_LE_UINT16(source + 10);
+ maskRect.priority = READ_LE_UINT16(source + 10);
debug(0, "SegmentMap::load() (%d, %d, %d, %d, %04X, %d)",
- maskRect.x, maskRect.y, maskRect.width, maskRect.height, maskRect.maskOffset, maskRect.ybottom);
+ maskRect.x, maskRect.y, maskRect.width, maskRect.height, maskRect.maskOffset, maskRect.priority);
source += 12;
_maskRects.push_back(maskRect);
@@ -393,7 +393,7 @@ void SegmentMap::restoreMasksBySprite(SpriteDrawItem *sprite) {
for (uint i = 0; i < _maskRects.size(); i++) {
#if 0
- if ( *(__int16 *)((char *)&spriteDrawList[0].y2 + v5) <= (unsigned __int16)v3->ybottom )
+ if ( *(__int16 *)((char *)&spriteDrawList[0].y2 + v5) <= (unsigned __int16)v3->priority )
{
if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].height + v5)
+ *(__int16 *)((char *)&spriteDrawList[0].y + v5)) > v3->y )
@@ -408,7 +408,7 @@ void SegmentMap::restoreMasksBySprite(SpriteDrawItem *sprite) {
#endif
- if (sprite->ybottom <= _maskRects[i].ybottom) {
+ if (sprite->priority <= _maskRects[i].priority) {
restoreMask(i);
}
}
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index a625c84..7e5150b 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -83,7 +83,7 @@ public: // for debugging purposes
int16 y, x;
int16 height, width;
int16 maskOffset;
- int16 ybottom;
+ int16 priority;
};
struct SegmapPathRect {
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index b9f8ffe..3327f04 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -209,7 +209,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.baseColor = drawRequest.baseColor;
sprite.x = drawRequest.x;
sprite.y = drawRequest.y;
- sprite.ybottom = drawRequest.y;
+ sprite.priority = drawRequest.y;
sprite.resIndex = drawRequest.resIndex;
spriteData = _vm->_res->load(drawRequest.resIndex);
@@ -393,7 +393,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
// Add sprite sorted by priority
Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin();
- while (iter != _spriteDrawList.end() && (*iter).ybottom <= sprite.ybottom) {
+ while (iter != _spriteDrawList.end() && (*iter).priority <= sprite.priority) {
iter++;
}
_spriteDrawList.insert(iter, sprite);
Commit: d299bbba01d3955d41d2ca3ebddca98a31f7eb27
https://github.com/scummvm/scummvm/commit/d299bbba01d3955d41d2ca3ebddca98a31f7eb27
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Changed how screen masks are handled.
At load time, a Surface is created for each screen mask, in which the gfx data from the background is copied.
This is the first step towards more optimized gfx rendering (more to come later).
Changed paths:
engines/toltecs/segmap.cpp
engines/toltecs/segmap.h
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 28965ce..6a3f849 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -43,22 +43,23 @@
namespace Toltecs {
SegmentMap::SegmentMap(ToltecsEngine *vm) : _vm(vm) {
- _maskRectData = new byte[32768];
}
SegmentMap::~SegmentMap() {
- delete[] _maskRectData;
+ freeSegmapMaskRectSurfaces();
}
void SegmentMap::load(byte *source) {
// TODO: Use MemoryReadStream
+ freeSegmapMaskRectSurfaces();
_maskRects.clear();
_pathRects.clear();
_infoRects.clear();
// Load mask rects
+ byte *maskData = source + 2;
uint16 maskSize = READ_LE_UINT16(source);
source += 2;
uint16 maskRectCount = READ_LE_UINT16(source);
@@ -69,24 +70,24 @@ void SegmentMap::load(byte *source) {
for (uint16 i = 0; i < maskRectCount; i++) {
SegmapMaskRect maskRect;
+ int16 maskOffset;
maskRect.y = READ_LE_UINT16(source);
maskRect.x = READ_LE_UINT16(source + 2);
maskRect.height = READ_LE_UINT16(source + 4);
maskRect.width = READ_LE_UINT16(source + 6);
- maskRect.maskOffset = READ_LE_UINT16(source + 8);
- maskRect.maskOffset -= maskRectDataSize;
+ maskOffset = READ_LE_UINT16(source + 8);
maskRect.priority = READ_LE_UINT16(source + 10);
+ loadSegmapMaskRectSurface(maskData + maskOffset, maskRect);
debug(0, "SegmentMap::load() (%d, %d, %d, %d, %04X, %d)",
- maskRect.x, maskRect.y, maskRect.width, maskRect.height, maskRect.maskOffset, maskRect.priority);
+ maskRect.x, maskRect.y, maskRect.width, maskRect.height, maskOffset, maskRect.priority);
source += 12;
_maskRects.push_back(maskRect);
}
- memcpy(_maskRectData, source, maskSize - maskRectDataSize);
source += maskSize - maskRectDataSize;
-
+
// Load path rects
source += 2; // skip rects array size
@@ -304,7 +305,7 @@ void SegmentMap::findPath(int16 *pointsArray, int16 destX, int16 destY, int16 so
pointsCount = 2;
- adjustPathPoint(sourceX, sourceY);
+ adjustPathPoint(sourceX, sourceY);
currentRectIndex = findPathRectAtPoint(sourceX, sourceY);
adjustPathPoint(destX, destY);
@@ -388,44 +389,59 @@ void SegmentMap::getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byt
debug(0, "SegmentMap::getRgbModifiertAtPoint() r: %d; g: %d; b: %d", r, g, b);
}
+void SegmentMap::loadSegmapMaskRectSurface(byte *maskData, SegmapMaskRect &maskRect) {
+
+ maskRect.surface = new Graphics::Surface();
+ maskRect.surface->create(maskRect.width, maskRect.height, 1);
+
+ byte *backScreen = _vm->_screen->_backScreen + maskRect.x + (maskRect.y * _vm->_sceneWidth);
+ byte *dest = (byte*)maskRect.surface->getBasePtr(0, 0);
+
+ for (int16 h = 0; h < maskRect.height; h++) {
+ int16 w = maskRect.width;
+ while (w > 0) {
+ byte mask = *maskData++;
+ byte count = mask & 0x7F;
+ if (mask & 0x80)
+ memcpy(dest, backScreen, count);
+ else
+ memset(dest, 0xFF, count);
+ w -= count;
+ dest += count;
+ backScreen += count;
+ }
+ backScreen += _vm->_sceneWidth - maskRect.width;
+ }
+
+}
+
+void SegmentMap::freeSegmapMaskRectSurfaces() {
+ for (uint i = 0; i < _maskRects.size(); i++) {
+ delete _maskRects[i].surface;
+ }
+}
+
void SegmentMap::restoreMasksBySprite(SpriteDrawItem *sprite) {
// TODO: This needs more optimization
for (uint i = 0; i < _maskRects.size(); i++) {
-
-#if 0
- if ( *(__int16 *)((char *)&spriteDrawList[0].y2 + v5) <= (unsigned __int16)v3->priority )
- {
- if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].height + v5)
- + *(__int16 *)((char *)&spriteDrawList[0].y + v5)) > v3->y )
- {
- if ( (unsigned __int16)(v3->height + v3->y) > *(__int16 *)((char *)&spriteDrawList[0].y + v5) )
- {
- if ( (unsigned __int16)(*(__int16 *)((char *)&spriteDrawList[0].width + v5)
- + *(__int16 *)((char *)&spriteDrawList[0].x + v5)) > v3->x )
- {
- if ( (unsigned __int16)(v3->width + v3->x) > *(__int16 *)((char *)&spriteDrawList[0].x + v5) )
- {
-
-#endif
-
if (sprite->priority <= _maskRects[i].priority) {
restoreMask(i);
}
}
-
}
void SegmentMap::restoreMask(int16 index) {
+
// TODO: This needs more optimization
SegmapMaskRect *maskRect = &_maskRects[index];
- int16 maskX = maskRect->x, maskY = maskRect->y;
int16 skipX = 0;
int16 x = maskRect->x - _vm->_cameraX;
int16 y = maskRect->y - _vm->_cameraY;
int16 width = maskRect->width;
int16 height = maskRect->height;
- byte *mask = _maskRectData + maskRect->maskOffset;
+ byte *maskSurface = (byte*)maskRect->surface->getBasePtr(0, 0);
+ byte *frontScreen;
debug(0, "SegmentMap::restoreMask() screenX = %d; screenY = %d; maskX = %d; maskY = %d",
x, y, maskRect->x, maskRect->y);
@@ -437,19 +453,14 @@ void SegmentMap::restoreMask(int16 index) {
if (x < 0) {
skipX = -x;
x = 0;
+ width -= skipX;
}
if (y < 0) {
int16 skipY = -y;
- for (int16 h = 0; h < skipY; h++) {
- int16 w = width;
- while (w > 0) {
- w -= (*mask++) & 0x7F;
- }
- }
+ maskSurface += maskRect->width * skipY;
y = 0;
height -= skipY;
- maskY += skipY;
}
if (x + width >= 640) {
@@ -460,38 +471,20 @@ void SegmentMap::restoreMask(int16 index) {
height -= y + height - _vm->_cameraHeight;
}
- byte *backScreen = _vm->_screen->_backScreen + maskX + (maskY * _vm->_sceneWidth);
- byte *frontScreen = _vm->_screen->_frontScreen + x + (y * 640);
+ frontScreen = _vm->_screen->_frontScreen + x + (y * 640);
for (int16 h = 0; h < height; h++) {
- byte *src = backScreen;
- byte *dst = frontScreen;
- byte maskLine[640], *maskLineP = maskLine;
-
- int16 w = width;
- while (w > 0) {
- byte m = *mask++;
- byte count = m & 0x7F;
- if (m & 0x80)
- memset(maskLineP, 1, count);
- else
- memset(maskLineP, 0, count);
- maskLineP += count;
- w -= count;
- }
-
- src += skipX;
- for (int16 c = skipX; c < width; c++) {
- if (maskLine[c] == 1)
- *dst = *src;
- dst++;
- src++;
+ maskSurface += skipX;
+ for (int16 w = 0; w < width; w++) {
+ if (*maskSurface != 0xFF)
+ *frontScreen = *maskSurface;
+ frontScreen++;
+ maskSurface++;
}
-
- backScreen += _vm->_sceneWidth;
- frontScreen += 640;
+ frontScreen += 640 - width;
+ maskSurface += maskRect->width - width - skipX;
}
-
+
}
void SegmentMap::debugDrawRects(Graphics::Surface *surf) {
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index 7e5150b..6c20eac 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -80,17 +80,13 @@ public:
public: // for debugging purposes
struct SegmapMaskRect {
- int16 y, x;
- int16 height, width;
- int16 maskOffset;
+ int16 x, y;
+ int16 width, height;
int16 priority;
+ Graphics::Surface *surface;
};
struct SegmapPathRect {
- /*
- int16 y, x;
- int16 height, width;
- */
int16 x1, y1, x2, y2;
};
@@ -128,6 +124,9 @@ public: // for debugging purposes
int16 findNextPathRect(int16 srcRectIndex, int16 destX, int16 destY);
+ void loadSegmapMaskRectSurface(byte *maskData, SegmapMaskRect &maskRect);
+ void freeSegmapMaskRectSurfaces();
+
};
} // End of namespace Toltecs
Commit: 8f3e598f8553d0eb7b292affca58e481000a5607
https://github.com/scummvm/scummvm/commit/8f3e598f8553d0eb7b292affca58e481000a5607
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Cleanup.
Changed paths:
engines/toltecs/saveload.cpp
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 18dd237..99bbc05 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -88,21 +88,6 @@ void ToltecsEngine::savegame(const char *filename) {
_anim->saveState(out);
_screen->saveState(out);
-/*
-case 0: return "mouseDisabled";
-case 1: return "mouseY";
-case 2: return "mouseX";
-case 3: return "mouseButton";
-*/
-
-/*
-PersistentGameVarRef <offset screenFlag01, 2>
-PersistentGameVarRef <offset currentSequenceResIndex, 4>
-PersistentGameVarRef <offset currentSequenceLoopCount, 4>
-PersistentGameVarRef <offset sequenceVolume, 4>
-PersistentGameVarRef <offset dword_99AC0, 4>
-*/
-
delete out;
}
Commit: 37a5f9e9ef9039808b225f598d02c1c48bc9fa95
https://github.com/scummvm/scummvm/commit/37a5f9e9ef9039808b225f598d02c1c48bc9fa95
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Switched quicksave key from F6 to F5.
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index b6d9633..f9ebb41 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -268,7 +268,7 @@ void ToltecsEngine::updateInput() {
// FIXME: This is just for debugging
switch (event.kbd.keycode) {
- case Common::KEYCODE_F6:
+ case Common::KEYCODE_F5:
savegame("toltecs.001");
break;
case Common::KEYCODE_F9:
Commit: 7b97e8cd9370095b999b22371c1aef606a8464a1
https://github.com/scummvm/scummvm/commit/7b97e8cd9370095b999b22371c1aef606a8464a1
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: A lot of changes in the graphics code:
- Optimized drawing code; now only items (sprites, text, screen masks) which have changed from the previous frame are redrawn, this speeds up things a lot
- Implemented dirty rectangles using a microtile array
- The previously committed Microtile Array implementation from SEL seemed buggy so I wrote my own version which works nicely so far (and is less code and GPL), only MicroTileArray::getRectangles uses parts from the old version, this will be changed later
- One known bug related to dirty rectangles remains: Sometimes the background isn't restored correctly and gfx artifacts are visible
Changed paths:
A engines/toltecs/render.cpp
A engines/toltecs/render.h
engines/toltecs/animation.cpp
engines/toltecs/microtiles.cpp
engines/toltecs/microtiles.h
engines/toltecs/module.mk
engines/toltecs/saveload.cpp
engines/toltecs/screen.cpp
engines/toltecs/screen.h
engines/toltecs/segmap.cpp
engines/toltecs/segmap.h
engines/toltecs/sprite.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
index 34a1848..3175bf6 100644
--- a/engines/toltecs/animation.cpp
+++ b/engines/toltecs/animation.cpp
@@ -138,6 +138,7 @@ int16 AnimationPlayer::getStatus() {
void AnimationPlayer::unpackFrame() {
_vm->_screen->unpackRle(_animBuffer, _vm->_screen->_frontScreen, _width, _height);
_vm->_screen->unpackRle(_animBuffer, _vm->_screen->_backScreen, _width, _height);
+ _vm->_screen->_fullRefresh = true;
}
void AnimationPlayer::saveState(Common::WriteStream *out) {
diff --git a/engines/toltecs/microtiles.cpp b/engines/toltecs/microtiles.cpp
index 3cd5fac..7c82505 100644
--- a/engines/toltecs/microtiles.cpp
+++ b/engines/toltecs/microtiles.cpp
@@ -1,614 +1,135 @@
-/*
- SEL - Simple DirectMedia Layer Extension Library
- Copyright (C) 2002 Matej Knopp <knopp at users.sf.net>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-/* microtile arrays implementation */
-
-/*
- * This is a microtile array implementation similiar to the one
- * from LibArt_LGPL. First, I wanted to use that one but unfortunately
- * I fount out that it suffered from a bad design and simply didn't meet
- * my requirements so I decided to write the implementation on my own.
- */
-
#include "toltecs/microtiles.h"
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
namespace Toltecs {
-typedef struct _GemUta GemUta;
-typedef struct _GemRect GemRect;
-
-typedef uint32 GemUtaBBox;
-
-#define GEM_UTA_BBOX_CONS(x0, y0, x1, y1) (((x0) << 24) | ((y0) << 16) | \
- ((x1) << 8) | (y1))
-
-#define GEM_UTILE_EMPTY 0x00000000
-#define GEM_UTILE_FULL 0x01012020
-
-#define GEM_UTA_BBOX_X0(ub) ((ub) >> 24)
-#define GEM_UTA_BBOX_Y0(ub) (((ub) >> 16) & 0xff)
-#define GEM_UTA_BBOX_X1(ub) (((ub) >> 8) & 0xff)
-#define GEM_UTA_BBOX_Y1(ub) ((ub) & 0xff)
-
-#define GEM_UTILE_SHIFT 5
-#define GEM_UTILE_SIZE (1 << GEM_UTILE_SHIFT)
-
-#define GEM_MIN(a,b) ((a) < (b) ? (a) : (b))
-#define GEM_MAX(a,b) ((a) > (b) ? (a) : (b))
-
-struct _GemUta {
- int x;
- int y;
- int width; /* number of tiles in one line */
- int height; /* number of tiles in one row */
- GemUtaBBox *tiles;
-};
-
-struct _GemRect {
- int x0;
- int x1;
- int y0;
- int y1;
-};
-
-
-static GemUta * gem_uta_new (int x, int y, int width, int height);
-static GemUta * gem_uta_new_coords (int x, int y, int width, int height);
-static void gem_uta_free (GemUta *uta);
-static void gem_uta_union (GemUta *uta1, const GemUta *uta2);
-static void gem_uta_add_rect (GemUta *uta, const GemRect * rect);
-
-#define GEM_UTA_QUERY_CONTAIN 0
-#define GEM_UTA_QUERY_INTERSECT 1
-
-static int gem_uta_query_rect (const GemUta *uta, const GemRect * rect, int query);
-
-static Common::Rect * gem_uta_get_rects (const GemUta *uta, int * num_rects,
- int min_x, int min_y, int max_x, int max_y);
-
-/************** UTA IMPLEMENTATION **************/
-
-#define GEM_UTILE_UNION(b1, b2) \
- { \
- if (b1 == GEM_UTILE_FULL || b2 == GEM_UTILE_EMPTY) \
- { } \
- else if (b1 == GEM_UTILE_EMPTY || b2 == GEM_UTILE_FULL) \
- { b1 = b2; } \
- else { \
- b1 = GEM_UTA_BBOX_CONS ( \
- GEM_MIN(GEM_UTA_BBOX_X0(b1), \
- GEM_UTA_BBOX_X0(b2)), \
- GEM_MIN(GEM_UTA_BBOX_Y0(b1), \
- GEM_UTA_BBOX_Y0(b2)), \
- GEM_MAX(GEM_UTA_BBOX_X1(b1), \
- GEM_UTA_BBOX_X1(b2)), \
- GEM_MAX(GEM_UTA_BBOX_Y1(b1), \
- GEM_UTA_BBOX_Y1(b2))); \
- } \
- }
-
-static GemUta * gem_uta_new (int x, int y, int width, int height) {
- GemUta *uta;
-
- uta = (GemUta *) malloc (sizeof (GemUta));
- uta->x = x;
- uta->y = y;
- uta->width = width;
- uta->height = height;
-
- uta->tiles = (GemUtaBBox *)
- malloc (sizeof (GemUtaBBox) * width * height);
-
- memset (uta->tiles, 0, sizeof (GemUtaBBox) * width * height);
-
- return uta;
-}
-
-static GemUta * gem_uta_new_coords (int x, int y, int width, int height) {
- return gem_uta_new (x >> GEM_UTILE_SHIFT, y >> GEM_UTILE_SHIFT,
- (width >> GEM_UTILE_SHIFT) + 1,
- (height >> GEM_UTILE_SHIFT) + 1);
+MicroTileArray::MicroTileArray(int16 width, int16 height) {
+ _tilesW = (width / TileSize) + ((width % TileSize) > 0 ? 1 : 0);
+ _tilesH = (height / TileSize) + ((height % TileSize) > 0 ? 1 : 0);
+ _tiles = new BoundingBox[_tilesW * _tilesH];
+ clear();
}
-static void gem_uta_free (GemUta *uta) {
- if (uta) {
- if (uta->tiles)
- free (uta->tiles);
- free(uta);
- }
+MicroTileArray::~MicroTileArray() {
+ delete[] _tiles;
}
-static void gem_uta_union (GemUta *uta1, const GemUta *uta2) {
- int32 x0, y0, x1, y1;
- int x, y;
- GemUtaBBox *_b1;
- const GemUtaBBox *_b2;
-
- if (!uta1 || !uta2)
- return;
-
- x0 = GEM_MAX (uta1->x, uta2->x);
- y0 = GEM_MAX (uta2->y, uta2->y);
- x1 = GEM_MIN (uta1->x + uta1->width - 1,
- uta2->x + uta2->width - 1);
- y1 = GEM_MIN (uta1->y + uta1->height - 1,
- uta2->y + uta2->height - 1);
+void MicroTileArray::addRect(Common::Rect r) {
- if (x0 > x1 || y0 > y1)
- return;
+ int ux0, uy0, ux1, uy1;
+ int tx0, ty0, tx1, ty1;
+ int ix0, iy0, ix1, iy1;
- _b1 = & (uta1->tiles [(y0 - uta1->y) * uta1->width + (x0 - uta1->x)]);
- _b2 = & (uta2->tiles [(y0 - uta2->y) * uta2->width + (x0 - uta2->x)]);
+ r.clip(Common::Rect(0, 0, 639, 399));
- for (y = y0; y <= y1; ++y)
- {
- GemUtaBBox *b1 = _b1;
- const GemUtaBBox *b2 = _b2;
+ ux0 = r.left / TileSize;
+ uy0 = r.top / TileSize;
+ ux1 = r.right / TileSize;
+ uy1 = r.bottom / TileSize;
- for (x = x0; x <= x1; ++x)
- {
- GEM_UTILE_UNION (*b1, *b2);
+ tx0 = r.left % TileSize;
+ ty0 = r.top % TileSize;
+ tx1 = r.right % TileSize;
+ ty1 = r.bottom % TileSize;
- b1 ++;
- b2 ++;
+ for (int yc = uy0; yc <= uy1; yc++) {
+ for (int xc = ux0; xc <= ux1; xc++) {
+ ix0 = (xc == ux0) ? tx0 : 0;
+ ix1 = (xc == ux1) ? tx1 : TileSize - 1;
+ iy0 = (yc == uy0) ? ty0 : 0;
+ iy1 = (yc == uy1) ? ty1 : TileSize - 1;
+ updateBoundingBox(_tiles[xc + yc * _tilesW], ix0, iy0, ix1, iy1);
}
- _b1 += uta1->width;
- _b2 += uta2->width;
}
-}
-
-/*
- * Add a rectangle to the microtile array.
- * The coordinates of the rectangle are considered absolute.
- */
-static void gem_uta_add_rect (GemUta *uta, const GemRect * _rect) {
- int xf0, xf1, yf0, yf1;
- int width, height;
- int x0, y0, x1, y1;
- int x, y;
- GemUtaBBox *_b;
- GemUtaBBox *b;
- GemUtaBBox bbox;
- GemRect rect;
-
- if (!uta || !_rect)
- return;
-
- rect = *_rect;
-
- rect.x0 -= uta->x << GEM_UTILE_SHIFT;
- rect.y0 -= uta->y << GEM_UTILE_SHIFT;
- rect.x1 -= uta->x << GEM_UTILE_SHIFT;
- rect.y1 -= uta->y << GEM_UTILE_SHIFT;
-
- if (rect.x0 < 0)
- rect.x0 = 0;
- if (rect.y0 < 0)
- rect.y0 = 0;
- if (rect.x1 > (uta->width << GEM_UTILE_SHIFT))
- rect.x1 = (uta->width << GEM_UTILE_SHIFT);
- if (rect.y1 > (uta->height << GEM_UTILE_SHIFT))
- rect.y1 = (uta->height << GEM_UTILE_SHIFT);
-
- if (rect.x0 > rect.x1 || rect.y0 > rect.y1)
- return;
-
- width = ((rect.x1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT)
- - (rect.x0 >> GEM_UTILE_SHIFT);
- height = ((rect.y1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT)
- - (rect.y0 >> GEM_UTILE_SHIFT);
-
- xf0 = rect.x0 % (GEM_UTILE_SIZE);
- yf0 = rect.y0 % (GEM_UTILE_SIZE);
- xf1 = rect.x1 % (GEM_UTILE_SIZE);
- yf1 = rect.y1 % (GEM_UTILE_SIZE);
-
- x0 = rect.x0 >> GEM_UTILE_SHIFT;
- y0 = rect.y0 >> GEM_UTILE_SHIFT;
- x1 = rect.x1 >> GEM_UTILE_SHIFT;
- y1 = rect.y1 >> GEM_UTILE_SHIFT;
-
- _b = & (uta->tiles [(y0 * uta->width) + x0]);
-
- if (width == 1 && height == 1) {
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, yf1 + 1);
- GEM_UTILE_UNION (*_b, bbox);
- return;
- }
- if (width == 1) {
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1,
- GEM_UTILE_SIZE);
- GEM_UTILE_UNION (*_b, bbox);
- _b += uta->width;
- if (height > 2) {
- for (y = y0 + 1; y <= (y1 - 1); ++y) {
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, GEM_UTILE_SIZE);
- GEM_UTILE_UNION (*_b, bbox);
- _b += uta->width;
- }
- }
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, yf1 + 1);
- GEM_UTILE_UNION (*_b, bbox);
- return;
- } else if (height == 1) {
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, yf1 + 1);
- GEM_UTILE_UNION (*_b, bbox);
- ++_b;
- if (width > 2) {
- for (x = x0 + 1; x <= (x1 - 1); ++x) {
- bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, xf1 + 1);
- GEM_UTILE_UNION (*_b, bbox);
- ++_b;
- }
- }
- bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, yf1 + 1);
- GEM_UTILE_UNION (*_b, bbox);
- return;
- }
-
- b = _b;
-
- /* top-left corner */
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
- GEM_UTILE_UNION (*b, bbox);
- ++b;
-
- /* top edge */
- if (width > 2) {
- for (x = x0 + 1; x <= (x1 - 1); ++x) {
- bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
- GEM_UTILE_UNION (*b, bbox);
- ++b;
- }
- }
-
- /* top-right corner */
- bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE);
- GEM_UTILE_UNION (*b, bbox);
-
- _b += uta->width;
-
- /* left edge, content, right edge */
- if (height > 2) {
- for (y = y0 + 1; y <= (y1 - 1); ++y) {
- b = _b;
-
- /* left edge */
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
- GEM_UTILE_UNION (*b, bbox);
- ++b;
-
- /* content */
- if (width > 2) {
- for (x = x0 + 1; x <= (x1 - 1); ++x) {
- *b = GEM_UTILE_FULL;
- ++b;
- }
- }
-
- /* right edge */
- bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, GEM_UTILE_SIZE);
- GEM_UTILE_UNION (*b, bbox);
-
- _b += uta->width;
- }
- }
+}
- b = _b;
-
- /* bottom-left corner */
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, yf1 + 1);
- GEM_UTILE_UNION (*b, bbox);
- ++b;
-
- /* bottom edge */
- if (width > 2) {
- for (x = x0 + 1; x <= (x1 - 1); ++x) {
- bbox = GEM_UTA_BBOX_CONS (1, 1, GEM_UTILE_SIZE, yf1 + 1);
- GEM_UTILE_UNION (*b, bbox);
- ++b;
- }
- }
-
- /* bottom-left corner */
- bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, yf1 + 1);
- GEM_UTILE_UNION (*b, bbox);
+void MicroTileArray::clear() {
+ memset(_tiles, 0, _tilesW * _tilesH * sizeof(BoundingBox));
+}
- /* done. */
+byte MicroTileArray::TileX0(const BoundingBox &boundingBox) {
+ return (boundingBox >> 24) & 0xFF;
}
-#define GEM_UTILE_CONTAINS(b1, b2) \
- ( !(GEM_UTA_BBOX_X0 (b1) > GEM_UTA_BBOX_X0 (b2) || \
- GEM_UTA_BBOX_Y0 (b1) > GEM_UTA_BBOX_Y0 (b2) || \
- GEM_UTA_BBOX_X1 (b1) < GEM_UTA_BBOX_X1 (b2) || \
- GEM_UTA_BBOX_Y1 (b1) < GEM_UTA_BBOX_Y1 (b2)) )
+byte MicroTileArray::TileY0(const BoundingBox &boundingBox) {
+ return (boundingBox >> 16) & 0xFF;
+}
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
+byte MicroTileArray::TileX1(const BoundingBox &boundingBox) {
+ return (boundingBox >> 8) & 0xFF;
+}
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
+byte MicroTileArray::TileY1(const BoundingBox &boundingBox) {
+ return boundingBox & 0xFF;
+}
-static inline int gem_utile_intersects (GemUtaBBox b1, GemUtaBBox b2) {
- GemUtaBBox b3;
- b3 = GEM_UTA_BBOX_CONS (
- MAX (GEM_UTA_BBOX_X0 (b1), GEM_UTA_BBOX_X0 (b2)),
- MAX (GEM_UTA_BBOX_Y0 (b1), GEM_UTA_BBOX_Y0 (b2)),
- MIN (GEM_UTA_BBOX_X1 (b1), GEM_UTA_BBOX_X1 (b2)),
- MIN (GEM_UTA_BBOX_Y1 (b1), GEM_UTA_BBOX_Y1 (b2))
- );
- return (GEM_UTA_BBOX_X0 (b3) <= GEM_UTA_BBOX_X1 (b3) &&
- GEM_UTA_BBOX_Y0 (b3) <= GEM_UTA_BBOX_Y1 (b3));
+bool MicroTileArray::isBoundingBoxEmpty(const BoundingBox &boundingBox) {
+ return boundingBox == EmptyBoundingBox;
}
-#define GEM_UTILE_INTERSECTS(b1, b2) \
- gem_utile_intersects (b1, b2)
-/*
- * Return if the uta contains the rectangle.
- */
+bool MicroTileArray::isBoundingBoxFull(const BoundingBox &boundingBox) {
+ return boundingBox == FullBoundingBox;
+}
-static int gem_uta_query_rect (const GemUta *uta, const GemRect * _rect, int query) {
- int xf0, xf1, yf0, yf1;
- int width, height;
- int x0, y0, x1, y1;
- int x, y;
- GemUtaBBox *_b;
- GemUtaBBox *b;
- GemUtaBBox bbox;
- GemRect rect;
-
- if (!uta || !_rect)
- return 0;
-
- rect = *_rect;
-
- rect.x0 -= uta->x << GEM_UTILE_SHIFT;
- rect.y0 -= uta->y << GEM_UTILE_SHIFT;
- rect.x1 -= uta->x << GEM_UTILE_SHIFT;
- rect.y1 -= uta->y << GEM_UTILE_SHIFT;
-
- if (rect.x0 < 0)
- rect.x0 = 0;
- if (rect.y0 < 0)
- rect.y0 = 0;
- if (rect.x1 > (uta->width << GEM_UTILE_SHIFT))
- rect.x1 = (uta->width << GEM_UTILE_SHIFT);
- if (rect.y1 > (uta->height << GEM_UTILE_SHIFT))
- rect.y1 = (uta->height << GEM_UTILE_SHIFT);
-
- if (rect.x0 > rect.x1 || rect.y0 > rect.y1)
- return 0;
-
- width = ((rect.x1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT)
- - (rect.x0 >> GEM_UTILE_SHIFT);
- height = ((rect.y1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT)
- - (rect.y0 >> GEM_UTILE_SHIFT);
-
- xf0 = rect.x0 % (GEM_UTILE_SIZE);
- yf0 = rect.y0 % (GEM_UTILE_SIZE);
- xf1 = rect.x1 % (GEM_UTILE_SIZE);
- yf1 = rect.y1 % (GEM_UTILE_SIZE);
-
- x0 = rect.x0 >> GEM_UTILE_SHIFT;
- y0 = rect.y0 >> GEM_UTILE_SHIFT;
- x1 = rect.x1 >> GEM_UTILE_SHIFT;
- y1 = rect.y1 >> GEM_UTILE_SHIFT;
-
- _b = & (uta->tiles [(y0 * uta->width) + x0]);
-
- if (width == 1 && height == 1) {
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, yf1 + 1);
- if (query == GEM_UTA_QUERY_INTERSECT &&
- GEM_UTILE_INTERSECTS (*_b, bbox))
- return 1;
- else if (query == GEM_UTA_QUERY_CONTAIN &&
- GEM_UTILE_CONTAINS (*_b, bbox))
- return 1;
- return 0;
-
- }
-#define CHECK(b1,b2) \
- { \
- if (query == GEM_UTA_QUERY_INTERSECT && \
- GEM_UTILE_INTERSECTS (b1, b2)) \
- return 1; \
- else if (query == GEM_UTA_QUERY_CONTAIN && \
- !(GEM_UTILE_CONTAINS (b1, b2))) \
- return 0; \
- }
- if (width == 1) {
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE);
- CHECK (*_b, bbox);
- _b += uta->width;
- if (height > 2) {
- for (y = y0 + 1; y <= (y1 - 1); ++y) {
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, GEM_UTILE_SIZE);
- CHECK (*_b, bbox);
- _b += uta->width;
- }
- }
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, yf1 + 1);
- CHECK (*_b, bbox);
- if (query == GEM_UTA_QUERY_INTERSECT)
- return 0;
- else if (query == GEM_UTA_QUERY_CONTAIN)
- return 1;
- } else if (height == 1) {
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, yf1 + 1);
- CHECK (*_b, bbox);
- ++_b;
- if (width > 2) {
- for (x = x0 + 1; x <= (x1 - 1); ++x) {
- bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, xf1 + 1);
- CHECK (*_b, bbox);
- ++_b;
- }
- }
- bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, yf1 + 1);
- CHECK (*_b, bbox);
- if (query == GEM_UTA_QUERY_INTERSECT)
- return 0;
- else if (query == GEM_UTA_QUERY_CONTAIN)
- return 1;
- }
-
- b = _b;
-
- /* top-left corner */
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
- CHECK (*b, bbox);
- ++b;
-
- /* top edge */
- if (width > 2) {
- for (x = x0 + 1; x <= (x1 - 1); ++x) {
- bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
- CHECK (*b, bbox);
- ++b;
- }
- }
-
- /* top-right corner */
- bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE);
- CHECK (*b, bbox);
-
- _b += uta->width;
-
- /* left edge, content, right edge */
- if (height > 2) {
- for (y = y0 + 1; y <= (y1 - 1); ++y) {
- b = _b;
-
- /* left edge */
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE);
- CHECK (*b, bbox);
- ++b;
-
- /* content */
- if (width > 2) {
- for (x = x0 + 1; x <= (x1 - 1); ++x) {
- CHECK (*b, GEM_UTILE_FULL);
- ++b;
- }
- }
-
- /* right edge */
- bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, GEM_UTILE_SIZE);
- CHECK (*b, bbox);
-
- _b += uta->width;
- }
- }
+void MicroTileArray::setBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1) {
+ boundingBox = (x0 << 24) | (y0 << 16) | (x1 << 8) | y1;
+}
- b = _b;
-
- /* bottom-left corner */
- bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, yf1 + 1);
- CHECK (*b, bbox);
- ++b;
-
- /* bottom edge */
- if (width > 2) {
- for (x = x0 + 1; x <= (x1 - 1); ++x) {
- bbox = GEM_UTA_BBOX_CONS (1, 1, GEM_UTILE_SIZE, yf1 + 1);
- CHECK (*b, bbox);
- ++b;
- }
+void MicroTileArray::updateBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1) {
+ if (!isBoundingBoxEmpty(boundingBox)) {
+ x0 = MIN(TileX0(boundingBox), x0);
+ y0 = MIN(TileY0(boundingBox), y0);
+ x1 = MAX(TileX1(boundingBox), x1);
+ y1 = MAX(TileY1(boundingBox), y1);
}
-
- /* bottom-left corner */
- bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, yf1 + 1);
- CHECK (*b, bbox);
-
-#undef CHECK
-
- /* done. */
- if (query == GEM_UTA_QUERY_CONTAIN)
- return 1;
- return 0;
+ setBoundingBox(boundingBox, x0, y0, x1, y1);
}
+Common::Rect * MicroTileArray::getRectangles(int *num_rects, int min_x, int min_y, int max_x, int max_y) {
-#undef CLAMP
-#define CLAMP(a,min,max) (a = (a < min ? min : (a > max ? max : a)))
-
-static Common::Rect * gem_uta_get_rects (const GemUta *uta, int * num_rects,
- int min_x, int min_y, int max_x, int max_y) {
-
-#if 1
-
+ Common::Rect *rects = new Common::Rect[_tilesW * _tilesH];
- GemRect *rects = new GemRect[uta->width * uta->height];
- Common::Rect *result = NULL;
int n_rects = 0;
int x, y;
int x0, y0, x1, y1;
+ int i = 0;
+
+ for (y = 0; y < _tilesH; ++y) {
+ for (x = 0; x < _tilesW; ++x) {
- int *glom = new int[uta->width * uta->height];
- int i; /* current */
-
- for (i = 0; i < uta->width * uta->height; ++i)
- glom [i] = -1;
-
- i = 0;
-
- for (y = 0; y < uta->height; ++y) {
- for (x = 0; x < uta->width; ++x) {
-#define TILE uta->tiles [i]
int start;
int finish = 0;
- GemUtaBBox b;
+ BoundingBox boundingBox;
+
+ boundingBox = _tiles[i];
+
+ if (isBoundingBoxEmpty(boundingBox))
+ goto next;
- b = uta->tiles [i];
+ x0 = (x * TileSize) + TileX0(boundingBox);
+ y0 = (y * TileSize) + TileY0(boundingBox);
+ y1 = (y * TileSize) + TileY1(boundingBox);
- if (TILE == GEM_UTILE_EMPTY)
- goto next;
+ x0 = CLIP (x0, min_x, max_x);
+ y0 = CLIP (y0, min_y, max_y);
+ y1 = CLIP (y1, min_y, max_y);
- x0 = ((uta->x + x) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_X0 (TILE) - 1;
- y0 = ((uta->y + y) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_Y0 (TILE) - 1;
- y1 = ((uta->y + y) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_Y1 (TILE) - 1;
-
- CLAMP (x0, min_x, max_x);
- CLAMP (y0, min_y, max_y);
- CLAMP (y1, min_y, max_y);
-
+#if 1
start = i;
-
- if (GEM_UTA_BBOX_X1 (TILE) != GEM_UTILE_SIZE || x == uta->width - 1) {
+
+ if (TileX1(boundingBox) != TileSize - 1 || x == _tilesW - 1) {
/* the tile does not continue */
goto done;
}
-
+
while (!finish) {
++x;
++i;
-
- if (x == uta->width ||
- GEM_UTA_BBOX_Y0 (TILE) != GEM_UTA_BBOX_Y0 (b) ||
- GEM_UTA_BBOX_Y1 (TILE) != GEM_UTA_BBOX_Y1 (b) ||
- GEM_UTA_BBOX_X0 (TILE) != 1)
+
+ if (x == _tilesW || i >= _tilesW * _tilesH ||
+ TileY0(_tiles[i]) != TileY0(boundingBox) ||
+ TileY1(_tiles[i]) != TileY1(boundingBox) ||
+ TileX0(_tiles[i]) != 0)
{
--x;
--i;
@@ -617,181 +138,56 @@ static Common::Rect * gem_uta_get_rects (const GemUta *uta, int * num_rects,
}
done:
- x1 = ((uta->x + x) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_X1 (TILE) - 1;
-
- CLAMP (x1, min_x, max_x);
-
- if (glom [start] != -1 && /* try to glom */
- rects [glom [start]].x0 == x0 &&
- rects [glom [start]].x1 == x1 &&
- rects [glom [start]].y1 == y0 - 1)
+#endif
+ x1 = (x * TileSize) + TileX1(_tiles[i]);
+
+ x1 = CLIP (x1, min_x, max_x);
+
+ #if 1
+
+ rects[n_rects].left = x0;
+ rects[n_rects].top = y0;
+ rects[n_rects].right = x1 + 1;
+ rects[n_rects].bottom = y1 + 1;
+ n_rects++;
+ fflush(stdout);
+
+ #else
+
+ if (glom [start] != -1 && /* try to glom */
+ rects [glom [start]].left == x0 &&
+ rects [glom [start]].right == x1 &&
+ rects [glom [start]].bottom == y0 - 1)
{
- rects [glom [start]].y1 = y1;
- if (y != uta->height - 1) {
- glom [start + uta->width] = glom [start];
+ rects [glom [start]].bottom = y1;
+ if (y != tilesH - 1) {
+ glom [start + tilesW] = glom [start];
}
} else {
- rects [n_rects].x0 = x0;
- rects [n_rects].y0 = y0;
- rects [n_rects].x1 = x1;
- rects [n_rects].y1 = y1;
- if (y != uta->height - 1) {
- glom [start + uta->width] = n_rects;
+ rects[n_rects].left = x0;
+ rects[n_rects].top = y0;
+ rects[n_rects].right = x1;
+ rects[n_rects].bottom = y1;
+ if (y != tilesH - 1) {
+ glom [start + tilesW] = n_rects;
}
n_rects ++;
}
+
+ #endif
+
next:
++i;
-#undef TILE
+
}
}
-
- result = new Common::Rect[n_rects];
-
- for (i = 0; i < n_rects; ++i) {
- result[i].left = rects [i].x0;
- result[i].top = rects [i].y0;
- result[i].right = rects[i].x1; // CHECK
- result[i].bottom = rects[i].y1; // CHECK
- }
*num_rects = n_rects;
-
- delete rects;
- delete glom;
-
- return result;
-
-#else
- return NULL;
-#endif
-
-}
-MicroTileArray::MicroTileArray()
- : m_uta (NULL)
-{
-}
+ //delete glom;
-MicroTileArray::MicroTileArray(int x, int y, int w, int h)
- : m_x (x), m_y (y), m_w (w), m_h (h)
-{
- m_uta = gem_uta_new_coords (x, y, w, h);
- if (!m_uta)
- error("MicroTileArray::MicroTileArray() Out of memory");
-}
+ return rects;
-MicroTileArray::~MicroTileArray() {
- if (m_uta)
- gem_uta_free (m_uta);
}
-void MicroTileArray::clear() {
- if (!m_uta)
- return;
-
- memset (m_uta->tiles, 0, m_uta->width * m_uta->height * sizeof(GemUtaBBox));
-}
-
-void MicroTileArray::init(int x, int y, int w, int h) {
- if (m_uta)
- gem_uta_free (m_uta);
- m_uta = gem_uta_new_coords (x, y, w, h);
- m_x = x;
- m_y = y;
- m_w = w;
- m_h = h;
- if (!m_uta)
- error("Out of memory");
-}
-
-int MicroTileArray::getRectangles(Common::Rect * & rects, int min_x, int max_x, int min_y, int max_y) const {
- if (!m_uta)
- return 0;
-
- int n_rects;
-
- rects = gem_uta_get_rects (m_uta, &n_rects, min_x, max_x, min_y, max_y);
-
- return n_rects;
-}
-
-int MicroTileArray::getRectangles(Common::Rect * & rects) const {
- if (!m_uta)
- return 0;
-
- int n_rects;
-
- rects = gem_uta_get_rects (m_uta, &n_rects,
- m_x, m_y, m_x + m_w - 1, m_y + m_h - 1);
-
- return n_rects;
-}
-
-bool MicroTileArray::contains(const Common::Rect & rect) const {
- if (!m_uta)
- return false;
-
- GemRect r;
- r.x0 = rect.left;
- r.y0 = rect.top;
- r.x1 = rect.right; // CHECK
- r.y1 = rect.bottom; // CHECK
-
- return gem_uta_query_rect (m_uta, &r, GEM_UTA_QUERY_CONTAIN);
-}
-
-bool MicroTileArray::intersects(const Common::Rect & rect) const {
- if (!m_uta)
- return false;
-
- GemRect r;
- r.x0 = rect.left;
- r.y0 = rect.top;
- r.x1 = rect.right; // CHECK
- r.y1 = rect.bottom; // CHECK
-
- return gem_uta_query_rect (m_uta, &r, GEM_UTA_QUERY_INTERSECT);
-}
-
-void MicroTileArray::unite(const Common::Rect & rect) {
- if (!m_uta || rect.width() == 0 || rect.height() == 0)
- return;
-
- GemRect r;
- r.x0 = rect.left;
- r.y0 = rect.top;
- r.x1 = rect.right; // CHECK
- r.y1 = rect.bottom; // CHECK
-
- gem_uta_add_rect (m_uta, &r);
-}
-
-MicroTileArray & MicroTileArray::operator += (const Common::Rect & rect) {
- if (!m_uta || rect.width() == 0 || rect.height() == 0)
- return *this;
-
- GemRect r;
- r.x0 = rect.left;
- r.y0 = rect.top;
- r.x1 = rect.right; // CHECK
- r.y1 = rect.bottom; // CHECK
-
- gem_uta_add_rect (m_uta, &r);
-
- return *this;
-}
-
-void MicroTileArray::unite (const MicroTileArray & uta) {
- if (m_uta)
- gem_uta_union (m_uta, uta.m_uta);
-}
-
-MicroTileArray & MicroTileArray::operator += (const MicroTileArray & uta) {
- if (m_uta)
- gem_uta_union (m_uta, uta.m_uta);
- return *this;
-}
-
-} // namespace Toltecs
-
+} // End of namespace Toltecs
diff --git a/engines/toltecs/microtiles.h b/engines/toltecs/microtiles.h
index 21dd5a9..2135add 100644
--- a/engines/toltecs/microtiles.h
+++ b/engines/toltecs/microtiles.h
@@ -1,105 +1,38 @@
-/*
- SEL - Simple DirectMedia Layer Extension Library
- Copyright (C) 2002 Matej Knopp <knopp at users.sf.net>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
#ifndef TOLTECS_MICROTILES_H
#define TOLTECS_MICROTILES_H
+#include "common/scummsys.h"
+#include "common/util.h"
#include "common/rect.h"
namespace Toltecs {
-//! Class that represents a microtile array.
-/*!
- Microtile array is an efficient method of representing regions that
- need to be redrawn. For more information about the microtile arrays
- in general visit the LibArt homepage at
- http://www.levien.com/libart/uta.html .
-
- Note that this implementation is not the one of LibArt and
- differs from it.
- */
-class MicroTileArray {
-public:
- //! Create an empty unitialized uta.
- /*
- \note You must initialize the class using
- Uta::init() before doing anything with it.
- */
- MicroTileArray();
+typedef uint32 BoundingBox;
- //! Create a new microtile array with given coordinates.
- MicroTileArray(int x, int y, int w, int h);
+const BoundingBox FullBoundingBox = 0x00001F1F;
+const BoundingBox EmptyBoundingBox = 0x00000000;
+const int TileSize = 32;
- //! Destroy the microtile array.
+class MicroTileArray {
+public:
+ MicroTileArray(int16 width, int16 height);
~MicroTileArray();
-
- //! Clear the microtile array.
+ void addRect(Common::Rect r);
void clear();
-
- //! Initialize the array.
- /*
- You can use this funtion to resize the array as well,
- but you should be aware that the content of the array
- will be cleared.
- */
- void init(int x, int y, int w, int h);
-
- //! Return the microtile array as rectangles.
- /*!
- The \a rects array should be freed when no longer needed.
- \return The number of rectangles in \a rects.
- */
- int getRectangles(Common::Rect * & rects,
- int min_x, int max_x, int min_y, int max_y) const;
-
- //! Return the microtile array as rectangles.
- /*!
- The \a rects array should be freed when no longer needed.
- \return The number of rectangles in \a rects.
- */
- int getRectangles(Common::Rect * & rects) const;
-
- //! Whether the microtile array contains given rectangle.
- bool contains(const Common::Rect &) const;
-
- //! Whether the microtile array intersects given rectangle.
- bool intersects(const Common::Rect &) const;
-
- //! Unite the microtile array with a rectangle.
- void unite(const Common::Rect &);
-
- //! Unite the microtile array with a rectangle.
- MicroTileArray & operator+=(const Common::Rect &);
-
- //! Unite the array with another microtile array.
- void unite(const MicroTileArray &);
-
- //! Unite the array with another microtile array.
- MicroTileArray & operator+=(const MicroTileArray &);
-
-protected:
- typedef struct _GemUta GemUta;
- GemUta *m_uta;
- int m_x, m_y, m_w, m_h;
-}; // class Uta
+ Common::Rect *getRectangles(int *num_rects, int min_x, int min_y, int max_x, int max_y);
+protected:
+ BoundingBox *_tiles;
+ int16 _tilesW, _tilesH;
+ byte TileX0(const BoundingBox &boundingBox);
+ byte TileY0(const BoundingBox &boundingBox);
+ byte TileX1(const BoundingBox &boundingBox);
+ byte TileY1(const BoundingBox &boundingBox);
+ bool isBoundingBoxEmpty(const BoundingBox &boundingBox);
+ bool isBoundingBoxFull(const BoundingBox &boundingBox);
+ void setBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1);
+ void updateBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1);
+};
} // namespace Toltecs
-
#endif // TOLTECS_MICROTILES_H
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
index 3cf8855..49d4e19 100644
--- a/engines/toltecs/module.mk
+++ b/engines/toltecs/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS = \
movie.o \
palette.o \
toltecs.o \
+ render.o \
resource.o \
saveload.o \
screen.o \
diff --git a/engines/toltecs/render.cpp b/engines/toltecs/render.cpp
new file mode 100644
index 0000000..dd7dfc2
--- /dev/null
+++ b/engines/toltecs/render.cpp
@@ -0,0 +1,320 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/render.h"
+#include "toltecs/resource.h"
+
+namespace Toltecs {
+
+Common::Rect makeRect(int16 x, int16 y, int16 width, int16 height) {
+ Common::Rect rect;
+ rect.left = x;
+ rect.top = y;
+ rect.setWidth(width);
+ rect.setHeight(height);
+ return rect;
+}
+
+RenderQueue::RenderQueue(ToltecsEngine *vm) : _vm(vm) {
+ _currQueue = new RenderQueueArray();
+ _prevQueue = new RenderQueueArray();
+ _updateUta = new MicroTileArray(640, 400);
+}
+
+RenderQueue::~RenderQueue() {
+ delete _currQueue;
+ delete _prevQueue;
+ delete _updateUta;
+}
+
+void RenderQueue::addSprite(SpriteDrawItem &sprite) {
+
+ RenderQueueItem item;
+ item.type = kSprite;
+ item.flags = kRefresh;
+ item.rect = makeRect(sprite.x - _vm->_cameraX, sprite.y - _vm->_cameraY, sprite.width, sprite.height);
+ item.priority = sprite.priority;
+
+ item.sprite = sprite;
+ item.sprite.x -= _vm->_cameraX;
+ item.sprite.y -= _vm->_cameraY;
+
+ // Add sprite sorted by priority
+ RenderQueueArray::iterator iter = _currQueue->begin();
+ while (iter != _currQueue->end() && (*iter).priority <= item.priority) {
+ iter++;
+ }
+ _currQueue->insert(iter, item);
+
+}
+
+void RenderQueue::addText(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len) {
+
+ Font font(_vm->_res->load(fontResIndex));
+
+ RenderQueueItem item;
+ item.type = kText;
+ item.flags = kRefresh;
+ item.rect = makeRect(x, y, font.getTextWidth(text), font.getHeight());
+ item.priority = 1000;
+
+ item.text.color = color;
+ item.text.fontResIndex = fontResIndex;
+ item.text.text = text;
+ item.text.len = len;
+
+ _currQueue->push_back(item);
+
+}
+
+void RenderQueue::addMask(SegmapMaskRect &mask) {
+
+ RenderQueueItem item;
+ item.type = kMask;
+ item.flags = kRefresh;
+ item.rect = makeRect(mask.x - _vm->_cameraX, mask.y - _vm->_cameraY, mask.width, mask.height);
+ item.priority = mask.priority;
+
+ item.mask = mask;
+
+ // Only add the mask if a sprite intersects its rect
+ if (rectIntersectsItem(item.rect)) {
+ RenderQueueArray::iterator iter = _currQueue->begin();
+ while (iter != _currQueue->end() && (*iter).priority <= item.priority) {
+ iter++;
+ }
+ _currQueue->insert(iter, item);
+ }
+
+}
+
+void RenderQueue::update() {
+
+ bool doFullRefresh = _vm->_screen->_fullRefresh;
+
+ _updateUta->clear();
+
+ if (!doFullRefresh) {
+
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ RenderQueueItem *item = &(*iter);
+ RenderQueueItem *prevItem = findItemInQueue(_prevQueue, *item);
+ if (prevItem) {
+ if (hasItemChanged(*prevItem, *item)) {
+ item->flags = kRefresh;
+ addDirtyRect(prevItem->rect);
+ } else {
+ item->flags = kUnchanged;
+ }
+ } else {
+ item->flags = kRefresh;
+ }
+ }
+
+ for (RenderQueueArray::iterator iter = _prevQueue->begin(); iter != _prevQueue->end(); iter++) {
+ RenderQueueItem *prevItem = &(*iter);
+ RenderQueueItem *item = findItemInQueue(_currQueue, *prevItem);
+ if (!item) {
+ prevItem->flags = kRemoved;
+ addDirtyRect(prevItem->rect);
+ }
+ }
+
+ restoreDirtyBackground();
+
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ RenderQueueItem *item = &(*iter);
+ if (item->flags != kUnchanged)
+ invalidateItemsByRect(item->rect, item);
+ }
+
+ } else {
+ byte *destp = _vm->_screen->_frontScreen;
+ byte *srcp = _vm->_screen->_backScreen + _vm->_cameraX + _vm->_cameraY * _vm->_sceneWidth;
+ int16 w = MIN<int16>(640, _vm->_sceneWidth);
+ int16 h = MIN<int16>(400, _vm->_cameraHeight);
+ while (h--) {
+ memcpy(destp, srcp, w);
+ destp += 640;
+ srcp += _vm->_sceneWidth;
+ }
+ _vm->_screen->_fullRefresh = false;
+ }
+
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ const RenderQueueItem *item = &(*iter);
+
+ if (item->flags == kRefresh) {
+
+ switch (item->type) {
+ case kSprite:
+ _vm->_screen->drawSprite(item->sprite);
+ break;
+ case kText:
+ _vm->_screen->drawString(item->rect.left, item->rect.top, item->text.color, item->text.fontResIndex,
+ item->text.text, item->text.len, NULL, true);
+ break;
+ case kMask:
+ _vm->_screen->drawSurface(item->rect.left, item->rect.top, item->mask.surface);
+ break;
+ default:
+ break;
+ }
+
+ if (!doFullRefresh)
+ addDirtyRect(item->rect);
+
+ }
+
+ }
+
+ if (doFullRefresh) {
+ clear();
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, _vm->_cameraHeight);
+ } else {
+ updateDirtyRects();
+ }
+
+ SWAP(_currQueue, _prevQueue);
+ _currQueue->clear();
+
+}
+
+void RenderQueue::clear() {
+ _prevQueue->clear();
+ _currQueue->clear();
+}
+
+bool RenderQueue::rectIntersectsItem(const Common::Rect &rect) {
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ const RenderQueueItem *item = &(*iter);
+ if (rect.intersects(item->rect))
+ return true;
+ }
+ return false;
+}
+
+RenderQueueItem *RenderQueue::findItemInQueue(RenderQueueArray *queue, const RenderQueueItem &item) {
+ /* This checks if the given item also exists in the previously drawn frame.
+ The state of the item (position, color etc) is handled elsewhere.
+ */
+ for (RenderQueueArray::iterator iter = queue->begin(); iter != queue->end(); iter++) {
+ RenderQueueItem *prevItem = &(*iter);
+ if (prevItem->type == item.type) {
+ switch (item.type) {
+ case kSprite:
+ if (prevItem->sprite.resIndex == item.sprite.resIndex &&
+ prevItem->sprite.frameNum == item.sprite.frameNum)
+ return prevItem;
+ break;
+ case kText:
+ if (prevItem->text.text == item.text.text &&
+ prevItem->text.len == item.text.len)
+ return prevItem;
+ break;
+ case kMask:
+ if (prevItem->mask.surface == item.mask.surface)
+ return prevItem;
+ break;
+ }
+ }
+ }
+ return NULL; // Not found
+}
+
+bool RenderQueue::hasItemChanged(const RenderQueueItem &item1, const RenderQueueItem &item2) {
+
+ // TODO: Clean up.
+
+ if (item1.type != item1.type)
+ return true;
+
+ if (item1.rect.left != item2.rect.left ||
+ item1.rect.top != item2.rect.top ||
+ item1.rect.right != item2.rect.right ||
+ item1.rect.bottom != item2.rect.bottom)
+ return true;
+
+ if (item1.type == kText && item1.text.color != item2.text.color)
+ return true;
+
+ return false;
+}
+
+void RenderQueue::invalidateItemsByRect(const Common::Rect &rect, const RenderQueueItem *item) {
+ for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
+ RenderQueueItem *subItem = &(*iter);
+ if (item != subItem &&
+ subItem->flags == kUnchanged &&
+ rect.intersects(subItem->rect)) {
+
+ subItem->flags = kRefresh;
+ invalidateItemsByRect(subItem->rect, subItem);
+ }
+ }
+}
+
+void RenderQueue::addDirtyRect(const Common::Rect &rect) {
+ _updateUta->addRect(rect);
+}
+
+void RenderQueue::restoreDirtyBackground() {
+ int n_rects = 0;
+ Common::Rect *rects = _updateUta->getRectangles(&n_rects, 0, 0, 639, _vm->_cameraHeight - 1);
+ for (int i = 0; i < n_rects; i++) {
+ byte *destp = _vm->_screen->_frontScreen + rects[i].left + rects[i].top * 640;
+ byte *srcp = _vm->_screen->_backScreen + (_vm->_cameraX + rects[i].left) + (_vm->_cameraY + rects[i].top) * _vm->_sceneWidth;
+ int16 w = rects[i].width();
+ int16 h = rects[i].height();
+ while (h--) {
+ memcpy(destp, srcp, w);
+ destp += 640;
+ srcp += _vm->_sceneWidth;
+ }
+ invalidateItemsByRect(rects[i], NULL);
+ }
+ delete[] rects;
+}
+
+void RenderQueue::updateDirtyRects() {
+ int n_rects = 0;
+ Common::Rect *rects = _updateUta->getRectangles(&n_rects, 0, 0, 639, _vm->_cameraHeight - 1);
+ for (int i = 0; i < n_rects; i++) {
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen + rects[i].left + rects[i].top * 640,
+ 640, rects[i].left, rects[i].top, rects[i].width(), rects[i].height());
+ }
+ delete[] rects;
+}
+
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/render.h b/engines/toltecs/render.h
new file mode 100644
index 0000000..0f5554b
--- /dev/null
+++ b/engines/toltecs/render.h
@@ -0,0 +1,119 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_RENDER_H
+#define TOLTECS_RENDER_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/list.h"
+#include "common/array.h"
+#include "common/rect.h"
+
+#include "graphics/surface.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+#include "toltecs/segmap.h"
+#include "toltecs/screen.h"
+#include "toltecs/microtiles.h"
+
+namespace Toltecs {
+
+enum RenderType {
+ kSprite,
+ kText,
+ kMask
+};
+
+enum RenderFlags {
+ kNone = 1 << 0,
+ kRefresh = 1 << 1,
+ kRemoved = 1 << 2,
+ kMoved = 1 << 3,
+ kUnchanged = 1 << 4
+};
+
+struct RenderTextItem {
+ byte color;
+ uint fontResIndex;
+ byte *text;
+ int len;
+};
+
+struct RenderQueueItem {
+ RenderType type;
+ uint flags;
+ Common::Rect rect;
+ int16 priority;
+ union {
+ SpriteDrawItem sprite;
+ RenderTextItem text;
+ SegmapMaskRect mask;
+ };
+};
+
+class RenderQueue {
+public:
+ RenderQueue(ToltecsEngine *vm);
+ ~RenderQueue();
+
+ void addSprite(SpriteDrawItem &sprite);
+ void addText(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len);
+ void addMask(SegmapMaskRect &mask);
+ void update();
+ void clear();
+
+protected:
+ typedef Common::List<RenderQueueItem> RenderQueueArray;
+
+ ToltecsEngine *_vm;
+ RenderQueueArray *_currQueue, *_prevQueue;
+ MicroTileArray *_updateUta;
+
+ bool rectIntersectsItem(const Common::Rect &rect);
+ RenderQueueItem *findItemInQueue(RenderQueueArray *queue, const RenderQueueItem &item);
+ bool hasItemChanged(const RenderQueueItem &item1, const RenderQueueItem &item2);
+ void invalidateItemsByRect(const Common::Rect &rect, const RenderQueueItem *item);
+
+ void addDirtyRect(const Common::Rect &rect);
+ void restoreDirtyBackground();
+ void updateDirtyRects();
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_RENDER_H */
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 99bbc05..b631b1d 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -139,7 +139,6 @@ void ToltecsEngine::loadgame(const char *filename) {
delete in;
loadScene(_sceneResIndex);
- _screen->clearSprites();
_newCameraX = _cameraX;
_newCameraY = _cameraY;
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index fc981db..8951c1e 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -36,6 +36,7 @@
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
+#include "toltecs/render.h"
#include "toltecs/resource.h"
#include "toltecs/screen.h"
#include "toltecs/script.h"
@@ -74,12 +75,18 @@ Screen::Screen(ToltecsEngine *vm) : _vm(vm) {
_talkTextFontColor = 0;
_talkTextMaxWidth = 520;
+ _renderQueue = new RenderQueue(_vm);
+ _fullRefresh = false;
+ _guiRefresh = false;
+
}
Screen::~Screen() {
delete[] _frontScreen;
delete[] _backScreen;
+
+ delete _renderQueue;
}
@@ -155,7 +162,9 @@ void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
}
}
}
-
+
+ _guiRefresh = true;
+
}
void Screen::startShakeScreen(int16 shakeCounter) {
@@ -261,9 +270,6 @@ void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, i
void Screen::clearSprites() {
- _spriteDrawList.clear();
- // TODO
-
}
void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
@@ -336,6 +342,8 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
+ _guiRefresh = true;
+
}
void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
@@ -461,7 +469,7 @@ void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16
}
-void Screen::drawTalkTextItems() {
+void Screen::addTalkTextItemsToRenderQueue() {
for (int16 i = 0; i <= _talkTextItemNum; i++) {
TalkTextItem *item = &_talkTextItems[i];
@@ -475,8 +483,8 @@ void Screen::drawTalkTextItems() {
item->duration = 0;
for (byte j = 0; j < item->lineCount; j++) {
- drawString(item->lines[j].x, item->lines[j].y, item->color, _fontResIndexArray[item->fontNum],
- text, item->lines[j].length, NULL, true);
+ _renderQueue->addText(item->lines[j].x, item->lines[j].y, item->color, _fontResIndexArray[item->fontNum],
+ text, item->lines[j].length);
text += item->lines[j].length;
}
@@ -535,6 +543,8 @@ void Screen::drawGuiTextMulti(byte *textData) {
} while (*wrapState.sourceString != 0xFF);
+ _guiRefresh = true;
+
}
int16 Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState) {
@@ -634,6 +644,55 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
}
+void Screen::drawSurface(int16 x, int16 y, Graphics::Surface *surface) {
+
+ int16 skipX = 0;
+ int16 width = surface->w;
+ int16 height = surface->h;
+ byte *surfacePixels = (byte*)surface->getBasePtr(0, 0);
+ byte *frontScreen;
+
+ // Not on screen, skip
+ if (x + width < 0 || y + height < 0 || x >= 640 || y >= _vm->_cameraHeight)
+ return;
+
+ if (x < 0) {
+ skipX = -x;
+ x = 0;
+ width -= skipX;
+ }
+
+ if (y < 0) {
+ int16 skipY = -y;
+ surfacePixels += surface->w * skipY;
+ y = 0;
+ height -= skipY;
+ }
+
+ if (x + width >= 640) {
+ width -= x + width - 640;
+ }
+
+ if (y + height >= _vm->_cameraHeight) {
+ height -= y + height - _vm->_cameraHeight;
+ }
+
+ frontScreen = _vm->_screen->_frontScreen + x + (y * 640);
+
+ for (int16 h = 0; h < height; h++) {
+ surfacePixels += skipX;
+ for (int16 w = 0; w < width; w++) {
+ if (*surfacePixels != 0xFF)
+ *frontScreen = *surfacePixels;
+ frontScreen++;
+ surfacePixels++;
+ }
+ frontScreen += 640 - width;
+ surfacePixels += surface->w - width - skipX;
+ }
+
+}
+
void Screen::saveState(Common::WriteStream *out) {
// Save verb line
@@ -726,6 +785,7 @@ void Screen::loadState(Common::ReadStream *in) {
in->read(gui, 640);
gui += 640;
}
+ _guiRefresh = true;
}
// Load fonts
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index e886631..752d5a4 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -59,7 +59,7 @@ struct SpriteDrawItem {
int16 x, y;
int16 width, height;
int16 origWidth, origHeight;
- int16 resIndex;
+ int16 resIndex, frameNum;
uint32 offset;
int16 xdelta, ydelta;
uint16 flags;
@@ -133,11 +133,11 @@ enum SpriteReaderStatus {
class SpriteFilter {
public:
- SpriteFilter(SpriteDrawItem *sprite) : _sprite(sprite) {
+ SpriteFilter(const SpriteDrawItem &sprite) : _sprite(&sprite) {
}
virtual SpriteReaderStatus readPacket(PixelPacket &packet) = 0;
protected:
- SpriteDrawItem *_sprite;
+ const SpriteDrawItem *_sprite;
};
struct TextRect {
@@ -163,6 +163,8 @@ struct GuiTextWrapState {
byte textBuffer[100];
};
+class RenderQueue;
+
class Screen {
public:
Screen(ToltecsEngine *vm);
@@ -184,9 +186,8 @@ public:
void clearSprites();
// Sprite drawing
- void drawSprite(SpriteDrawItem *sprite);
- void drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite);
- void drawSprites();
+ void drawSprite(const SpriteDrawItem &sprite);
+ void drawSpriteCore(byte *dest, SpriteFilter &reader, const SpriteDrawItem &sprite);
// Verb line
void updateVerbLine(int16 slotIndex, int16 slotOffset);
@@ -194,7 +195,7 @@ public:
// Talk text
void updateTalkText(int16 slotIndex, int16 slotOffset);
void addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item);
- void drawTalkTextItems();
+ void addTalkTextItemsToRenderQueue();
int16 getTalkTextDuration();
void finishTextDrawItems();
@@ -207,6 +208,8 @@ public:
int16 drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len = -1, int16 *ywobble = NULL, bool outline = false);
void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline);
+ void drawSurface(int16 x, int16 y, Graphics::Surface *surface);
+
void saveState(Common::WriteStream *out);
void loadState(Common::ReadStream *in);
@@ -226,8 +229,6 @@ public:
byte *_frontScreen, *_backScreen;
- Common::List<SpriteDrawItem> _spriteDrawList;
-
uint _fontResIndexArray[10];
byte _fontColor1, _fontColor2;
@@ -249,6 +250,10 @@ public:
int16 _talkTextItemNum;
TalkTextItem _talkTextItems[5];
+ RenderQueue *_renderQueue;
+ bool _fullRefresh;
+ bool _guiRefresh;
+
void addDrawRequest(const DrawRequest &drawRequest);
};
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 6a3f849..ec9d021 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -36,6 +36,7 @@
#include "sound/mixer.h"
#include "toltecs/toltecs.h"
+#include "toltecs/render.h"
#include "toltecs/resource.h"
#include "toltecs/screen.h"
#include "toltecs/segmap.h"
@@ -421,78 +422,9 @@ void SegmentMap::freeSegmapMaskRectSurfaces() {
}
}
-void SegmentMap::restoreMasksBySprite(SpriteDrawItem *sprite) {
- // TODO: This needs more optimization
+void SegmentMap::addMasksToRenderQueue() {
for (uint i = 0; i < _maskRects.size(); i++) {
- if (sprite->priority <= _maskRects[i].priority) {
- restoreMask(i);
- }
- }
-}
-
-void SegmentMap::restoreMask(int16 index) {
-
- // TODO: This needs more optimization
- SegmapMaskRect *maskRect = &_maskRects[index];
-
- int16 skipX = 0;
- int16 x = maskRect->x - _vm->_cameraX;
- int16 y = maskRect->y - _vm->_cameraY;
- int16 width = maskRect->width;
- int16 height = maskRect->height;
- byte *maskSurface = (byte*)maskRect->surface->getBasePtr(0, 0);
- byte *frontScreen;
-
- debug(0, "SegmentMap::restoreMask() screenX = %d; screenY = %d; maskX = %d; maskY = %d",
- x, y, maskRect->x, maskRect->y);
-
- // Not on screen, skip
- if (x + width < 0 || y + height < 0 || x >= 640 || y >= _vm->_cameraHeight)
- return;
-
- if (x < 0) {
- skipX = -x;
- x = 0;
- width -= skipX;
- }
-
- if (y < 0) {
- int16 skipY = -y;
- maskSurface += maskRect->width * skipY;
- y = 0;
- height -= skipY;
- }
-
- if (x + width >= 640) {
- width -= x + width - 640;
- }
-
- if (y + height >= _vm->_cameraHeight) {
- height -= y + height - _vm->_cameraHeight;
- }
-
- frontScreen = _vm->_screen->_frontScreen + x + (y * 640);
-
- for (int16 h = 0; h < height; h++) {
- maskSurface += skipX;
- for (int16 w = 0; w < width; w++) {
- if (*maskSurface != 0xFF)
- *frontScreen = *maskSurface;
- frontScreen++;
- maskSurface++;
- }
- frontScreen += 640 - width;
- maskSurface += maskRect->width - width - skipX;
- }
-
-}
-
-void SegmentMap::debugDrawRects(Graphics::Surface *surf) {
- for (uint16 i = 0; i < _pathRects.size(); i++) {
- SegmapPathRect pathRect = _pathRects[i];
- surf->frameRect(
- Common::Rect(pathRect.x1, pathRect.y1, pathRect.x2, pathRect.y2),
- 255);
+ _vm->_screen->_renderQueue->addMask(_maskRects[i]);
}
}
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index 6c20eac..77ab247 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -56,6 +56,13 @@ struct ScriptWalk {
int16 scaling;
};
+struct SegmapMaskRect {
+ int16 x, y;
+ int16 width, height;
+ int16 priority;
+ Graphics::Surface *surface;
+};
+
class SegmentMap {
public:
SegmentMap(ToltecsEngine *vm);
@@ -71,21 +78,11 @@ public:
int8 getScalingAtPoint(int16 x, int16 y);
void getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byte &g, byte &b);
- void restoreMasksBySprite(SpriteDrawItem *sprite);
- void restoreMask(int16 index);
-
- void debugDrawRects(Graphics::Surface *surf);
+ void addMasksToRenderQueue();
//protected:
public: // for debugging purposes
- struct SegmapMaskRect {
- int16 x, y;
- int16 width, height;
- int16 priority;
- Graphics::Surface *surface;
- };
-
struct SegmapPathRect {
int16 x1, y1, x2, y2;
};
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index 3327f04..4e5af5f 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -36,6 +36,7 @@
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
+#include "toltecs/render.h"
#include "toltecs/resource.h"
#include "toltecs/screen.h"
#include "toltecs/script.h"
@@ -45,7 +46,7 @@ namespace Toltecs {
class SpriteReader : public SpriteFilter {
public:
- SpriteReader(byte *source, SpriteDrawItem *sprite) : SpriteFilter(sprite), _source(source) {
+ SpriteReader(byte *source, const SpriteDrawItem &sprite) : SpriteFilter(sprite), _source(source) {
_curWidth = _sprite->origWidth;
_curHeight = _sprite->origHeight;
}
@@ -95,7 +96,7 @@ protected:
class SpriteFilterScaleDown : public SpriteFilter {
public:
- SpriteFilterScaleDown(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ SpriteFilterScaleDown(const SpriteDrawItem &sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
_height = _sprite->height;
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
@@ -146,7 +147,7 @@ protected:
class SpriteFilterScaleUp : public SpriteFilter {
public:
- SpriteFilterScaleUp(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ SpriteFilterScaleUp(const SpriteDrawItem &sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
_height = _sprite->height;
_yerror = _sprite->yerror;
_origHeight = _sprite->origHeight;
@@ -205,12 +206,15 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (drawRequest.flags == 0xFFFF)
return;
+ frameNum = drawRequest.flags & 0x0FFF;
+
sprite.flags = 0;
sprite.baseColor = drawRequest.baseColor;
sprite.x = drawRequest.x;
sprite.y = drawRequest.y;
sprite.priority = drawRequest.y;
sprite.resIndex = drawRequest.resIndex;
+ sprite.frameNum = frameNum;
spriteData = _vm->_res->load(drawRequest.resIndex);
@@ -226,8 +230,6 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.flags |= 0x40;
}
- frameNum = drawRequest.flags & 0x0FFF;
-
// First initialize the sprite item with the values from the sprite resource
SpriteFrameEntry spriteFrameEntry(spriteData + frameNum * 12);
@@ -391,48 +393,43 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (sprite.width <= 0)
return;
- // Add sprite sorted by priority
- Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin();
- while (iter != _spriteDrawList.end() && (*iter).priority <= sprite.priority) {
- iter++;
- }
- _spriteDrawList.insert(iter, sprite);
+ _renderQueue->addSprite(sprite);
}
-void Screen::drawSprite(SpriteDrawItem *sprite) {
+void Screen::drawSprite(const SpriteDrawItem &sprite) {
debug(0, "Screen::drawSprite() x = %d; y = %d; flags = %04X; resIndex = %d; offset = %08X; drawX = %d; drawY = %d",
- sprite->x, sprite->y, sprite->flags, sprite->resIndex, sprite->offset,
- sprite->x - _vm->_cameraX, sprite->y - _vm->_cameraY);
+ sprite.x, sprite.y, sprite.flags, sprite.resIndex, sprite.offset,
+ sprite.x - _vm->_cameraX, sprite.y - _vm->_cameraY);
debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
- sprite->width, sprite->height, sprite->origWidth, sprite->origHeight);
+ sprite.width, sprite.height, sprite.origWidth, sprite.origHeight);
- byte *source = _vm->_res->load(sprite->resIndex) + sprite->offset;
- byte *dest = _frontScreen + (sprite->x - _vm->_cameraX) + (sprite->y - _vm->_cameraY) * 640;
+ byte *source = _vm->_res->load(sprite.resIndex) + sprite.offset;
+ byte *dest = _frontScreen + sprite.x + sprite.y * 640;
SpriteReader spriteReader(source, sprite);
- if (sprite->flags & 0x40) {
+ if (sprite.flags & 0x40) {
// Shadow sprites
- if (sprite->flags & 1) {
+ if (sprite.flags & 1) {
SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
- } else if (sprite->flags & 2) {
+ } else if (sprite.flags & 2) {
SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
} else {
drawSpriteCore(dest, spriteReader, sprite);
}
- } else if (sprite->flags & 0x10) {
+ } else if (sprite.flags & 0x10) {
// 256 color sprite
drawSpriteCore(dest, spriteReader, sprite);
} else {
// 16 color sprite
- if (sprite->flags & 1) {
+ if (sprite.flags & 1) {
SpriteFilterScaleDown spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
- } else if (sprite->flags & 2) {
+ } else if (sprite.flags & 2) {
SpriteFilterScaleUp spriteScaler(sprite, &spriteReader);
drawSpriteCore(dest, spriteScaler, sprite);
} else {
@@ -444,13 +441,13 @@ void Screen::drawSprite(SpriteDrawItem *sprite) {
}
-void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite) {
+void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, const SpriteDrawItem &sprite) {
int16 destInc;
- if (sprite->flags & 4) {
+ if (sprite.flags & 4) {
destInc = -1;
- dest += sprite->width;
+ dest += sprite.width;
} else {
destInc = 1;
}
@@ -459,10 +456,10 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
PixelPacket packet;
byte *destp = dest;
- int16 skipX = sprite->skipX;
+ int16 skipX = sprite.skipX;
- int16 w = sprite->width;
- int16 h = sprite->height;
+ int16 w = sprite.width;
+ int16 h = sprite.height;
do {
status = reader.readPacket(packet);
@@ -483,20 +480,20 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
w -= packet.count;
- if (((sprite->flags & 0x40) && (packet.pixel != 0)) ||
- ((sprite->flags & 0x10) && (packet.pixel != 0xFF)) ||
- !(sprite->flags & 0x10) && (packet.pixel != 0))
+ if (((sprite.flags & 0x40) && (packet.pixel != 0)) ||
+ ((sprite.flags & 0x10) && (packet.pixel != 0xFF)) ||
+ !(sprite.flags & 0x10) && (packet.pixel != 0))
{
- if (sprite->flags & 0x40) {
+ if (sprite.flags & 0x40) {
while (packet.count--) {
*dest = _vm->_palette->getColorTransPixel(*dest);
dest += destInc;
}
} else {
- if (sprite->flags & 0x10) {
+ if (sprite.flags & 0x10) {
packet.pixel = ((packet.pixel << 4) & 0xF0) | ((packet.pixel >> 4) & 0x0F);
} else {
- packet.pixel += sprite->baseColor - 1;
+ packet.pixel += sprite.baseColor - 1;
}
while (packet.count--) {
*dest = packet.pixel;
@@ -515,8 +512,8 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
}
dest = destp + 640;
destp = dest;
- skipX = sprite->skipX;
- w = sprite->width;
+ skipX = sprite.skipX;
+ w = sprite.width;
h--;
}
@@ -524,12 +521,4 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sp
}
-void Screen::drawSprites() {
- for (Common::List<SpriteDrawItem>::iterator iter = _spriteDrawList.begin(); iter != _spriteDrawList.end(); iter++) {
- SpriteDrawItem *sprite = &(*iter);
- drawSprite(sprite);
- _vm->_segmap->restoreMasksBySprite(sprite);
- }
-}
-
} // End of namespace Toltecs
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index f9ebb41..3c9f1db 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -42,11 +42,11 @@
#include "toltecs/menu.h"
#include "toltecs/movie.h"
#include "toltecs/palette.h"
+#include "toltecs/render.h"
#include "toltecs/resource.h"
#include "toltecs/script.h"
#include "toltecs/screen.h"
#include "toltecs/segmap.h"
-
#include "toltecs/microtiles.h"
namespace Toltecs {
@@ -89,8 +89,6 @@ int ToltecsEngine::init() {
int ToltecsEngine::go() {
- _system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true);
-
_quitGame = false;
_counter01 = 0;
_counter02 = 0;
@@ -162,23 +160,6 @@ int ToltecsEngine::go() {
}
#endif
-//#define TEST_MICROTILES
-#ifdef TEST_MICROTILES
- MicroTileArray *uta = new MicroTileArray(0, 0, 640, 480);
- uta->unite(Common::Rect(10, 10, 50, 50));
- uta->unite(Common::Rect(45, 45, 60, 60));
- Common::Rect *rects;
- int n_rects;
- n_rects = uta->getRectangles(rects);
- printf("n_rects = %d\n", n_rects); fflush(stdout);
- for (int i = 0; i < n_rects; i++) {
- printf("%d, %d, %d, %d\n", rects[i].left, rects[i].top, rects[i].right, rects[i].bottom);
- fflush(stdout);
- }
- _system->quit();
- delete uta;
-#endif
-
#if 1
_script->loadScript(0, 0);
_script->runScript(0);
@@ -231,6 +212,9 @@ void ToltecsEngine::loadScene(uint resIndex) {
// Load scene segmap
_segmap->load(scene + imageSize + 4);
+ _screen->_fullRefresh = true;
+ _screen->_renderQueue->clear();
+
}
void ToltecsEngine::updateScreen() {
@@ -238,21 +222,19 @@ void ToltecsEngine::updateScreen() {
// FIXME: Quick hack, sometimes cameraY was negative (the code in updateCamera was at fault)
if (_cameraY < 0) _cameraY = 0;
- // TODO: Optimize redraw by using dirty rectangles
- byte *destp = _screen->_frontScreen;
- byte *srcp = _screen->_backScreen + _cameraX + _cameraY * _sceneWidth;
- for (uint y = 0; y < MIN<uint>(_cameraHeight, 400); y++) {
- memcpy(destp, srcp, MIN<uint>(_sceneWidth, 640));
- destp += 640;
- srcp += _sceneWidth;
- }
+ _segmap->addMasksToRenderQueue();
+ _screen->addTalkTextItemsToRenderQueue();
- _screen->drawSprites();
- _screen->clearSprites();
+ _screen->_renderQueue->update();
+
+ //printf("_guiHeight = %d\n", _guiHeight); fflush(stdout);
- _screen->drawTalkTextItems();
+ if (_screen->_guiRefresh && _guiHeight > 0 && _cameraHeight > 0) {
+ _system->copyRectToScreen((const byte *)_screen->_frontScreen + _cameraHeight * 640,
+ 640, 0, _cameraHeight, 640, _guiHeight);
+ _screen->_guiRefresh = false;
+ }
- _system->copyRectToScreen((const byte *)_screen->_frontScreen, 640, 0, 0, 640, 400);
_system->updateScreen();
updateCamera();
@@ -268,7 +250,7 @@ void ToltecsEngine::updateInput() {
// FIXME: This is just for debugging
switch (event.kbd.keycode) {
- case Common::KEYCODE_F5:
+ case Common::KEYCODE_F7:
savegame("toltecs.001");
break;
case Common::KEYCODE_F9:
@@ -342,6 +324,15 @@ void ToltecsEngine::updateInput() {
}
+void ToltecsEngine::setGuiHeight(int16 guiHeight) {
+ if (guiHeight != _guiHeight) {
+ _guiHeight = guiHeight;
+ _cameraHeight = 400 - _guiHeight;
+ debug(0, "ToltecsEngine::setGuiHeight() _guiHeight = %d; _cameraHeight = %d", _guiHeight, _cameraHeight);
+ // TODO: clearScreen();
+ }
+}
+
void ToltecsEngine::setCamera(int16 x, int16 y) {
_screen->finishTextDrawItems();
@@ -356,8 +347,6 @@ void ToltecsEngine::setCamera(int16 x, int16 y) {
y = _sceneHeight - _cameraHeight;
*/
- // TODO DirtyRect clearing stuff
-
_screen->clearSprites();
_cameraX = x;
@@ -366,17 +355,6 @@ void ToltecsEngine::setCamera(int16 x, int16 y) {
_cameraY = y;
_newCameraY = y;
- // TODO More DirtyRect clearing stuff
-
-}
-
-void ToltecsEngine::setGuiHeight(int16 guiHeight) {
- if (guiHeight != _guiHeight) {
- _guiHeight = guiHeight;
- _cameraHeight = 400 - _guiHeight;
- debug(0, "ToltecsEngine::setGuiHeight() _guiHeight = %d; _cameraHeight = %d", _guiHeight, _cameraHeight);
- // TODO: clearScreen();
- }
}
void ToltecsEngine::scrollCameraUp(int16 delta) {
@@ -385,7 +363,6 @@ void ToltecsEngine::scrollCameraUp(int16 delta) {
_newCameraY = 0;
else
_newCameraY -= delta;
- _screen->finishTextDrawItems();
}
}
@@ -396,7 +373,6 @@ void ToltecsEngine::scrollCameraDown(int16 delta) {
delta += (_sceneHeight - _cameraHeight) - (delta + _newCameraY);
_newCameraY += delta;
debug(0, "ToltecsEngine::scrollCameraDown() _newCameraY = %d; delta = %d", _newCameraY, delta);
- _screen->finishTextDrawItems();
}
}
@@ -406,7 +382,6 @@ void ToltecsEngine::scrollCameraLeft(int16 delta) {
_newCameraX = 0;
else
_newCameraX -= delta;
- _screen->finishTextDrawItems();
}
}
@@ -417,7 +392,6 @@ void ToltecsEngine::scrollCameraRight(int16 delta) {
delta += (_sceneWidth - 640) - (delta + _newCameraX);
_newCameraX += delta;
debug(0, "ToltecsEngine::scrollCameraRight() _newCameraX = %d; delta = %d", _newCameraY, delta);
- _screen->finishTextDrawItems();
}
}
@@ -426,11 +400,15 @@ void ToltecsEngine::updateCamera() {
if (_cameraX != _newCameraX) {
//dirtyFullRefresh = -1;
_cameraX = _newCameraX;
+ _screen->_fullRefresh = true;
+ _screen->finishTextDrawItems();
}
if (_cameraY != _newCameraY) {
//dirtyFullRefresh = -1;
_cameraY = _newCameraY;
+ _screen->_fullRefresh = true;
+ _screen->finishTextDrawItems();
}
debug(0, "ToltecsEngine::updateCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 7c7e3ea..e0d64bd 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -82,8 +82,9 @@ public:
void updateScreen();
void updateInput();
- void setCamera(int16 x, int16 y);
void setGuiHeight(int16 guiHeight);
+
+ void setCamera(int16 x, int16 y);
void scrollCameraUp(int16 delta);
void scrollCameraDown(int16 delta);
void scrollCameraLeft(int16 delta);
Commit: 3acd7871450d62e34a15bbad8f467060cb64bade
https://github.com/scummvm/scummvm/commit/3acd7871450d62e34a15bbad8f467060cb64bade
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:06-08:00
Commit Message:
TOLTECS: Updated TODO.txt
Changed paths:
engines/toltecs/TODO.txt
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index cf4a199..378c1c3 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -19,8 +19,6 @@ TODO
messy function
- Extend savegame format (savegame version, description, more data)
- When saving a game, save the whole screen when an animation is playing
-- Implement dirty rectangles (low priority)
-- Optimize segment mask redrawing (only redraw what's neccessary)
BUGS
------
@@ -28,3 +26,8 @@ BUGS
- Still some clipping issues (walking upstairs in the saloon, when on top of the tower in the hideout)
- Crashes sometimes on scene changes
(I guess because some talktext is still running although the slot used by it has changed)
+
+DONE
+------
+- Implement dirty rectangles (low priority)
+- Optimize segment mask redrawing (only redraw what's neccessary)
Commit: 02e2b78e5c2e1f63668d32183a2ba5d2b57c4031
https://github.com/scummvm/scummvm/commit/02e2b78e5c2e1f63668d32183a2ba5d2b57c4031
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Added sound to the movie player (finally). Still TODO: Ability to abort movies.
Changed paths:
engines/toltecs/movie.cpp
engines/toltecs/movie.h
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index ef280fa..b5665aa 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -49,7 +49,7 @@ MoviePlayer::~MoviePlayer() {
void MoviePlayer::playMovie(uint resIndex) {
- uint32 chunkCount, frameCount, subtitleSlot;
+ uint32 subtitleSlot;
byte moviePalette[768];
memset(moviePalette, 0, sizeof(moviePalette));
@@ -59,19 +59,34 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_arc->openResource(resIndex);
- frameCount = _vm->_arc->readUint32LE();
- chunkCount = _vm->_arc->readUint32LE();
subtitleSlot = kMaxScriptSlots - 1;
-
- // TODO: Read/figure out rest of the header
- _vm->_arc->seek(0x10, SEEK_CUR);
+
+ _frameCount = _vm->_arc->readUint32LE();
+ _chunkCount = _vm->_arc->readUint32LE();
+
+ // TODO: Figure out rest of the header
+ _vm->_arc->readUint32LE();
+ _vm->_arc->readUint32LE();
+ _framesPerSoundChunk = _vm->_arc->readUint32LE();
+ _vm->_arc->readUint32LE();
+
_vm->_sceneWidth = 640;
_vm->_sceneHeight = 400;
_vm->_cameraHeight = 400;
_vm->_cameraX = 0;
_vm->_cameraY = 0;
- while (chunkCount--) {
+ _audioStream = Audio::makeAppendableAudioStream(22050, Audio::Mixer::FLAG_UNSIGNED);
+
+ _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
+
+ _soundChunkFramesLeft = 0;
+ _lastPrefetchOfs = 0;
+ fetchAudioChunks();
+
+ uint32 lastTime = _vm->_mixer->getSoundElapsedTime(_audioStreamHandle);
+
+ while (_chunkCount--) {
byte chunkType;
uint32 chunkSize;
@@ -91,12 +106,25 @@ void MoviePlayer::playMovie(uint resIndex) {
switch (chunkType) {
case 0: // image data
case 1:
+
unpackRle(chunkBuffer, _vm->_screen->_backScreen);
// TODO: Rework this
_vm->_screen->updateShakeScreen();
+ _vm->_screen->_fullRefresh = true;
_vm->updateInput();
_vm->updateScreen();
- g_system->delayMillis(80);
+
+ _soundChunkFramesLeft--;
+ if (_soundChunkFramesLeft <= _framesPerSoundChunk) {
+ fetchAudioChunks();
+ }
+
+ while (_vm->_mixer->getSoundElapsedTime(_audioStreamHandle) < lastTime + 111) {
+ g_system->delayMillis(0);
+ }
+
+ lastTime = _vm->_mixer->getSoundElapsedTime(_audioStreamHandle);
+
break;
case 2: // palette data
unpackPalette(chunkBuffer, moviePalette, 256, 3);
@@ -104,7 +132,6 @@ void MoviePlayer::playMovie(uint resIndex) {
break;
//case 3: -- what is this type
case 4: // audio data
- // TODO: Handle audio data
break;
case 5:
// TODO: Check if the text is a subtitle (last character == 0xFE).
@@ -119,8 +146,8 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_screen->startShakeScreen(chunkBuffer[0]);
break;
case 7: // setup subtitle parameters
- _vm->_screen->_talkTextY = READ_LE_UINT16(&chunkBuffer[0]);
- _vm->_screen->_talkTextX = READ_LE_UINT16(&chunkBuffer[2]);
+ _vm->_screen->_talkTextY = READ_LE_UINT16(chunkBuffer + 0);
+ _vm->_screen->_talkTextX = READ_LE_UINT16(chunkBuffer + 2);
_vm->_screen->_talkTextFontColor = chunkBuffer[4];
debug(0, "_talkTextX = %d; _talkTextY = %d; _talkTextFontColor = %d",
_vm->_screen->_talkTextX, _vm->_screen->_talkTextY, _vm->_screen->_talkTextFontColor);
@@ -139,7 +166,43 @@ void MoviePlayer::playMovie(uint resIndex) {
}
+ _audioStream->finish();
+ _vm->_mixer->stopHandle(_audioStreamHandle);
+
_vm->_arc->closeResource();
+
+ debug(0, "playMovie() done");
+
+}
+
+void MoviePlayer::fetchAudioChunks() {
+
+ uint32 startOfs = _vm->_arc->pos();
+ uint32 chunkCount = _chunkCount;
+ uint prefetchChunkCount = 0;
+
+ if (_lastPrefetchOfs != 0)
+ _vm->_arc->seek(_lastPrefetchOfs, SEEK_SET);
+
+ while (chunkCount-- && prefetchChunkCount < _framesPerSoundChunk / 2) {
+ byte chunkType = _vm->_arc->readByte();
+ uint32 chunkSize = _vm->_arc->readUint32LE();
+ if (chunkType == 4) {
+ byte *chunkBuffer = new byte[chunkSize];
+ _vm->_arc->read(chunkBuffer, chunkSize);
+ _audioStream->queueBuffer(chunkBuffer, chunkSize);
+ chunkBuffer = NULL;
+ prefetchChunkCount++;
+ _soundChunkFramesLeft += _framesPerSoundChunk;
+ delete[] chunkBuffer;
+ } else {
+ _vm->_arc->seek(chunkSize, SEEK_CUR);
+ }
+ }
+
+ _lastPrefetchOfs = _vm->_arc->pos();
+
+ _vm->_arc->seek(startOfs, SEEK_SET);
}
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
index 9ab5435..40b1f2e 100644
--- a/engines/toltecs/movie.h
+++ b/engines/toltecs/movie.h
@@ -47,16 +47,23 @@ namespace Toltecs {
class MoviePlayer {
public:
- MoviePlayer(ToltecsEngine *vm);
- ~MoviePlayer();
+ MoviePlayer(ToltecsEngine *vm);
+ ~MoviePlayer();
void playMovie(uint resIndex);
protected:
- ToltecsEngine *_vm;
+ ToltecsEngine *_vm;
+ Audio::AppendableAudioStream *_audioStream;
+ Audio::SoundHandle _audioStreamHandle;
+
+ uint32 _chunkCount, _frameCount, _lastPrefetchOfs;
+ uint32 _soundChunkFramesLeft, _framesPerSoundChunk;
void unpackPalette(byte *source, byte *dest, int elemCount, int elemSize);
void unpackRle(byte *source, byte *dest);
+
+ void fetchAudioChunks();
};
Commit: beab4e3ca537f93d560640093e2f56c3120bceb4
https://github.com/scummvm/scummvm/commit/beab4e3ca537f93d560640093e2f56c3120bceb4
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Correct initialization for graphics. Since the game is 640x480, it should be
default to 1x scaler.
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 3c9f1db..a5c1caf 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -81,7 +81,7 @@ ToltecsEngine::~ToltecsEngine() {
int ToltecsEngine::init() {
// Initialize backend
_system->beginGFXTransaction();
- initCommonGFX(false);
+ initCommonGFX(true);
_system->initSize(640, 400);
_system->endGFXTransaction();
return 0;
Commit: f77960e81b5f0b17ebddd4b640cc315bcfc6ef78
https://github.com/scummvm/scummvm/commit/f77960e81b5f0b17ebddd4b640cc315bcfc6ef78
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Removed unused functions.
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/script.h
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 6f155b2..13cc0ea 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -1147,10 +1147,6 @@ int16 ScriptInterpreter::arg16(int16 offset) {
return READ_LE_UINT16(&_subCode[offset]);
}
-int32 ScriptInterpreter::arg32(int16 offset) {
- return READ_LE_UINT32(&_subCode[offset]);
-}
-
void ScriptInterpreter::pushByte(byte value) {
_stack[_regs.sp] = value;
_regs.sp--;
@@ -1171,16 +1167,6 @@ int16 ScriptInterpreter::popInt16() {
return READ_LE_UINT16(_stack + _regs.sp);
}
-void ScriptInterpreter::pushInt32(int32 value) {
- WRITE_LE_UINT32(_stack + _regs.sp, value);
- _regs.sp -= 4;
-}
-
-int32 ScriptInterpreter::popInt32() {
- _regs.sp += 4;
- return READ_LE_UINT32(_stack + _regs.sp);
-}
-
void ScriptInterpreter::localWrite8(int16 offset, byte value) {
debug(1, "localWrite8(%d, %d)", offset, value);
_localData[offset] = value;
@@ -1201,16 +1187,6 @@ int16 ScriptInterpreter::localRead16(int16 offset) {
return (int16)READ_LE_UINT16(&_localData[offset]);
}
-void ScriptInterpreter::localWrite32(int16 offset, int32 value) {
- debug(1, "localWrite32(%d, %d)", offset, value);
- WRITE_LE_UINT32(&_localData[offset], value);
-}
-
-int32 ScriptInterpreter::localRead32(int16 offset) {
- debug(1, "localRead32(%d) -> %d", offset, (int32)READ_LE_UINT32(&_localData[offset]));
- return (int32)READ_LE_UINT32(&_localData[offset]);
-}
-
byte *ScriptInterpreter::localPtr(int16 offset) {
debug(1, "localPtr(%d)", offset);
return &_localData[offset];
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index eacd116..8f4ae80 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -111,21 +111,16 @@ protected:
byte arg8(int16 offset);
int16 arg16(int16 offset);
- int32 arg32(int16 offset);
void pushByte(byte value);
byte popByte();
void pushInt16(int16 value);
int16 popInt16();
- void pushInt32(int32 value);
- int32 popInt32();
void localWrite8(int16 offset, byte value);
byte localRead8(int16 offset);
void localWrite16(int16 offset, int16 value);
int16 localRead16(int16 offset);
- void localWrite32(int16 offset, int32 value);
- int32 localRead32(int16 offset);
byte *localPtr(int16 offset);
};
Commit: 4b13982116828453efd4a445328d455d9b820149
https://github.com/scummvm/scummvm/commit/4b13982116828453efd4a445328d455d9b820149
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Implemented preliminary sound playback; some stuff is still missing (correct volumes etc.)
Changed paths:
A engines/toltecs/sound.cpp
A engines/toltecs/sound.h
engines/toltecs/module.mk
engines/toltecs/movie.cpp
engines/toltecs/screen.cpp
engines/toltecs/screen.h
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
index 49d4e19..1d9d50c 100644
--- a/engines/toltecs/module.mk
+++ b/engines/toltecs/module.mk
@@ -14,6 +14,7 @@ MODULE_OBJS = \
screen.o \
script.o \
segmap.o \
+ sound.o \
sprite.o
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index b5665aa..6e59882 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -54,7 +54,7 @@ void MoviePlayer::playMovie(uint resIndex) {
memset(moviePalette, 0, sizeof(moviePalette));
- _vm->_screen->finishTextDrawItems();
+ _vm->_screen->finishTalkTextItems();
_vm->_screen->clearSprites();
_vm->_arc->openResource(resIndex);
@@ -154,7 +154,7 @@ void MoviePlayer::playMovie(uint resIndex) {
break;
case 8: // stop subtitles
_vm->_script->getSlotData(subtitleSlot)[0] = 0xFF;
- _vm->_screen->finishTextDrawItems();
+ _vm->_screen->finishTalkTextItems();
break;
default:
error("Unknown chunk type %d at %08X", chunkType, _vm->_arc->pos() - 5 - chunkSize);
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 8951c1e..cde0138 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -496,12 +496,22 @@ int16 Screen::getTalkTextDuration() {
return _talkTextItems[_talkTextItemNum].duration;
}
-void Screen::finishTextDrawItems() {
+void Screen::finishTalkTextItems() {
for (int16 i = 0; i <= _talkTextItemNum; i++) {
_talkTextItems[i].duration = 0;
}
}
+void Screen::keepTalkTextItemsAlive() {
+ for (int16 i = 0; i <= _talkTextItemNum; i++) {
+ TalkTextItem *item = &_talkTextItems[i];
+ if (item->fontNum == -1)
+ item->duration = 0;
+ else if (item->duration > 0)
+ item->duration = 2;
+ }
+}
+
void Screen::registerFont(uint fontIndex, uint resIndex) {
_fontResIndexArray[fontIndex] = resIndex;
}
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 752d5a4..ff27bb2 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -197,7 +197,8 @@ public:
void addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item);
void addTalkTextItemsToRenderQueue();
int16 getTalkTextDuration();
- void finishTextDrawItems();
+ void finishTalkTextItems();
+ void keepTalkTextItemsAlive();
// Font/text
void registerFont(uint fontIndex, uint resIndex);
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 13cc0ea..4f50ca2 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -41,6 +41,7 @@
#include "toltecs/script.h"
#include "toltecs/screen.h"
#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
namespace Toltecs {
@@ -445,7 +446,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
debug(0, "o2_updateScreen()");
- // TODO? updateSamples();
+ _vm->_sound->updateSpeech();
_vm->_screen->updateShakeScreen();
@@ -592,6 +593,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
{
debug(0, "o2_loadScene(resIndex: %d; flag: %d)", arg16(4), arg8(3));
if (arg8(3) == 0) {
+ _vm->_sound->stopSpeech();
_vm->loadScene(arg16(4));
} else {
_vm->_screen->loadMouseCursor(arg16(4));
@@ -845,7 +847,10 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 54:// TODO
{
- debug(0, "o2_playSound2(%d, %d, %d)", arg16(7), arg16(5), arg16(3));
+ //debug(0, "o2_playSound2(%d, %d, %d)", arg16(7), arg16(5), arg16(3));
+
+ _vm->_sound->playSound(arg16(3), arg16(5), arg16(7));
+
break;
}
@@ -878,15 +883,13 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 59:// TODO
{
- debug(0, "o2_precacheResources(%04X)", arg16(3));
+ debug(0, "o2_precacheSprites(%04X)", arg16(3));
break;
}
case 60:// TODO
{
debug(0, "o2_precacheSounds1(%04X)", arg16(3));
- // CHECKME
- _vm->_screen->clearSprites();
break;
}
@@ -896,6 +899,12 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
break;
}
+ case 62:// TODO - this opcode was never executed while I completed the game
+ {
+ debug(0, "o2_precacheSounds2(%04X)", arg16(3));
+ break;
+ }
+
case 63:// ok
{
_regs.sp = _savedSp;
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
new file mode 100644
index 0000000..a3e7a76
--- /dev/null
+++ b/engines/toltecs/sound.cpp
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+#include "base/version.h"
+
+#include "graphics/cursorman.h"
+
+#include "sound/mixer.h"
+
+#include "toltecs/toltecs.h"
+#include "toltecs/palette.h"
+#include "toltecs/render.h"
+#include "toltecs/resource.h"
+#include "toltecs/screen.h"
+#include "toltecs/script.h"
+#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
+
+namespace Toltecs {
+
+Sound::Sound(ToltecsEngine *vm) : _vm(vm) {
+ for (int i = 0; i < 4; i++) {
+ channels[i].type = 0;
+ channels[i].resIndex = -1;
+ }
+}
+
+Sound::~Sound() {
+}
+
+void Sound::playSpeech(int16 resIndex) {
+
+ // TODO
+
+ debug(0, "playSpeech(%d)", resIndex);
+
+ internalPlaySound(resIndex, -3, 50 /*TODO*/, 64);
+
+}
+
+void Sound::playSound(int16 resIndex, int16 type, int16 volume) {
+
+ // TODO: Use the right volumes
+
+ debug(0, "playSound(%d, %d, %d)", resIndex, type, volume);
+
+ if (volume == -1 || type == -2) {
+ if (type == -1) {
+ internalPlaySound(resIndex, type, 50 /*TODO*/, 64);
+ } else {
+ internalPlaySound(resIndex, type, 100 /*TODO*/, 64);
+ }
+ } else {
+ internalPlaySound(resIndex, type, 100 /*TODO*/, 64);
+ }
+
+}
+
+void Sound::playSoundAtPos(int16 resIndex, int16 x, int16 y) {
+
+ // TODO: Everything
+
+ debug(0, "playSoundAtPos(%d, %d, %d)", resIndex, x, y);
+
+ internalPlaySound(resIndex, 1, 50, 64);
+
+}
+
+void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning) {
+
+ // TODO
+
+ if (resIndex == -1) {
+ // Stop all sounds
+ _vm->_mixer->stopAll();
+ _vm->_screen->keepTalkTextItemsAlive();
+ for (int i = 0; i < 4; i++) {
+ channels[i].type = 0;
+ channels[i].resIndex = -1;
+ }
+ } else if (type == -2) {
+ // Stop sounds with specified resIndex
+ for (int i = 0; i < 4; i++) {
+ if (channels[i].resIndex == resIndex) {
+ _vm->_mixer->stopHandle(channels[i].handle);
+ channels[i].type = 0;
+ channels[i].resIndex = -1;
+ }
+ }
+ } else {
+
+ if (type == -3) {
+ // Stop sounds with type == -3 and play new sound
+ stopSpeech();
+ }
+
+ // Play new sound in empty channel
+
+ int freeChannel = -1;
+ for (int i = 0; i < 4; i++) {
+ if (channels[i].type == 0) {
+ freeChannel = i;
+ break;
+ }
+ }
+
+ // If all channels are in use no new sound will be played
+ if (freeChannel >= 0) {
+
+ byte *soundData = _vm->_res->load(resIndex);
+ uint32 soundSize = _vm->_res->getCurItemSize();
+
+ byte flags = Audio::Mixer::FLAG_UNSIGNED;
+ // Sounds with type == -1 loop
+ if (type == -1)
+ flags |= Audio::Mixer::FLAG_LOOP;
+ Audio::AudioStream *stream = Audio::makeLinearInputStream(soundData, soundSize, 22050, flags, 0, 0);
+
+ channels[freeChannel].type = type;
+ channels[freeChannel].resIndex = resIndex;
+
+ _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType/*TODO*/, &channels[freeChannel].handle,
+ stream, -1, volume, panning);
+
+ }
+
+ }
+
+}
+
+void Sound::updateSpeech() {
+ for (int i = 0; i < 4; i++) {
+ if (channels[i].type == -3 && _vm->_mixer->isSoundHandleActive(channels[i].handle)) {
+ _vm->_screen->keepTalkTextItemsAlive();
+ break;
+ }
+ }
+}
+
+void Sound::stopSpeech() {
+ for (int i = 0; i < 4; i++) {
+ if (channels[i].type == -3) {
+ _vm->_mixer->stopHandle(channels[i].handle);
+ _vm->_screen->keepTalkTextItemsAlive();
+ channels[i].type = 0;
+ channels[i].resIndex = -1;
+ }
+ }
+}
+
+} // End of namespace Toltecs
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
new file mode 100644
index 0000000..02f7a96
--- /dev/null
+++ b/engines/toltecs/sound.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef TOLTECS_SOUND_H
+#define TOLTECS_SOUND_H
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "common/hash-str.h"
+#include "common/events.h"
+#include "common/keyboard.h"
+#include "common/array.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+#include "toltecs/toltecs.h"
+
+namespace Toltecs {
+
+// 0x1219
+
+struct SoundChannel {
+ int16 resIndex;
+ int16 type;
+ Audio::SoundHandle handle;
+};
+
+class Sound {
+public:
+ Sound(ToltecsEngine *vm);
+ ~Sound();
+
+ void playSpeech(int16 resIndex);
+ void playSound(int16 resIndex, int16 type, int16 volume);
+ void playSoundAtPos(int16 resIndex, int16 x, int16 y);
+ void updateSpeech();
+ void stopSpeech();
+
+protected:
+ ToltecsEngine *_vm;
+
+ SoundChannel channels[4];
+
+ void internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning);
+
+};
+
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_SOUND_H */
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index a5c1caf..3aa160a 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -47,6 +47,7 @@
#include "toltecs/script.h"
#include "toltecs/screen.h"
#include "toltecs/segmap.h"
+#include "toltecs/sound.h"
#include "toltecs/microtiles.h"
namespace Toltecs {
@@ -134,6 +135,8 @@ int ToltecsEngine::go() {
_segmap = new SegmentMap(this);
_moviePlayer = new MoviePlayer(this);
_menuSystem = new MenuSystem(this);
+
+ _sound = new Sound(this);
_system->showMouse(true);
@@ -141,7 +144,10 @@ int ToltecsEngine::go() {
#ifdef TEST_MOVIE
_screen->registerFont(0, 0x0D);
_screen->registerFont(1, 0x0E);
- _moviePlayer->playMovie(0x000012D8);
+ //_moviePlayer->playMovie(0x000012D8);
+ //_moviePlayer->playMovie(0x000012D7);
+ //_moviePlayer->playMovie(0x);
+ _moviePlayer->playMovie(0x000012E0);
#endif
//#define TEST_MENU
@@ -151,7 +157,7 @@ int ToltecsEngine::go() {
_screen->loadMouseCursor(12);
_palette->loadAddPalette(9, 224);
_palette->setDeltaPalette(_palette->getMainPalette(), 7, 0, 31, 224);
- _screen->finishTextDrawItems();
+ _screen->finishTalkTextItems();
_screen->clearSprites();
while (1) {
updateInput();
@@ -174,6 +180,8 @@ int ToltecsEngine::go() {
delete _segmap;
delete _moviePlayer;
delete _menuSystem;
+
+ delete _sound;
return 0;
}
@@ -335,7 +343,7 @@ void ToltecsEngine::setGuiHeight(int16 guiHeight) {
void ToltecsEngine::setCamera(int16 x, int16 y) {
- _screen->finishTextDrawItems();
+ _screen->finishTalkTextItems();
/*
// TODO: Fix checks; sometimes cameraY ended up being negative
@@ -401,14 +409,14 @@ void ToltecsEngine::updateCamera() {
//dirtyFullRefresh = -1;
_cameraX = _newCameraX;
_screen->_fullRefresh = true;
- _screen->finishTextDrawItems();
+ _screen->finishTalkTextItems();
}
if (_cameraY != _newCameraY) {
//dirtyFullRefresh = -1;
_cameraY = _newCameraY;
_screen->_fullRefresh = true;
- _screen->finishTextDrawItems();
+ _screen->finishTalkTextItems();
}
debug(0, "ToltecsEngine::updateCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
@@ -438,6 +446,7 @@ void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
if (_doSpeech) {
int16 resIndex = READ_LE_UINT16(scanData + 1);
debug(0, "ToltecsEngine::talk() playSound(resIndex: %d)", resIndex);
+ _sound->playSpeech(resIndex);
}
if (_doText) {
_screen->updateTalkText(slotIndex, slotOffset);
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index e0d64bd..b9d08c3 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -59,6 +59,7 @@ class ResourceCache;
class ScriptInterpreter;
class Screen;
class SegmentMap;
+class Sound;
class ToltecsEngine : public ::Engine {
Common::KeyState _keyPressed;
@@ -112,6 +113,7 @@ public:
ScriptInterpreter *_script;
Screen *_screen;
SegmentMap *_segmap;
+ Sound *_sound;
uint _sceneResIndex;
int16 _sceneWidth, _sceneHeight;
Commit: 47ae9085899a41f5ed5204183b008d4bff7c4a31
https://github.com/scummvm/scummvm/commit/47ae9085899a41f5ed5204183b008d4bff7c4a31
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: - Fixed Screen::updateTalkText (text x position was read incorrectly and font color wasn't nibble-swapped)
- Hooked up the movie player; movies can be aborted with Escape (not with mouse clicks at the moment because I was too lazy to implement it; funny, writing this explanation probably took longer :))
Changed paths:
engines/toltecs/movie.cpp
engines/toltecs/movie.h
engines/toltecs/screen.cpp
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 6e59882..2813c0e 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -148,7 +148,7 @@ void MoviePlayer::playMovie(uint resIndex) {
case 7: // setup subtitle parameters
_vm->_screen->_talkTextY = READ_LE_UINT16(chunkBuffer + 0);
_vm->_screen->_talkTextX = READ_LE_UINT16(chunkBuffer + 2);
- _vm->_screen->_talkTextFontColor = chunkBuffer[4];
+ _vm->_screen->_talkTextFontColor = ((chunkBuffer[4] << 4) & 0xF0) | ((chunkBuffer[4] >> 4) & 0x0F);
debug(0, "_talkTextX = %d; _talkTextY = %d; _talkTextFontColor = %d",
_vm->_screen->_talkTextX, _vm->_screen->_talkTextY, _vm->_screen->_talkTextFontColor);
break;
@@ -157,12 +157,15 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_screen->finishTalkTextItems();
break;
default:
- error("Unknown chunk type %d at %08X", chunkType, _vm->_arc->pos() - 5 - chunkSize);
+ error("MoviePlayer::playMovie(%04X) Unknown chunk type %d at %08X", resIndex, chunkType, _vm->_arc->pos() - 5 - chunkSize);
}
delete[] chunkBuffer;
_vm->_arc->seek(movieOffset, SEEK_SET);
+
+ if (!handleInput())
+ break;
}
@@ -238,5 +241,24 @@ void MoviePlayer::unpackRle(byte *source, byte *dest) {
}
}
+bool MoviePlayer::handleInput() {
+ Common::Event event;
+ Common::EventManager *eventMan = g_system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+ return false;
+ break;
+ case Common::EVENT_QUIT:
+ g_system->quit();
+ return false;
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+}
} // End of namespace Toltecs
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
index 40b1f2e..abb7532 100644
--- a/engines/toltecs/movie.h
+++ b/engines/toltecs/movie.h
@@ -64,7 +64,9 @@ protected:
void unpackRle(byte *source, byte *dest);
void fetchAudioChunks();
-
+
+ bool handleInput();
+
};
} // End of namespace Toltecs
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index cde0138..d70cda3 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -364,12 +364,12 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
while (1) {
if (*textData == 0x0A) {
- x = CLIP<int16>(textData[3], 120, _talkTextMaxWidth);
+ x = CLIP<int16>(READ_LE_UINT16(&textData[3]), 120, _talkTextMaxWidth);
y = CLIP<int16>(READ_LE_UINT16(&textData[1]), 4, _vm->_cameraHeight - 16);
maxWidth = 624 - ABS(x - 320) * 2;
textData += 4;
} else if (*textData == 0x14) {
- item->color = textData[1];
+ item->color = ((textData[1] << 4) & 0xF0) | ((textData[1] >> 4) & 0x0F);
textData += 2;
} else if (*textData == 0x19) {
durationModifier = textData[1];
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 4f50ca2..18942ec 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -36,6 +36,7 @@
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
+#include "toltecs/movie.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
#include "toltecs/script.h"
@@ -920,7 +921,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 65:// TODO
{
debug(0, "o2_playMovie(%d, %d)", arg16(3), arg16(5));
- // TODO: Enable once the player is ready: _vm->_moviePlayer->playMovie()
+ _vm->_moviePlayer->playMovie(arg16(3));
break;
}
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 3aa160a..4691d23 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -345,16 +345,6 @@ void ToltecsEngine::setCamera(int16 x, int16 y) {
_screen->finishTalkTextItems();
- /*
- // TODO: Fix checks; sometimes cameraY ended up being negative
-
- if (x > _sceneWidth)
- x = _sceneWidth;
-
- if (y > _sceneHeight - _cameraHeight)
- y = _sceneHeight - _cameraHeight;
- */
-
_screen->clearSprites();
_cameraX = x;
Commit: 9e78b5d393cadd6ce426f0184e136a38579c819a
https://github.com/scummvm/scummvm/commit/9e78b5d393cadd6ce426f0184e136a38579c819a
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: - Listing savestates via command line or Launcher
- Loading/Saving during run time
Other savestate functions yet todo.
I'll probably remove the "original" in-game menu and move everything to the GMM.
Changed paths:
engines/toltecs/detection.cpp
engines/toltecs/movie.cpp
engines/toltecs/saveload.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 39915a5..9128ce5 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -56,7 +56,7 @@ namespace Toltecs {
static const ToltecsGameDescription gameDescriptions[] = {
{
- // Toltecs English version
+ // 3 Skulls of the Toltecs English version
{
"toltecs",
0,
@@ -67,8 +67,8 @@ static const ToltecsGameDescription gameDescriptions[] = {
},
},
-
{
+ // 3 Skulls of the Toltecs Russian version
{
"toltecs",
0,
@@ -115,9 +115,30 @@ public:
return "Toltecs Engine (C) 1996";
}
+ virtual bool hasFeature(MetaEngineFeature f) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+ SaveStateList listSaves(const char *target) const;
+ virtual int getMaximumSaveSlot() const;
+ void removeSaveState(const char *target, int slot) const;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
};
+bool ToltecsMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+// (f == kSupportsLoadingDuringStartup) ||
+// (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail);
+}
+
+bool Toltecs::ToltecsEngine::hasFeature(EngineFeature f) const {
+ return
+// (f == kSupportsRTL) ||
+ (f == kSupportsLoadingDuringRuntime) ||
+ (f == kSupportsSavingDuringRuntime);
+}
+
bool ToltecsMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
const Toltecs::ToltecsGameDescription *gd = (const Toltecs::ToltecsGameDescription *)desc;
if (gd) {
@@ -126,6 +147,100 @@ bool ToltecsMetaEngine::createInstance(OSystem *syst, Engine **engine, const Com
return gd != 0;
}
+SaveStateList ToltecsMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Toltecs::ToltecsEngine::SaveHeader header;
+ Common::String pattern = target;
+ pattern += ".???";
+
+ Common::StringList filenames;
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ saveList.push_back(SaveStateDescriptor(slotNum, header.description));
+ }
+ delete in;
+ }
+ }
+ }
+
+ return saveList;
+}
+
+int ToltecsMetaEngine::getMaximumSaveSlot() const {
+ return 999;
+}
+
+void ToltecsMetaEngine::removeSaveState(const char *target, int slot) const {
+ // Slot 0 can't be deleted, it's for restarting the game(s)
+ if (slot == 0)
+ return;
+
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::String filename = Toltecs::ToltecsEngine::getSavegameFilename(target, slot);
+
+ saveFileMan->removeSavefile(filename.c_str());
+
+ Common::StringList filenames;
+ Common::String pattern = target;
+ pattern += ".???";
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+
+ // Rename every slot greater than the deleted slot,
+ // Also do not rename quicksaves.
+ if (slotNum > slot && slotNum < 990) {
+ // FIXME: Our savefile renaming done here is inconsitent with what we do in
+ // GUI_v2::deleteMenu. While here we rename every slot with a greater equal
+ // number of the deleted slot to deleted slot, deleted slot + 1 etc.,
+ // we only rename the following slots in GUI_v2::deleteMenu until a slot
+ // is missing.
+ saveFileMan->renameSavefile(file->c_str(), filename.c_str());
+
+ filename = Toltecs::ToltecsEngine::getSavegameFilename(target, ++slot);
+ }
+ }
+
+}
+
+SaveStateDescriptor ToltecsMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Toltecs::ToltecsEngine::getSavegameFilename(target, slot);
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
+
+ if (in) {
+ Toltecs::ToltecsEngine::SaveHeader header;
+ Toltecs::ToltecsEngine::kReadSaveHeaderError error;
+
+ error = Toltecs::ToltecsEngine::readSaveHeader(in, true, header);
+ delete in;
+
+ if (error == Toltecs::ToltecsEngine::kRSHENoError) {
+ SaveStateDescriptor desc(slot, header.description);
+
+ desc.setDeletableFlag(false);
+ desc.setWriteProtectedFlag(false);
+ desc.setThumbnail(header.thumbnail);
+
+ return desc;
+ }
+ }
+
+ return SaveStateDescriptor();
+}
+
#if PLUGIN_ENABLED_DYNAMIC(TOLTECS)
REGISTER_PLUGIN_DYNAMIC(TOLTECS, PLUGIN_TYPE_ENGINE, ToltecsMetaEngine);
#else
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 2813c0e..9cbcbb2 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -52,6 +52,8 @@ void MoviePlayer::playMovie(uint resIndex) {
uint32 subtitleSlot;
byte moviePalette[768];
+ _vm->_isSaveAllowed = false;
+
memset(moviePalette, 0, sizeof(moviePalette));
_vm->_screen->finishTalkTextItems();
@@ -176,6 +178,8 @@ void MoviePlayer::playMovie(uint resIndex) {
debug(0, "playMovie() done");
+ _vm->_isSaveAllowed = true;
+
}
void MoviePlayer::fetchAudioChunks() {
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index b631b1d..da62da4 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -30,6 +30,8 @@
#include "base/plugins.h"
#include "base/version.h"
+#include "graphics/thumbnail.h"
+
#include "sound/mixer.h"
#include "toltecs/toltecs.h"
@@ -44,14 +46,43 @@ namespace Toltecs {
/* TODO:
- Saveload is working so far but only one slot is supported until the game menu is implemented
- - Save with F6; Load with F9
+ - Save with F7; Load with F9
- Saving during an animation (AnimationPlayer) is not working correctly yet
- Maybe switch to SCUMM/Tinsel serialization approach?
*/
#define SAVEGAME_VERSION 0 // 0 is dev version until in official SVN
-void ToltecsEngine::savegame(const char *filename) {
+ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+
+ header.version = in->readUint32LE();
+ if (header.version != SAVEGAME_VERSION)
+ return kRSHEInvalidVersion;
+
+ byte descriptionLen = in->readByte();
+ header.description = "";
+ while (descriptionLen--)
+ header.description += (char)in->readByte();
+
+ if (loadThumbnail) {
+ header.thumbnail = new Graphics::Surface();
+ assert(header.thumbnail);
+ if (!Graphics::loadThumbnail(*in, *header.thumbnail)) {
+ delete header.thumbnail;
+ header.thumbnail = 0;
+ }
+ } else {
+ Graphics::skipThumbnailHeader(*in);
+ }
+
+ // Not used yet, reserved for future usage
+ header.gameID = in->readByte();
+ header.flags = in->readUint32LE();
+
+ return (in->ioFailed() ? kRSHEIoError : kRSHENoError);
+}
+
+void ToltecsEngine::savegame(const char *filename, const char *description) {
Common::OutSaveFile *out;
if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
@@ -61,6 +92,16 @@ void ToltecsEngine::savegame(const char *filename) {
out->writeUint32LE(SAVEGAME_VERSION);
+ byte descriptionLen = strlen(description);
+ out->writeByte(descriptionLen);
+ out->write(description, descriptionLen);
+
+ Graphics::saveThumbnail(*out);
+
+ // Not used yet, reserved for future usage
+ out->writeByte(0);
+ out->writeUint32LE(0);
+
out->writeUint16LE(_cameraX);
out->writeUint16LE(_cameraY);
out->writeUint16LE(_cameraHeight);
@@ -99,10 +140,14 @@ void ToltecsEngine::loadgame(const char *filename) {
warning("Can't open file '%s', game not loaded", filename);
return;
}
+
+ SaveHeader header;
+
+ kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
- uint32 version = in->readUint32LE();
- if (version != SAVEGAME_VERSION) {
- warning("Savegame '%s' too old, game not loaded (got v%d, need v%d)", filename, version, SAVEGAME_VERSION);
+ if (errorCode != kRSHENoError) {
+ warning("Error loading savegame '%s'", filename);
+ delete in;
return;
}
@@ -145,4 +190,29 @@ void ToltecsEngine::loadgame(const char *filename) {
}
+Common::Error ToltecsEngine::loadGameState(int slot) {
+ const char *fileName = getSavegameFilename(slot);
+ loadgame(fileName);
+}
+
+Common::Error ToltecsEngine::saveGameState(int slot, const char *description) {
+ const char *fileName = getSavegameFilename(slot);
+ savegame(fileName, description);
+}
+
+const char *ToltecsEngine::getSavegameFilename(int num) {
+ static Common::String filename;
+ filename = getSavegameFilename(_targetName, num);
+ return filename.c_str();
+}
+
+Common::String ToltecsEngine::getSavegameFilename(const Common::String &target, int num) {
+ assert(num >= 0 && num <= 999);
+
+ char extension[5];
+ sprintf(extension, "%03d", num);
+
+ return target + "." + extension;
+}
+
} // End of namespace Toltecs
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 4691d23..6e65999 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -79,16 +79,28 @@ ToltecsEngine::~ToltecsEngine() {
delete _rnd;
}
-int ToltecsEngine::init() {
+Common::Error ToltecsEngine::init() {
// Initialize backend
_system->beginGFXTransaction();
initCommonGFX(true);
_system->initSize(640, 400);
_system->endGFXTransaction();
- return 0;
+ return Common::kNoError;
}
-int ToltecsEngine::go() {
+void ToltecsEngine::syncSoundSettings() {
+ /*
+ _music->setVolume(ConfMan.getInt("music_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+ */
+}
+
+Common::Error ToltecsEngine::go() {
+
+ _isSaveAllowed = true;
_quitGame = false;
_counter01 = 0;
@@ -140,16 +152,6 @@ int ToltecsEngine::go() {
_system->showMouse(true);
-//#define TEST_MOVIE
-#ifdef TEST_MOVIE
- _screen->registerFont(0, 0x0D);
- _screen->registerFont(1, 0x0E);
- //_moviePlayer->playMovie(0x000012D8);
- //_moviePlayer->playMovie(0x000012D7);
- //_moviePlayer->playMovie(0x);
- _moviePlayer->playMovie(0x000012E0);
-#endif
-
//#define TEST_MENU
#ifdef TEST_MENU
_screen->registerFont(0, 0x0D);
@@ -183,7 +185,7 @@ int ToltecsEngine::go() {
delete _sound;
- return 0;
+ return Common::kNoError;
}
void ToltecsEngine::loadScene(uint resIndex) {
@@ -259,7 +261,7 @@ void ToltecsEngine::updateInput() {
// FIXME: This is just for debugging
switch (event.kbd.keycode) {
case Common::KEYCODE_F7:
- savegame("toltecs.001");
+ savegame("toltecs.001", "Quicksave");
break;
case Common::KEYCODE_F9:
loadgame("toltecs.001");
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index b9d08c3..0794a26 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -43,10 +43,6 @@
namespace Toltecs {
-enum ToltecsGameFeatures {
- GF_PACKED = (1 << 0)
-};
-
struct ToltecsGameDescription;
class AnimationPlayer;
@@ -65,14 +61,17 @@ class ToltecsEngine : public ::Engine {
Common::KeyState _keyPressed;
protected:
- int init();
- int go();
+ Common::Error init();
+ Common::Error go();
// void shutdown();
public:
ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDesc);
virtual ~ToltecsEngine();
+ virtual bool hasFeature(EngineFeature f) const;
+ virtual void syncSoundSettings();
+
Common::RandomSource *_rnd;
const ToltecsGameDescription *_gameDescription;
uint32 getFeatures() const;
@@ -99,10 +98,8 @@ public:
int16 findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize);
- void savegame(const char *filename);
- void loadgame(const char *filename);
-
public:
+
AnimationPlayer *_anim;
ArchiveReader *_arc;
Input *_input;
@@ -140,6 +137,37 @@ public:
int16 _mouseDisabled;
bool _leftButtonDown, _rightButtonDown;
+ /* Save/load */
+
+ enum kReadSaveHeaderError {
+ kRSHENoError = 0,
+ kRSHEInvalidType = 1,
+ kRSHEInvalidVersion = 2,
+ kRSHEIoError = 3
+ };
+
+ struct SaveHeader {
+ Common::String description;
+ uint32 version;
+ byte gameID;
+ uint32 flags;
+ Graphics::Surface *thumbnail;
+ };
+
+ bool _isSaveAllowed;
+
+ bool canLoadGameStateCurrently() { return _isSaveAllowed; }
+ bool canSaveGameStateCurrently() { return _isSaveAllowed; }
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameState(int slot, const char *description);
+ void savegame(const char *filename, const char *description);
+ void loadgame(const char *filename);
+
+ const char *getSavegameFilename(int num);
+ static Common::String getSavegameFilename(const Common::String &target, int num);
+
+ static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
+
};
} // End of namespace Toltecs
Commit: ec6f0d23a7bb502cd1fa5eef96340189fc64d8b4
https://github.com/scummvm/scummvm/commit/ec6f0d23a7bb502cd1fa5eef96340189fc64d8b4
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Very very minor cleanup.
Changed paths:
engines/toltecs/sound.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index a3e7a76..cb7b234 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -122,7 +122,6 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
}
// Play new sound in empty channel
-
int freeChannel = -1;
for (int i = 0; i < 4; i++) {
if (channels[i].type == 0) {
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 6e65999..b903107 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -398,14 +398,12 @@ void ToltecsEngine::scrollCameraRight(int16 delta) {
void ToltecsEngine::updateCamera() {
if (_cameraX != _newCameraX) {
- //dirtyFullRefresh = -1;
_cameraX = _newCameraX;
_screen->_fullRefresh = true;
_screen->finishTalkTextItems();
}
if (_cameraY != _newCameraY) {
- //dirtyFullRefresh = -1;
_cameraY = _newCameraY;
_screen->_fullRefresh = true;
_screen->finishTalkTextItems();
Commit: 1f4764ad1c6a4ef2d4c2a2697572f692957bbc02
https://github.com/scummvm/scummvm/commit/1f4764ad1c6a4ef2d4c2a2697572f692957bbc02
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: - Implemented RTL
- Fixed return values in savegame/loadgame
- Some minor cleanup
Changed paths:
engines/toltecs/detection.cpp
engines/toltecs/movie.cpp
engines/toltecs/saveload.cpp
engines/toltecs/screen.cpp
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 9128ce5..9db6155 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -134,7 +134,7 @@ bool ToltecsMetaEngine::hasFeature(MetaEngineFeature f) const {
bool Toltecs::ToltecsEngine::hasFeature(EngineFeature f) const {
return
-// (f == kSupportsRTL) ||
+ (f == kSupportsRTL) ||
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime);
}
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 9cbcbb2..28402c9 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -254,15 +254,18 @@ bool MoviePlayer::handleInput() {
if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
return false;
break;
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_RBUTTONDOWN:
+ return false;
case Common::EVENT_QUIT:
- g_system->quit();
+ _vm->quitGame();
return false;
break;
default:
break;
}
}
- return true;
+ return !_vm->shouldQuit();
}
} // End of namespace Toltecs
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index da62da4..d758fa7 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -193,11 +193,13 @@ void ToltecsEngine::loadgame(const char *filename) {
Common::Error ToltecsEngine::loadGameState(int slot) {
const char *fileName = getSavegameFilename(slot);
loadgame(fileName);
+ return Common::kNoError;
}
Common::Error ToltecsEngine::saveGameState(int slot, const char *description) {
const char *fileName = getSavegameFilename(slot);
savegame(fileName, description);
+ return Common::kNoError;
}
const char *ToltecsEngine::getSavegameFilename(int num) {
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index d70cda3..363a6f2 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -125,7 +125,6 @@ void Screen::loadMouseCursor(uint resIndex) {
*mouseCursorP++ = pixel;
}
}
- //CursorMan.replaceCursor((const byte*)mouseCursor, 16, 16, 0, 0, 0);
// FIXME: Where's the cursor hotspot? Using 8, 8 seems good enough for now.
CursorMan.replaceCursor((const byte*)mouseCursor, 16, 16, 8, 8, 0);
}
@@ -540,7 +539,7 @@ void Screen::drawGuiTextMulti(byte *textData) {
wrapState.sourceString += 4;
} else if (*wrapState.sourceString == 0x0B) {
// Inc text position
- y += wrapState.sourceString[1]; // CHECKME: Maybe these are signed?
+ y += wrapState.sourceString[1];
x += wrapState.sourceString[2];
wrapState.sourceString += 3;
} else {
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 18942ec..a278ad5 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -96,7 +96,7 @@ void ScriptInterpreter::runScript(uint slotIndex) {
_code = getSlotData(_regs.reg4);
- while (1) {
+ while (!_vm->shouldQuit()) {
if (_vm->_movieSceneFlag)
_vm->_mouseButton = 0;
@@ -124,7 +124,7 @@ void ScriptInterpreter::runScript(uint slotIndex) {
// Call updateScreen roughly every 10ms else the mouse cursor will be jerky
if (_vm->_system->getMillis() % 10 == 0)
_vm->_system->updateScreen();
-
+
}
}
@@ -451,7 +451,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
_vm->_screen->updateShakeScreen();
- if (_vm->_quitGame)
+ if (_vm->shouldQuit())
return;
if (!_vm->_movieSceneFlag)
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index b903107..c7ec3ca 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -102,7 +102,6 @@ Common::Error ToltecsEngine::go() {
_isSaveAllowed = true;
- _quitGame = false;
_counter01 = 0;
_counter02 = 0;
_movieSceneFlag = false;
@@ -248,6 +247,7 @@ void ToltecsEngine::updateScreen() {
_system->updateScreen();
updateCamera();
+
}
void ToltecsEngine::updateInput() {
@@ -272,8 +272,7 @@ void ToltecsEngine::updateInput() {
break;
case Common::EVENT_QUIT:
- // FIXME: Find a nicer way to quit
- _system->quit();
+ quitGame();
break;
case Common::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
@@ -338,6 +337,7 @@ void ToltecsEngine::setGuiHeight(int16 guiHeight) {
if (guiHeight != _guiHeight) {
_guiHeight = guiHeight;
_cameraHeight = 400 - _guiHeight;
+ _screen->_guiRefresh = true;
debug(0, "ToltecsEngine::setGuiHeight() _guiHeight = %d; _cameraHeight = %d", _guiHeight, _cameraHeight);
// TODO: clearScreen();
}
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 0794a26..1992d9d 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -115,7 +115,6 @@ public:
uint _sceneResIndex;
int16 _sceneWidth, _sceneHeight;
- bool _quitGame;
int _counter01, _counter02;
bool _movieSceneFlag;
byte _flag01;
Commit: 46257f7bb47938e02382d4ddc2670ed6904e7914
https://github.com/scummvm/scummvm/commit/46257f7bb47938e02382d4ddc2670ed6904e7914
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Silenced MSVC warnings
Changed paths:
engines/toltecs/palette.cpp
engines/toltecs/screen.cpp
engines/toltecs/script.cpp
engines/toltecs/segmap.cpp
engines/toltecs/sprite.cpp
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 4d0f13f..23ce3d8 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -157,7 +157,7 @@ void Palette::buildColorTransTable(byte limit, char deltaValue, byte mask) {
// TODO
- byte r, g, b;
+ byte r = 0, g = 0, b = 0;
mask &= 7;
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 363a6f2..47c852d 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -293,7 +293,7 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
}
GuiTextWrapState wrapState;
- int16 len;
+ int16 len = 0;
wrapState.width = 0;
wrapState.destString = wrapState.textBuffer;
wrapState.len1 = 0;
@@ -310,7 +310,7 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
}
if (_verbLineCount != 1) {
- int16 charWidth;
+ int16 charWidth = 0;
if (*wrapState.sourceString < 0xF0) {
while (*wrapState.sourceString > 0x20 && *wrapState.sourceString < 0xF0 && len > 0) {
byte ch = *wrapState.sourceString--;
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index a278ad5..2433a1a 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -433,7 +433,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
{
debug(0, "o2_setGameVar(%d, %d)", arg16(3), arg16(5));
VarType varType = getGameVarType(arg16(3));
- int16 value;
+ int16 value = 0;
if (varType == vtByte)
value = arg8(5);
else if (varType == vtWord)
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index ec9d021..4647f79 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -158,7 +158,7 @@ void SegmentMap::adjustPathPoint(int16 &x, int16 &y) {
return;
uint32 minDistance = 0xFFFFFFFF, distance;
- int16 adjustedX, adjustedY, x2, y2;
+ int16 adjustedX = 0, adjustedY = 0, x2, y2;
for (int16 rectIndex = 0; rectIndex < (int16)_pathRects.size(); rectIndex++) {
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index 4e5af5f..264216d 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -103,7 +103,7 @@ public:
_scalerStatus = 0;
}
SpriteReaderStatus readPacket(PixelPacket &packet) {
- SpriteReaderStatus status;
+ SpriteReaderStatus status = kSrsPixelsLeft;
if (_scalerStatus == 0) {
_xerror = _sprite->xdelta;
_yerror -= 100;
Commit: 2eb6482b0690e4413b20f216727675dca2a43ebf
https://github.com/scummvm/scummvm/commit/2eb6482b0690e4413b20f216727675dca2a43ebf
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: - Fixed compilation after Fingolfin's latest series of commits
- Added a warning for the yet unimplemented palette transparency code
- Removed "debug" calls from script, they weren't that useful
- Removed unneccessary delete in the MoviePlayer
- Fixed the renderer (hopefully?)
Changed paths:
engines/toltecs/detection.cpp
engines/toltecs/movie.cpp
engines/toltecs/palette.cpp
engines/toltecs/render.cpp
engines/toltecs/script.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 9db6155..5180a07 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -23,7 +23,7 @@
#include "base/plugins.h"
-#include "common/advancedDetector.h"
+#include "engines/advancedDetector.h"
#include "common/file.h"
#include "toltecs/toltecs.h"
@@ -32,7 +32,7 @@
namespace Toltecs {
struct ToltecsGameDescription {
- Common::ADGameDescription desc;
+ ADGameDescription desc;
};
uint32 ToltecsEngine::getFeatures() const {
@@ -63,7 +63,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
AD_ENTRY1s("WESTERN", "05472037e9cfde146e953c434e74f0f4", 337643527),
Common::EN_ANY,
Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
+ ADGF_NO_FLAGS
},
},
@@ -75,7 +75,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
AD_ENTRY1s("WESTERN", "ba1742d3193b68ceb9434e2ab7a09a9b", 391462783),
Common::RU_RUS,
Common::kPlatformPC,
- Common::ADGF_NO_FLAGS
+ ADGF_NO_FLAGS
},
},
@@ -84,7 +84,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
} // End of namespace Toltecs
-static const Common::ADParams detectionParams = {
+static const ADParams detectionParams = {
// Pointer to ADGameDescription or its superset structure
(const byte *)Toltecs::gameDescriptions,
// Size of that superset structure
@@ -103,9 +103,9 @@ static const Common::ADParams detectionParams = {
0
};
-class ToltecsMetaEngine : public Common::AdvancedMetaEngine {
+class ToltecsMetaEngine : public AdvancedMetaEngine {
public:
- ToltecsMetaEngine() : Common::AdvancedMetaEngine(detectionParams) {}
+ ToltecsMetaEngine() : AdvancedMetaEngine(detectionParams) {}
virtual const char *getName() const {
return "Toltecs Engine";
@@ -116,7 +116,7 @@ public:
}
virtual bool hasFeature(MetaEngineFeature f) const;
- virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
SaveStateList listSaves(const char *target) const;
virtual int getMaximumSaveSlot() const;
void removeSaveState(const char *target, int slot) const;
@@ -139,7 +139,7 @@ bool Toltecs::ToltecsEngine::hasFeature(EngineFeature f) const {
(f == kSupportsSavingDuringRuntime);
}
-bool ToltecsMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
+bool ToltecsMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
const Toltecs::ToltecsGameDescription *gd = (const Toltecs::ToltecsGameDescription *)desc;
if (gd) {
*engine = new Toltecs::ToltecsEngine(syst, gd);
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 28402c9..eedf496 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -201,7 +201,6 @@ void MoviePlayer::fetchAudioChunks() {
chunkBuffer = NULL;
prefetchChunkCount++;
_soundChunkFramesLeft += _framesPerSoundChunk;
- delete[] chunkBuffer;
} else {
_vm->_arc->seek(chunkSize, SEEK_CUR);
}
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 23ce3d8..0d5faec 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -165,6 +165,7 @@ void Palette::buildColorTransTable(byte limit, char deltaValue, byte mask) {
if (deltaValue < 0) {
// TODO
+ warning("Palette::buildColorTransTable(%d, %d, %02X) not yet implemented!", limit, deltaValue, mask);
} else {
r = _mainPalette[i * 3 + 0];
g = _mainPalette[i * 3 + 1];
diff --git a/engines/toltecs/render.cpp b/engines/toltecs/render.cpp
index dd7dfc2..4ffb9f6 100644
--- a/engines/toltecs/render.cpp
+++ b/engines/toltecs/render.cpp
@@ -174,7 +174,7 @@ void RenderQueue::update() {
for (RenderQueueArray::iterator iter = _currQueue->begin(); iter != _currQueue->end(); iter++) {
const RenderQueueItem *item = &(*iter);
- if (item->flags == kRefresh) {
+ if (item->flags == kRefresh || doFullRefresh) {
switch (item->type) {
case kSprite:
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 2433a1a..0596402 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -168,36 +168,29 @@ void ScriptInterpreter::execOpcode(byte opcode) {
case 1:
// ok
_regs.reg0 = readInt16();
- debug(1, "mov reg0, #%d", _regs.reg0);
break;
case 2:
// ok
_regs.reg1 = readInt16();
- debug(1, "mov reg1, #%d", _regs.reg1);
break;
case 3:
// ok
_regs.reg3 = readInt16();
- debug(1, "mov reg3, #%d", _regs.reg3);
break;
case 4:
// ok
_regs.reg5 = _regs.reg0;
- debug(1, "mov reg5, reg0");
break;
case 5:
// ok
_regs.reg3 = _regs.reg0;
- debug(1, "mov reg3, reg0");
break;
case 6:
// ok
_regs.reg1 = _regs.reg0;
- debug(1, "mov reg1, reg0");
break;
case 7:
_regs.reg1 = localRead16(_regs.reg3);
- debug(1, "mov reg1, *%d", _regs.reg3);
break;
case 8:
localWrite16(_regs.reg3, _regs.reg0);
@@ -279,19 +272,15 @@ void ScriptInterpreter::execOpcode(byte opcode) {
break;
case 34:
pushInt16(_regs.reg0);
- debug(1, "pushw reg0");
break;
case 35:
pushInt16(_regs.reg1);
- debug(1, "pushw reg1");
break;
case 36:
_regs.reg1 = popInt16();
- debug(1, "popw reg1");
break;
case 37:
_regs.reg0 = popInt16();
- debug(1, "popw reg0");
break;
case 38:
_regs.reg2 = -_regs.reg2;
@@ -313,23 +302,19 @@ void ScriptInterpreter::execOpcode(byte opcode) {
_cmpBitTest = true;
break;
case 43:
- debug(1, "retn (slot: %d; ofs: %04X)\n", _regs.reg4, _regs.reg0);
_code = getSlotData(_regs.reg4) + _regs.reg0;
break;
case 44:
- debug(1, "retf (slot: %d; ofs: %04X)\n", _regs.reg5, _regs.reg0);
_code = getSlotData(_regs.reg5) + _regs.reg0;
_regs.reg4 = _regs.reg5;
_switchLocalDataNear = true;
break;
case 45:
- debug(1, "callnear %04X (slot: %d; ofs: %04X)\n", _regs.reg0, _regs.reg4, _regs.reg0);
pushInt16(_code - getSlotData(_regs.reg4));
pushInt16(_regs.reg4);
_code = getSlotData(_regs.reg4) + _regs.reg0;
break;
case 46:
- debug(1, "callfar %04X (slot: %d; ofs: %04X)\n", _regs.reg0, _regs.reg5, _regs.reg0);
pushInt16(_code - getSlotData(_regs.reg4));
pushInt16(_regs.reg4);
_code = getSlotData(_regs.reg5) + _regs.reg0;
@@ -340,16 +325,12 @@ void ScriptInterpreter::execOpcode(byte opcode) {
_regs.reg4 = popInt16();
ofs = popInt16();
_code = getSlotData(_regs.reg4) + ofs;
- debug(1, "ret (slot: %d; ofs: %04X)\n", _regs.reg4, ofs);
- //_code = getSlotData(_regs.reg4) + popInt16();
_switchLocalDataNear = true;
break;
case 48:
_regs.reg4 = popInt16();
ofs = popInt16();
_code = getSlotData(_regs.reg4) + ofs;
- debug(1, "retsp (slot: %d; ofs: %04X)\n", _regs.reg4, ofs);
- //_code = getSlotData(_regs.reg4) + popInt16();
_regs.sp += _regs.reg0;
_switchLocalDataNear = true;
break;
@@ -400,15 +381,8 @@ void ScriptInterpreter::execOpcode(byte opcode) {
_code++;
break;
default:
- {
- /*
- FILE *ex = fopen("error.0", "wb");
- fwrite(_code - 8, 4096, 1, ex);
- fclose(ex);
- */
error("Invalid opcode %d", opcode);
}
- }
}
@@ -612,6 +586,7 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 23:// ok
{
debug(0, "o2_findMouseInRectIndex1(offset: %d; slot: %d; elemSize: %d; var: %d; index: %d)", arg16(3), arg16(5), arg16(7), arg16(9), arg16(11));
+
int16 index = -1;
if (_vm->_mouseY < _vm->_cameraHeight) {
index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
@@ -625,19 +600,11 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
case 24:// ok
{
+
debug(0, "o2_findMouseInRectIndex2(offset: %d, slot: %d, elemSize: %d, var: %d)", arg16(3), arg16(5), arg16(7), arg16(9));
int16 index = -1;
- debug(0, "_vm->_mouseDisabled = %d", _vm->_mouseDisabled);
-
- /* FIXME: This opcode is called after the Revistronic logo at the beginning,
- but at the slot/offset there's bytecode and not a rect array as expected.
- To avoid crashes we skip searching the rectangle index for now when scene 215 is active.
- I don't know yet whether this is a bug in the original engine as well or just here.
- Needs some more checking.
- Annoyingly scene 215 is the map which becomes unusable with this hack.
- */
- if (_vm->_sceneResIndex != 215) {
+ if (_vm->_sceneResIndex != 0) {
if (_vm->_mouseY < _vm->_cameraHeight) {
index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
_vm->_mouseX + _vm->_cameraX,
@@ -645,9 +612,9 @@ void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
0, arg16(7));
}
}
-
+
localWrite16(arg16(9), index);
-
+
break;
}
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 1992d9d..c3c538b 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -114,12 +114,11 @@ public:
uint _sceneResIndex;
int16 _sceneWidth, _sceneHeight;
-
+
int _counter01, _counter02;
bool _movieSceneFlag;
byte _flag01;
- // TODO: Move camera stuff into own Scene class
int16 _cameraX, _cameraY;
int16 _newCameraX, _newCameraY;
int16 _cameraHeight;
Commit: 2156fecf534284323ee205e748eb92543b785eb2
https://github.com/scummvm/scummvm/commit/2156fecf534284323ee205e748eb92543b785eb2
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Added German version
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 5180a07..4faa1d1 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -79,6 +79,18 @@ static const ToltecsGameDescription gameDescriptions[] = {
},
},
+ {
+ // 3 Skulls of the Toltecs German version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "1a3292bad8e0bb5701800c73531dd75e", 345176617),
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS
+ },
+ },
+
{ AD_TABLE_END_MARKER }
};
Commit: edefa37a45c2ae518847da0cbad6352745e30f5a
https://github.com/scummvm/scummvm/commit/edefa37a45c2ae518847da0cbad6352745e30f5a
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Fixed compilation
Changed paths:
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index c7ec3ca..40b2388 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -79,15 +79,6 @@ ToltecsEngine::~ToltecsEngine() {
delete _rnd;
}
-Common::Error ToltecsEngine::init() {
- // Initialize backend
- _system->beginGFXTransaction();
- initCommonGFX(true);
- _system->initSize(640, 400);
- _system->endGFXTransaction();
- return Common::kNoError;
-}
-
void ToltecsEngine::syncSoundSettings() {
/*
_music->setVolume(ConfMan.getInt("music_volume"));
@@ -98,7 +89,12 @@ void ToltecsEngine::syncSoundSettings() {
*/
}
-Common::Error ToltecsEngine::go() {
+Common::Error ToltecsEngine::run() {
+ // Initialize backend
+ _system->beginGFXTransaction();
+ initCommonGFX(true);
+ _system->initSize(640, 400);
+ _system->endGFXTransaction();
_isSaveAllowed = true;
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index c3c538b..7b7e1a3 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -61,8 +61,7 @@ class ToltecsEngine : public ::Engine {
Common::KeyState _keyPressed;
protected:
- Common::Error init();
- Common::Error go();
+ Common::Error run();
// void shutdown();
public:
Commit: b9de8beb6e3263e8bba5414bb8dc357e0544ee77
https://github.com/scummvm/scummvm/commit/b9de8beb6e3263e8bba5414bb8dc357e0544ee77
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Fixed compilation
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 4faa1d1..f92ba29 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -123,7 +123,7 @@ public:
return "Toltecs Engine";
}
- virtual const char *getCopyright() const {
+ virtual const char *getOriginalCopyright() const {
return "Toltecs Engine (C) 1996";
}
Commit: 5c481dd1167fd5d186509837eb71fd33e8bf8902
https://github.com/scummvm/scummvm/commit/5c481dd1167fd5d186509837eb71fd33e8bf8902
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: - Removed TODO, external resources aren't explicitly used (the original game extracts resources from WESTERN to HD to increase access speed)
Changed paths:
engines/toltecs/resource.h
diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h
index b4d21c3..ee1eb21 100644
--- a/engines/toltecs/resource.h
+++ b/engines/toltecs/resource.h
@@ -44,14 +44,6 @@
namespace Toltecs {
-/*
- TODO:
-
- ArchiveReader:
- - Add support for external resources; and check if they're used
-
-*/
-
const uint kMaxCacheItems = 1024;
const uint kMaxCacheSize = 8 * 1024 * 1024; // 8 MB
Commit: 170b66b2cbf9c43d3bfe5e1c1a22723dba51f565
https://github.com/scummvm/scummvm/commit/170b66b2cbf9c43d3bfe5e1c1a22723dba51f565
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Updated TODO (nothing new, just syncing local copy with the repo)
Changed paths:
engines/toltecs/TODO.txt
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 378c1c3..62df586 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -11,7 +11,6 @@ TODO
- each resource type gets its own class, the resource cache manages the resource instances
- generic resource class which has a method that creates a MemoryReadStream
- rewrite parts of the engine to use the new resource system
-- Add movie playback functionality (movie format is known, needs implementing)
- Add sound support (after rewrite of the resource system)
- Add music support (game seems to use XMIDI, MIDI and headerless music...figure out more)
- Add game menu
@@ -26,8 +25,10 @@ BUGS
- Still some clipping issues (walking upstairs in the saloon, when on top of the tower in the hideout)
- Crashes sometimes on scene changes
(I guess because some talktext is still running although the slot used by it has changed)
+- Crashes sometimes (e.g. when inside the barn and going up the ladder)
DONE
------
- Implement dirty rectangles (low priority)
- Optimize segment mask redrawing (only redraw what's neccessary)
+- Add movie playback functionality (movie format is known, needs implementing)
Commit: 041fe21417d107dd558212ba70004d71d02e0355
https://github.com/scummvm/scummvm/commit/041fe21417d107dd558212ba70004d71d02e0355
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: - Added enum for sound channel type
- Added isPointInside
Changed paths:
engines/toltecs/segmap.cpp
engines/toltecs/segmap.h
engines/toltecs/sound.cpp
engines/toltecs/sound.h
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 4647f79..b51886f 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -341,7 +341,7 @@ void SegmentMap::findPath(int16 *pointsArray, int16 destX, int16 destY, int16 so
debug(0, "SegmentMap::findPath() count = %d", pointsArray[1]);
-#if 0 // DEBUG: Draw the path we found
+#if 1 // DEBUG: Draw the path we found
int sx = sourceX, sy = sourceY;
LineData ld;
ld.pitch = _vm->_sceneWidth;
@@ -359,10 +359,7 @@ void SegmentMap::findPath(int16 *pointsArray, int16 destX, int16 destY, int16 so
int8 SegmentMap::getScalingAtPoint(int16 x, int16 y) {
int8 scaling = 0;
for (uint i = 0; i < _infoRects.size(); i++) {
- if (_infoRects[i].id == 0 &&
- y >= _infoRects[i].y && y <= _infoRects[i].y + _infoRects[i].height &&
- x >= _infoRects[i].x && x <= _infoRects[i].x + _infoRects[i].width) {
-
+ if (_infoRects[i].id == 0 && _infoRects[i].isPointInside(x, y)) {
int8 topScaling = (int8)_infoRects[i].b;
int8 bottomScaling = (int8)_infoRects[i].c;
if (y - _infoRects[i].y > 0) {
@@ -370,6 +367,7 @@ int8 SegmentMap::getScalingAtPoint(int16 x, int16 y) {
}
}
}
+ debug(0, "SegmentMap::getScalingAtPoint(%d, %d) %d", x, y, scaling);
return scaling;
}
@@ -378,10 +376,7 @@ void SegmentMap::getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byt
g = 0;
b = 0;
for (uint i = 0; i < _infoRects.size(); i++) {
- if (_infoRects[i].id == id &&
- y >= _infoRects[i].y && y <= _infoRects[i].y + _infoRects[i].height &&
- x >= _infoRects[i].x && x <= _infoRects[i].x + _infoRects[i].width) {
-
+ if (_infoRects[i].id == id && _infoRects[i].isPointInside(x, y)) {
r = _infoRects[i].a;
g = _infoRects[i].b;
b = _infoRects[i].c;
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index 77ab247..b860efb 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -92,6 +92,9 @@ public: // for debugging purposes
int16 height, width;
byte id;
byte a, b, c;
+ inline bool isPointInside(int16 px, int16 py) {
+ return py >= y && py <= y + height && px >= x && px <= x + width;
+ }
};
struct PathPoint {
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index cb7b234..3f1be4b 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -47,7 +47,7 @@ namespace Toltecs {
Sound::Sound(ToltecsEngine *vm) : _vm(vm) {
for (int i = 0; i < 4; i++) {
- channels[i].type = 0;
+ channels[i].type = kChannelTypeEmpty;
channels[i].resIndex = -1;
}
}
@@ -61,7 +61,7 @@ void Sound::playSpeech(int16 resIndex) {
debug(0, "playSpeech(%d)", resIndex);
- internalPlaySound(resIndex, -3, 50 /*TODO*/, 64);
+ internalPlaySound(resIndex, kChannelTypeSpeech, 50 /*TODO*/, 64);
}
@@ -71,8 +71,8 @@ void Sound::playSound(int16 resIndex, int16 type, int16 volume) {
debug(0, "playSound(%d, %d, %d)", resIndex, type, volume);
- if (volume == -1 || type == -2) {
- if (type == -1) {
+ if (volume == -1 || type == kChannelTypeSfx) {
+ if (type == kChannelTypeBackground) {
internalPlaySound(resIndex, type, 50 /*TODO*/, 64);
} else {
internalPlaySound(resIndex, type, 100 /*TODO*/, 64);
@@ -102,29 +102,29 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
_vm->_mixer->stopAll();
_vm->_screen->keepTalkTextItemsAlive();
for (int i = 0; i < 4; i++) {
- channels[i].type = 0;
+ channels[i].type = kChannelTypeEmpty;
channels[i].resIndex = -1;
}
- } else if (type == -2) {
+ } else if (type == kChannelTypeSfx) {
// Stop sounds with specified resIndex
for (int i = 0; i < 4; i++) {
if (channels[i].resIndex == resIndex) {
_vm->_mixer->stopHandle(channels[i].handle);
- channels[i].type = 0;
+ channels[i].type = kChannelTypeEmpty;
channels[i].resIndex = -1;
}
}
} else {
- if (type == -3) {
- // Stop sounds with type == -3 and play new sound
+ if (type == kChannelTypeSpeech) {
+ // Stop speech and play new sound
stopSpeech();
}
// Play new sound in empty channel
int freeChannel = -1;
for (int i = 0; i < 4; i++) {
- if (channels[i].type == 0) {
+ if (channels[i].type == kChannelTypeEmpty) {
freeChannel = i;
break;
}
@@ -137,8 +137,8 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
uint32 soundSize = _vm->_res->getCurItemSize();
byte flags = Audio::Mixer::FLAG_UNSIGNED;
- // Sounds with type == -1 loop
- if (type == -1)
+ // Background sounds
+ if (type == kChannelTypeBackground)
flags |= Audio::Mixer::FLAG_LOOP;
Audio::AudioStream *stream = Audio::makeLinearInputStream(soundData, soundSize, 22050, flags, 0, 0);
@@ -156,7 +156,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
void Sound::updateSpeech() {
for (int i = 0; i < 4; i++) {
- if (channels[i].type == -3 && _vm->_mixer->isSoundHandleActive(channels[i].handle)) {
+ if (channels[i].type == kChannelTypeSpeech && _vm->_mixer->isSoundHandleActive(channels[i].handle)) {
_vm->_screen->keepTalkTextItemsAlive();
break;
}
@@ -165,10 +165,10 @@ void Sound::updateSpeech() {
void Sound::stopSpeech() {
for (int i = 0; i < 4; i++) {
- if (channels[i].type == -3) {
+ if (channels[i].type == kChannelTypeSpeech) {
_vm->_mixer->stopHandle(channels[i].handle);
_vm->_screen->keepTalkTextItemsAlive();
- channels[i].type = 0;
+ channels[i].type = kChannelTypeEmpty;
channels[i].resIndex = -1;
}
}
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
index 02f7a96..7552d85 100644
--- a/engines/toltecs/sound.h
+++ b/engines/toltecs/sound.h
@@ -48,6 +48,13 @@ namespace Toltecs {
// 0x1219
+enum SoundChannelType {
+ kChannelTypeEmpty = 0,
+ kChannelTypeBackground = -1,
+ kChannelTypeSfx = -2,
+ kChannelTypeSpeech = -3
+};
+
struct SoundChannel {
int16 resIndex;
int16 type;
@@ -56,22 +63,22 @@ struct SoundChannel {
class Sound {
public:
- Sound(ToltecsEngine *vm);
- ~Sound();
+ Sound(ToltecsEngine *vm);
+ ~Sound();
- void playSpeech(int16 resIndex);
- void playSound(int16 resIndex, int16 type, int16 volume);
+ void playSpeech(int16 resIndex);
+ void playSound(int16 resIndex, int16 type, int16 volume);
void playSoundAtPos(int16 resIndex, int16 x, int16 y);
void updateSpeech();
void stopSpeech();
protected:
- ToltecsEngine *_vm;
+ ToltecsEngine *_vm;
+
+ SoundChannel channels[4];
+
+ void internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning);
- SoundChannel channels[4];
-
- void internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning);
-
};
Commit: eab360f3e7e1d4757ec3f8d64724863b61bb0b82
https://github.com/scummvm/scummvm/commit/eab360f3e7e1d4757ec3f8d64724863b61bb0b82
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: - Moved script functions out of the switch statement and into an array
Changed paths:
engines/toltecs/TODO.txt
engines/toltecs/script.cpp
engines/toltecs/script.h
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 62df586..6cf06a4 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -11,7 +11,6 @@ TODO
- each resource type gets its own class, the resource cache manages the resource instances
- generic resource class which has a method that creates a MemoryReadStream
- rewrite parts of the engine to use the new resource system
-- Add sound support (after rewrite of the resource system)
- Add music support (game seems to use XMIDI, MIDI and headerless music...figure out more)
- Add game menu
- Rewrite from scratch with only minor stuff from the disasm since the original menu is one huge
@@ -32,3 +31,4 @@ DONE
- Implement dirty rectangles (low priority)
- Optimize segment mask redrawing (only redraw what's neccessary)
- Add movie playback functionality (movie format is known, needs implementing)
+- Add sound support (after rewrite of the resource system)
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 0596402..6d4976d 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -57,12 +57,95 @@ ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) {
_slots[kMaxScriptSlots - 1].size = 1024;
_slots[kMaxScriptSlots - 1].data = new byte[_slots[kMaxScriptSlots - 1].size];
+ setupScriptFunctions();
+
}
ScriptInterpreter::~ScriptInterpreter() {
delete[] _stack;
for (int i = 0; i < kMaxScriptSlots; i++)
delete[] _slots[i].data;
+ for (uint i = 0; i < _scriptFuncs.size(); ++i)
+ delete _scriptFuncs[i];
+}
+
+typedef Common::Functor0Mem<void, ScriptInterpreter> ScriptFunctionF;
+#define RegisterScriptFunction(x) \
+ _scriptFuncs.push_back(new ScriptFunctionF(this, &ScriptInterpreter::x)); \
+ _scriptFuncNames.push_back(#x);
+void ScriptInterpreter::setupScriptFunctions() {
+
+ RegisterScriptFunction(sfNop);
+ RegisterScriptFunction(sfNop);
+ RegisterScriptFunction(sfGetGameVar);
+ RegisterScriptFunction(sfSetGameVar);
+ RegisterScriptFunction(sfUpdateScreen);
+ RegisterScriptFunction(sfGetRandomNumber);
+ RegisterScriptFunction(sfDrawGuiTextMulti);
+ RegisterScriptFunction(sfUpdateVerbLine);
+ RegisterScriptFunction(sfSetFontColor);
+ RegisterScriptFunction(sfGetTalkTextDuration);
+ RegisterScriptFunction(sfTalk);
+ RegisterScriptFunction(sfFindPaletteFragment);
+ RegisterScriptFunction(sfClearPaletteFragments);
+ RegisterScriptFunction(sfAddPaletteFragment);
+ RegisterScriptFunction(sfSetDeltaAnimPalette);
+ RegisterScriptFunction(sfNop); // TODO
+ RegisterScriptFunction(sfBuildColorTransTable);
+ RegisterScriptFunction(sfSetDeltaMainPalette);
+ RegisterScriptFunction(sfLoadScript);
+ RegisterScriptFunction(sfRegisterFont);
+ RegisterScriptFunction(sfLoadAddPalette);
+ RegisterScriptFunction(sfLoadScene);
+ RegisterScriptFunction(sfSetGuiHeight);
+ RegisterScriptFunction(sfFindMouseInRectIndex1);
+ RegisterScriptFunction(sfFindMouseInRectIndex2);
+ RegisterScriptFunction(sfDrawGuiImage);
+ RegisterScriptFunction(sfAddAnimatedSpriteNoLoop);
+ RegisterScriptFunction(sfAddAnimatedSprite);
+ RegisterScriptFunction(sfAddStaticSprite);
+ RegisterScriptFunction(sfAddAnimatedSpriteScaled);
+ RegisterScriptFunction(sfFindPath);
+ RegisterScriptFunction(sfWalk);
+ RegisterScriptFunction(sfScrollCameraUp);
+ RegisterScriptFunction(sfScrollCameraDown);
+ RegisterScriptFunction(sfScrollCameraLeft);
+ RegisterScriptFunction(sfScrollCameraRight);
+ RegisterScriptFunction(sfScrollCameraUpEx);
+ RegisterScriptFunction(sfScrollCameraDownEx);
+ RegisterScriptFunction(sfScrollCameraLeftEx);
+ RegisterScriptFunction(sfScrollCameraRightEx);
+ RegisterScriptFunction(sfSetCamera);
+ RegisterScriptFunction(sfNop); // TODO
+ RegisterScriptFunction(sfGetRgbModifiertAtPoint);
+ RegisterScriptFunction(sfStartAnim);
+ RegisterScriptFunction(sfAnimNextFrame);
+ RegisterScriptFunction(sfNop);
+ RegisterScriptFunction(sfGetAnimFrameNumber);
+ RegisterScriptFunction(sfGetAnimStatus);
+ RegisterScriptFunction(sfStartShakeScreen);
+ RegisterScriptFunction(sfStopShakeScreen);
+ RegisterScriptFunction(sfStartSequence);
+ RegisterScriptFunction(sfEndSequence);
+ RegisterScriptFunction(sfSequenceVolumeStuff);
+ RegisterScriptFunction(sfPlaySound1);
+ RegisterScriptFunction(sfPlaySound2);
+ RegisterScriptFunction(sfClearScreen);
+ RegisterScriptFunction(sfNop);
+ RegisterScriptFunction(sfHandleInput);
+ RegisterScriptFunction(sfRunOptionsScreen);
+ RegisterScriptFunction(sfPrecacheSprites);
+ RegisterScriptFunction(sfPrecacheSounds1);
+ RegisterScriptFunction(sfDeleteAllPbfFilesByExternalArray);
+ RegisterScriptFunction(sfPrecacheSounds2);
+ RegisterScriptFunction(sfRestoreStackPtr);
+ RegisterScriptFunction(sfSaveStackPtr);
+ RegisterScriptFunction(sfPlayMovie);
+ RegisterScriptFunction(sfNop);
+
+
+
+
}
void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
@@ -141,13 +224,6 @@ int16 ScriptInterpreter::readInt16() {
void ScriptInterpreter::execOpcode(byte opcode) {
-#if 0
- char ln[256];
- snprintf(ln, 256, "\t\t\t%02X %02X %02X %02X %02X %02X %02X %02X",
- _code[0], _code[1], _code[2], _code[3], _code[4], _code[5], _code[6], _code[7]);
- debug(1, "%s", ln);
-#endif
-
int16 ofs;
debug(1, "opcode = %d", opcode);
@@ -159,9 +235,9 @@ void ScriptInterpreter::execOpcode(byte opcode) {
_subCode = _code;
byte length = readByte();
debug(1, "length = %d", length);
- uint16 kernelOpcode = readInt16();
- debug(1, "callKernel %d", kernelOpcode);
- execKernelOpcode(kernelOpcode);
+ uint16 index = readInt16();
+ debug(1, "callScriptFunction %d", index);
+ execScriptFunction(index);
_code += length - 2;
break;
}
@@ -386,520 +462,12 @@ void ScriptInterpreter::execOpcode(byte opcode) {
}
-void ScriptInterpreter::execKernelOpcode(uint16 kernelOpcode) {
-
- switch (kernelOpcode) {
-
- case 0:
- case 1:
- // ok, NOPs
- break;
-
- case 2:// ok
- {
- debug(0, "o2_getGameVar(%d, %d)", arg16(3), arg16(5));
- int16 value = getGameVar(arg16(3));
- localWrite16(arg16(5), value);
- break;
- }
-
- case 3:// ok
- {
- debug(0, "o2_setGameVar(%d, %d)", arg16(3), arg16(5));
- VarType varType = getGameVarType(arg16(3));
- int16 value = 0;
- if (varType == vtByte)
- value = arg8(5);
- else if (varType == vtWord)
- value = arg16(5);
- setGameVar(arg16(3), value);
- break;
- }
-
- case 4:
- {
-
- debug(0, "o2_updateScreen()");
-
- _vm->_sound->updateSpeech();
-
- _vm->_screen->updateShakeScreen();
-
- if (_vm->shouldQuit())
- return;
-
- if (!_vm->_movieSceneFlag)
- _vm->updateInput();
- else
- _vm->_mouseButton = 0;
-
- // TODO? Check keyb
-
- _vm->_counter01--;
- if (_vm->_counter01 <= 0) {
- _vm->_counter01 = MIN(_vm->_counter02, 30);
- _vm->_counter02 = 0;
- _vm->updateScreen();
- _vm->_flag01 = 1;
- _vm->_system->delayMillis(5);
- _vm->_counter02 = 1; // ?
- } else {
- _vm->_screen->clearSprites();
- _vm->_flag01 = 0;
- //_vm->_system->updateScreen();
- }
-
- // TODO
- break;
-
- }
-
- case 5:// ok
- {
- debug(0, "o2_getRandomNumber(%d)", arg16(3));
- localWrite16(arg16(5), _vm->_rnd->getRandomNumber(arg16(3) - 1));
- break;
- }
-
- case 6:// ok
- {
- debug(0, "o2_drawGuiTextMulti()");
- _vm->_screen->drawGuiTextMulti((byte*)localPtr(arg16(3)));
- break;
- }
-
- case 7:// ok
- {
- debug(0, "o2_updateVerbLine(slot: %d; offset: %04X)", arg16(5), arg16(3));
- _vm->_screen->updateVerbLine(arg16(5), arg16(3));
- break;
- }
-
- case 8:// ok
- {
- debug(0, "o2_setFontColor(%d)", arg8(3));
- _vm->_screen->_fontColor1 = 0;
- _vm->_screen->_fontColor2 = arg8(3);
- break;
- }
-
- case 9:// ok
- {
- debug(0, "o2_getTalkTextDuration()");
- int16 duration = _vm->_screen->getTalkTextDuration();
- localWrite16(arg16(3), duration);
- break;
- }
-
- case 10:// ok
- {
- debug(0, "o2_talk(slot: %d; offset: %d)", arg16(5), arg16(3));
- _vm->talk(arg16(5), arg16(3));
- break;
- }
-
- case 11:// ok
- {
- debug(0, "o2_findFragment(%d, %d)", arg16(3), arg16(5));
- localWrite16(arg16(5), _vm->_palette->findFragment(arg16(3)));
- break;
- }
-
- case 12:// ok
- {
- debug(0, "o2_clearPaletteFragments()");
- _vm->_palette->clearFragments();
- break;
- }
-
- case 13:// ok
- {
- debug(0, "o2_addFragment(%d, %d)", arg16(3), arg16(5));
- _vm->_palette->addFragment(arg16(3), arg16(5));
- break;
- }
-
- case 14:// ok
- {
- debug(0, "o2_setDeltaPalette(animPalette, %d, %d, %d, %d)", arg8(6), arg8(5), arg8(4), arg8(3));
- _vm->_palette->setDeltaPalette(_vm->_palette->getAnimPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
- break;
- }
-
- case 16:// ok
- {
- debug(0, "o2_buildColorTransTable(%d, %d, %d)", arg8(4), (char)arg8(3), arg8(5));
- _vm->_palette->buildColorTransTable(arg8(4), (char)arg8(3), arg8(5));
- break;
- }
-
- case 17:// ok
- {
- debug(0, "o2_setDeltaPalette(mainPalette, %d, %d, %d, %d)", arg8(6), arg8(5), arg8(4), arg8(3));
- _vm->_palette->setDeltaPalette(_vm->_palette->getMainPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
- break;
- }
-
- case 18:// ok
- {
- debug(0, "o2_loadScript(resIndex: %d; slotIndex: %d)", arg16(4), arg8(3));
- int16 codeOfs = _code - getSlotData(_regs.reg4);
- loadScript(arg16(4), arg8(3));
- _code = getSlotData(_regs.reg4) + codeOfs;
- _switchLocalDataNear = true;
- break;
- }
-
- case 19:// ok
- {
- debug(0, "o2_registerFont(%d, %d)", arg8(3), arg16(4));
- _vm->_screen->registerFont(arg8(3), arg16(4));
- break;
- }
-
- case 20:// ok
- {
- debug(0, "o2_loadAddPalette(startIndex: %d; resIndex: %d)", arg8(3), arg16(4));
- _vm->_palette->loadAddPalette(arg16(4), arg8(3));
- break;
- }
-
- case 21:// TODO
- {
- debug(0, "o2_loadScene(resIndex: %d; flag: %d)", arg16(4), arg8(3));
- if (arg8(3) == 0) {
- _vm->_sound->stopSpeech();
- _vm->loadScene(arg16(4));
- } else {
- _vm->_screen->loadMouseCursor(arg16(4));
- }
- break;
- }
-
- case 22:// ok
- {
- debug(0, "o2_setGuiHeight(%d)", arg8(3));
- _vm->setGuiHeight(arg8(3));
- break;
- }
-
- case 23:// ok
- {
- debug(0, "o2_findMouseInRectIndex1(offset: %d; slot: %d; elemSize: %d; var: %d; index: %d)", arg16(3), arg16(5), arg16(7), arg16(9), arg16(11));
-
- int16 index = -1;
- if (_vm->_mouseY < _vm->_cameraHeight) {
- index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
- _vm->_mouseX + _vm->_cameraX,
- _vm->_mouseY + _vm->_cameraY,
- arg16(11) + 1, arg16(7));
- }
- localWrite16(arg16(9), index);
- break;
- }
-
- case 24:// ok
- {
-
- debug(0, "o2_findMouseInRectIndex2(offset: %d, slot: %d, elemSize: %d, var: %d)", arg16(3), arg16(5), arg16(7), arg16(9));
- int16 index = -1;
-
- if (_vm->_sceneResIndex != 0) {
- if (_vm->_mouseY < _vm->_cameraHeight) {
- index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
- _vm->_mouseX + _vm->_cameraX,
- _vm->_mouseY + _vm->_cameraY,
- 0, arg16(7));
- }
- }
-
- localWrite16(arg16(9), index);
-
- break;
- }
-
- case 25:// ok
- {
- debug(0, "o2_drawGuiImage(x: %d; y: %d; resIndex: %d)", arg16(5), arg16(3), arg16(7));
- _vm->_screen->drawGuiImage(arg16(5), arg16(3), arg16(7));
- break;
- }
-
- case 26:// ok
- {
- debug(0, "o2_addAnimatedSpriteNoLoop(2; x: %d; y: %d; fragmentId: %d; offset: %d)", arg16(5), arg16(3), arg16(7), arg16(9));
- _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), false, 2);
- break;
- }
-
- case 27:// ok
- {
- debug(0, "o2_addAnimatedSprite(2; x: %d; y: %d; fragmentId: %d; offset: %d)", arg16(5), arg16(3), arg16(7), arg16(9));
- _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), true, 2);
- break;
- }
-
- case 28:// ok
- {
- debug(1, "o2_addStaticSprite()");
- _vm->_screen->addStaticSprite(_subCode + 3);
- break;
- }
-
- case 29:// ok
- {
- debug(0, "o2_addAnimatedSprite(1; x: %d; y: %d; value: %d; offset: %d)", arg16(5), arg16(3), arg16(7), arg16(9));
- _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), true, 1);
- break;
- }
-
- case 30:// ok
- {
- debug(0, "o2_findPath(sourceX: %d; sourceY: %d; destX: %d; destY: %d; slotIndex: %d; offset: %d)", arg16(5), arg16(3), arg16(9), arg16(7), arg16(13), arg16(11));
- _vm->_segmap->findPath((int16*)(getSlotData(arg16(13)) + arg16(11)), arg16(9), arg16(7), arg16(5), arg16(3));
- break;
- }
-
- case 31:// ok
- {
- debug(0, "o2_walk()");
- _vm->walk(getSlotData(arg16(5)) + arg16(3));
- break;
- }
-
- case 32:// ok
- {
- debug(0, "o2_scrollCameraUp()");
- _vm->scrollCameraUp(4);
- break;
- }
-
- case 33:// ok
- {
- debug(0, "o2_scrollCameraDown()");
- _vm->scrollCameraDown(4);
- break;
- }
-
- case 34:// ok
- {
- debug(0, "o2_scrollCameraLeft()");
- _vm->scrollCameraLeft(4);
- break;
- }
-
- case 35:// ok
- {
- debug(0, "o2_scrollCameraRight()");
- _vm->scrollCameraRight(4);
- break;
- }
-
- case 36:// ok
- {
- debug(0, "o2_scrollCameraUpEx(%d)", arg16(3));
- _vm->scrollCameraUp(arg16(3));
- break;
- }
-
- case 37:// ok
- {
- debug(0, "o2_scrollCameraDownEx(%d)", arg16(3));
- _vm->scrollCameraDown(arg16(3));
- break;
- }
-
- case 38:// ok
- {
- debug(0, "o2_scrollCameraLeftEx(%d)", arg16(3));
- _vm->scrollCameraLeft(arg16(3));
- break;
- }
-
- case 39:// ok
- {
- debug(0, "o2_scrollCameraRightEx(%d)", arg16(3));
- _vm->scrollCameraRight(arg16(3));
- break;
- }
-
- case 40:// ok
- {
- debug(0, "o2_setCamera(%d, %d)", arg16(5), arg16(3));
- _vm->setCamera(arg16(5), arg16(3));
- break;
- }
-
- case 42:// ok
- {
- debug(0, "o2_getRgbModifiertAtPoint(x: %d; y: %d; id: %d; varSlot: %d; varOffset: %d)", arg16(5), arg16(3), arg16(7), arg16(11), arg16(9));
- byte *rgb = getSlotData(arg16(11)) + arg16(9);
- _vm->_segmap->getRgbModifiertAtPoint(arg16(5), arg16(3), arg16(7), rgb[0], rgb[1], rgb[2]);
- break;
- }
-
- case 43:// ok
- {
- debug(0, "o2_startAnim(%d)", arg16(3));
- _vm->_anim->start(arg16(3));
- break;
- }
-
- case 44:// ok
- {
- debug(0, "o2_animNextFrame()");
- _vm->_anim->nextFrame();
- break;
- }
-
- case 45:// ok
- {
- // NOP
- break;
- }
-
- case 46:// ok
- {
- debug(0, "o2_getAnimFrameNumber(%d)", arg16(3));
- localWrite16(arg16(3), _vm->_anim->getFrameNumber());
- break;
- }
-
- case 47:
- {
- // almost ok
- debug(0, "o2_getAnimStatus()");
- int16 status = _vm->_anim->getStatus();
- if (status == 0 || status == 1) {
- // TODO mov screenFlag01, 0
- }
- localWrite16(arg16(3), status);
- break;
- }
-
- case 48:// ok
- {
- _vm->_screen->startShakeScreen(arg16(3));
- break;
- }
-
- case 49:// ok
- {
- _vm->_screen->stopShakeScreen();
- break;
- }
-
- case 50:// TODO
- {
- debug(0, "o2_startSequence");
- break;
- }
-
- case 51:// TODO
- {
- debug(0, "o2_endSequence");
- break;
- }
-
- case 52:// TODO
- {
- debug(0, "o2_sequenceVolumeStuff");
- break;
- }
-
- case 53:// TODO
- {
- debug(0, "o2_playSound1(%d, %d, %d, %d)", arg16(9), arg16(7), arg16(5), arg16(3));
- break;
- }
-
- case 54:// TODO
- {
- //debug(0, "o2_playSound2(%d, %d, %d)", arg16(7), arg16(5), arg16(3));
-
- _vm->_sound->playSound(arg16(3), arg16(5), arg16(7));
-
- break;
- }
-
- case 55:// TODO
- debug(0, "o2_clearScreen()");
- break;
-
- case 56:// ok
- {
- // NOP
- break;
- }
-
- case 57:// TODO
- {
- debug(0, "o2_handleInput");
- int16 varOfs = arg16(3);
-
- localWrite16(varOfs, 0);
-
- //_vm->_input->update();
- break;
- }
-
- case 58:// TODO
- {
- debug(0, "o2_runOptionsScreen(%d, %d)", arg16(5), arg16(3));
- break;
- }
-
- case 59:// TODO
- {
- debug(0, "o2_precacheSprites(%04X)", arg16(3));
- break;
- }
-
- case 60:// TODO
- {
- debug(0, "o2_precacheSounds1(%04X)", arg16(3));
- break;
- }
-
- case 61:// TODO
- {
- debug(0, "o2_deleteAllPbfFilesByExternalArray()");
- break;
- }
-
- case 62:// TODO - this opcode was never executed while I completed the game
- {
- debug(0, "o2_precacheSounds2(%04X)", arg16(3));
- break;
- }
-
- case 63:// ok
- {
- _regs.sp = _savedSp;
- break;
- }
-
- case 64:// ok
- {
- _savedSp = _regs.sp;
- break;
- }
-
- case 65:// TODO
- {
- debug(0, "o2_playMovie(%d, %d)", arg16(3), arg16(5));
- _vm->_moviePlayer->playMovie(arg16(3));
- break;
- }
-
- case 66:
- // NOP
- break;
-
- default:
- error("Invalid kernel opcode %d", kernelOpcode);
- }
-
+void ScriptInterpreter::execScriptFunction(uint16 index) {
+ debug(4, "execScriptFunction(%d)", index);
+ if (index >= _scriptFuncs.size())
+ error("ScriptInterpreter::execScriptFunction() Invalid script function index %d", index);
+ debug(4, "%s", _scriptFuncNames[index]);
+ (*_scriptFuncs[index])();
}
VarType ScriptInterpreter::getGameVarType(uint variable) {
@@ -1124,16 +692,6 @@ int16 ScriptInterpreter::arg16(int16 offset) {
return READ_LE_UINT16(&_subCode[offset]);
}
-void ScriptInterpreter::pushByte(byte value) {
- _stack[_regs.sp] = value;
- _regs.sp--;
-}
-
-byte ScriptInterpreter::popByte() {
- _regs.sp++;
- return _stack[_regs.sp];
-}
-
void ScriptInterpreter::pushInt16(int16 value) {
WRITE_LE_UINT16(_stack + _regs.sp, value);
_regs.sp -= 2;
@@ -1232,4 +790,315 @@ void ScriptInterpreter::loadState(Common::ReadStream *in) {
}
+void ScriptInterpreter::sfNop() {
+ // NOP
+}
+
+void ScriptInterpreter::sfGetGameVar() {
+ int16 value = getGameVar(arg16(3));
+ localWrite16(arg16(5), value);
+}
+
+void ScriptInterpreter::sfSetGameVar() {
+ int16 varIndex = arg16(3);
+ VarType varType = getGameVarType(varIndex);
+ int16 value = 0;
+ if (varType == vtByte)
+ value = arg8(5);
+ else if (varType == vtWord)
+ value = arg16(5);
+ setGameVar(varIndex, value);
+}
+
+void ScriptInterpreter::sfUpdateScreen() {
+
+ _vm->_sound->updateSpeech();
+
+ _vm->_screen->updateShakeScreen();
+
+ // TODO: Set quit flag
+ if (_vm->shouldQuit())
+ return;
+
+ if (!_vm->_movieSceneFlag)
+ _vm->updateInput();
+ else
+ _vm->_mouseButton = 0;
+
+ // TODO? Check keyb
+
+ _vm->_counter01--;
+ if (_vm->_counter01 <= 0) {
+ _vm->_counter01 = MIN(_vm->_counter02, 30);
+ _vm->_counter02 = 0;
+ _vm->updateScreen();
+ _vm->_flag01 = 1;
+ _vm->_system->delayMillis(5);
+ _vm->_counter02 = 1; // ?
+ } else {
+ _vm->_screen->clearSprites();
+ _vm->_flag01 = 0;
+ //_vm->_system->updateScreen();
+ }
+
+ // TODO
+
+}
+
+void ScriptInterpreter::sfGetRandomNumber() {
+ localWrite16(arg16(5), _vm->_rnd->getRandomNumber(arg16(3) - 1));
+}
+
+void ScriptInterpreter::sfDrawGuiTextMulti() {
+ _vm->_screen->drawGuiTextMulti((byte*)localPtr(arg16(3)));
+}
+
+void ScriptInterpreter::sfUpdateVerbLine() {
+ _vm->_screen->updateVerbLine(arg16(5), arg16(3));
+}
+
+void ScriptInterpreter::sfSetFontColor() {
+ _vm->_screen->_fontColor1 = 0;
+ _vm->_screen->_fontColor2 = arg8(3);
+}
+
+void ScriptInterpreter::sfGetTalkTextDuration() {
+ localWrite16(arg16(3), _vm->_screen->getTalkTextDuration());
+}
+
+void ScriptInterpreter::sfTalk() {
+ _vm->talk(arg16(5), arg16(3));
+}
+
+void ScriptInterpreter::sfFindPaletteFragment() {
+ localWrite16(arg16(5), _vm->_palette->findFragment(arg16(3)));
+}
+
+void ScriptInterpreter::sfClearPaletteFragments() {
+ _vm->_palette->clearFragments();
+}
+
+void ScriptInterpreter::sfAddPaletteFragment() {
+ _vm->_palette->addFragment(arg16(3), arg16(5));
+}
+
+void ScriptInterpreter::sfSetDeltaAnimPalette() {
+ _vm->_palette->setDeltaPalette(_vm->_palette->getAnimPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
+}
+
+void ScriptInterpreter::sfBuildColorTransTable() {
+ _vm->_palette->buildColorTransTable(arg8(4), (char)arg8(3), arg8(5));
+}
+
+void ScriptInterpreter::sfSetDeltaMainPalette() {
+ _vm->_palette->setDeltaPalette(_vm->_palette->getMainPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
+}
+
+void ScriptInterpreter::sfLoadScript() {
+ int16 codeOfs = _code - getSlotData(_regs.reg4);
+ loadScript(arg16(4), arg8(3));
+ _code = getSlotData(_regs.reg4) + codeOfs;
+ _switchLocalDataNear = true;
+}
+
+void ScriptInterpreter::sfRegisterFont() {
+ _vm->_screen->registerFont(arg8(3), arg16(4));
+}
+
+void ScriptInterpreter::sfLoadAddPalette() {
+ _vm->_palette->loadAddPalette(arg16(4), arg8(3));
+}
+
+void ScriptInterpreter::sfLoadScene() {
+ if (arg8(3) == 0) {
+ _vm->_sound->stopSpeech();
+ _vm->loadScene(arg16(4));
+ } else {
+ _vm->_screen->loadMouseCursor(arg16(4));
+ }
+}
+
+void ScriptInterpreter::sfSetGuiHeight() {
+ _vm->setGuiHeight(arg8(3));
+}
+
+void ScriptInterpreter::sfFindMouseInRectIndex1() {
+ int16 index = -1;
+ if (_vm->_mouseY < _vm->_cameraHeight) {
+ index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
+ _vm->_mouseX + _vm->_cameraX,
+ _vm->_mouseY + _vm->_cameraY,
+ arg16(11) + 1, arg16(7));
+ }
+ localWrite16(arg16(9), index);
+}
+
+void ScriptInterpreter::sfFindMouseInRectIndex2() {
+ int16 index = -1;
+ if (_vm->_sceneResIndex != 0) {
+ if (_vm->_mouseY < _vm->_cameraHeight) {
+ index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
+ _vm->_mouseX + _vm->_cameraX,
+ _vm->_mouseY + _vm->_cameraY,
+ 0, arg16(7));
+ }
+ }
+ localWrite16(arg16(9), index);
+}
+
+void ScriptInterpreter::sfDrawGuiImage() {
+ _vm->_screen->drawGuiImage(arg16(5), arg16(3), arg16(7));
+}
+
+void ScriptInterpreter::sfAddAnimatedSpriteNoLoop() {
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), false, 2);
+}
+
+void ScriptInterpreter::sfAddAnimatedSprite() {
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), true, 2);
+}
+
+void ScriptInterpreter::sfAddStaticSprite() {
+ _vm->_screen->addStaticSprite(_subCode + 3);
+}
+
+void ScriptInterpreter::sfAddAnimatedSpriteScaled() {
+ _vm->_screen->addAnimatedSprite(arg16(5), arg16(3), arg16(7), (byte*)localPtr(0), (int16*)localPtr(arg16(9)), true, 1);
+}
+
+void ScriptInterpreter::sfFindPath() {
+ _vm->_segmap->findPath((int16*)(getSlotData(arg16(13)) + arg16(11)), arg16(9), arg16(7), arg16(5), arg16(3));
+}
+
+void ScriptInterpreter::sfWalk() {
+ _vm->walk(getSlotData(arg16(5)) + arg16(3));
+}
+
+void ScriptInterpreter::sfScrollCameraUp() {
+ _vm->scrollCameraUp(4);
+}
+
+void ScriptInterpreter::sfScrollCameraDown() {
+ _vm->scrollCameraDown(4);
+}
+
+void ScriptInterpreter::sfScrollCameraLeft() {
+ _vm->scrollCameraLeft(4);
+}
+
+void ScriptInterpreter::sfScrollCameraRight() {
+ _vm->scrollCameraRight(4);
+}
+
+void ScriptInterpreter::sfScrollCameraUpEx() {
+ _vm->scrollCameraUp(arg16(3));
+}
+
+void ScriptInterpreter::sfScrollCameraDownEx() {
+ _vm->scrollCameraDown(arg16(3));
+}
+
+void ScriptInterpreter::sfScrollCameraLeftEx() {
+ _vm->scrollCameraLeft(arg16(3));
+}
+
+void ScriptInterpreter::sfScrollCameraRightEx() {
+ _vm->scrollCameraRight(arg16(3));
+}
+
+void ScriptInterpreter::sfSetCamera() {
+ _vm->setCamera(arg16(5), arg16(3));
+}
+
+void ScriptInterpreter::sfGetRgbModifiertAtPoint() {
+ byte *rgb = getSlotData(arg16(11)) + arg16(9);
+ _vm->_segmap->getRgbModifiertAtPoint(arg16(5), arg16(3), arg16(7), rgb[0], rgb[1], rgb[2]);
+}
+
+void ScriptInterpreter::sfStartAnim() {
+ _vm->_anim->start(arg16(3));
+}
+
+void ScriptInterpreter::sfAnimNextFrame() {
+ _vm->_anim->nextFrame();
+}
+
+void ScriptInterpreter::sfGetAnimFrameNumber() {
+ localWrite16(arg16(3), _vm->_anim->getFrameNumber());
+}
+
+void ScriptInterpreter::sfGetAnimStatus() {
+ int16 status = _vm->_anim->getStatus();
+ if (status == 0 || status == 1) {
+ // TODO mov screenFlag01, 0
+ }
+ localWrite16(arg16(3), status);
+}
+
+void ScriptInterpreter::sfStartShakeScreen() {
+ _vm->_screen->startShakeScreen(arg16(3));
+}
+
+void ScriptInterpreter::sfStopShakeScreen() {
+ _vm->_screen->stopShakeScreen();
+}
+
+void ScriptInterpreter::sfStartSequence() {
+ // TODO
+}
+
+void ScriptInterpreter::sfEndSequence() {
+ // TODO
+}
+
+void ScriptInterpreter::sfSequenceVolumeStuff() {
+ // TODO
+}
+
+void ScriptInterpreter::sfPlaySound1() {
+ // TODO
+}
+
+void ScriptInterpreter::sfPlaySound2() {
+ _vm->_sound->playSound(arg16(3), arg16(5), arg16(7));
+}
+
+void ScriptInterpreter::sfClearScreen() {
+ // TODO
+}
+
+void ScriptInterpreter::sfHandleInput() {
+ // TODO: Recheck what this does, I don't remember
+ int16 varOfs = arg16(3);
+ localWrite16(varOfs, 0);
+}
+
+void ScriptInterpreter::sfRunOptionsScreen() {
+ // TODO
+}
+
+void ScriptInterpreter::sfPrecacheSprites() {
+}
+
+void ScriptInterpreter::sfPrecacheSounds1() {
+}
+
+void ScriptInterpreter::sfDeleteAllPbfFilesByExternalArray() {
+}
+
+void ScriptInterpreter::sfPrecacheSounds2() {
+}
+
+void ScriptInterpreter::sfRestoreStackPtr() {
+ _regs.sp = _savedSp;
+}
+
+void ScriptInterpreter::sfSaveStackPtr() {
+ _savedSp = _regs.sp;
+}
+
+void ScriptInterpreter::sfPlayMovie() {
+ _vm->_moviePlayer->playMovie(arg16(3));
+}
+
} // End of namespace Toltecs
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index 8f4ae80..c35a2e4 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -34,6 +34,7 @@
#include "common/events.h"
#include "common/keyboard.h"
#include "common/array.h"
+#include "common/func.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
@@ -52,6 +53,8 @@ enum VarType {
vtWord
};
+typedef Common::Functor0<void> ScriptFunction;
+
class ScriptInterpreter {
public:
ScriptInterpreter(ToltecsEngine *vm);
@@ -90,6 +93,8 @@ protected:
};
ToltecsEngine *_vm;
+ Common::Array<const ScriptFunction*> _scriptFuncs;
+ Common::Array<const char *> _scriptFuncNames;
byte *_stack;
@@ -107,13 +112,13 @@ protected:
int16 readInt16();
void execOpcode(byte opcode);
- void execKernelOpcode(uint16 kernelOpcode);
+
+ void setupScriptFunctions();
+ void execScriptFunction(uint16 index);
byte arg8(int16 offset);
int16 arg16(int16 offset);
- void pushByte(byte value);
- byte popByte();
void pushInt16(int16 value);
int16 popInt16();
@@ -123,6 +128,68 @@ protected:
int16 localRead16(int16 offset);
byte *localPtr(int16 offset);
+ void sfNop();
+ void sfGetGameVar();
+ void sfSetGameVar();
+ void sfUpdateScreen();
+ void sfGetRandomNumber();
+ void sfDrawGuiTextMulti();
+ void sfUpdateVerbLine();
+ void sfSetFontColor();
+ void sfGetTalkTextDuration();
+ void sfTalk();
+ void sfFindPaletteFragment();
+ void sfClearPaletteFragments();
+ void sfAddPaletteFragment();
+ void sfSetDeltaAnimPalette();
+ void sfBuildColorTransTable();
+ void sfSetDeltaMainPalette();
+ void sfLoadScript();
+ void sfRegisterFont();
+ void sfLoadAddPalette();
+ void sfLoadScene();
+ void sfSetGuiHeight();
+ void sfFindMouseInRectIndex1();
+ void sfFindMouseInRectIndex2();
+ void sfDrawGuiImage();
+ void sfAddAnimatedSpriteNoLoop();
+ void sfAddAnimatedSprite();
+ void sfAddStaticSprite();
+ void sfAddAnimatedSpriteScaled();
+ void sfFindPath();
+ void sfWalk();
+ void sfScrollCameraUp();
+ void sfScrollCameraDown();
+ void sfScrollCameraLeft();
+ void sfScrollCameraRight();
+ void sfScrollCameraUpEx();
+ void sfScrollCameraDownEx();
+ void sfScrollCameraLeftEx();
+ void sfScrollCameraRightEx();
+ void sfSetCamera();
+ void sfGetRgbModifiertAtPoint();
+ void sfStartAnim();
+ void sfAnimNextFrame();
+ void sfGetAnimFrameNumber();
+ void sfGetAnimStatus();
+ void sfStartShakeScreen();
+ void sfStopShakeScreen();
+ void sfStartSequence();
+ void sfEndSequence();
+ void sfSequenceVolumeStuff();
+ void sfPlaySound1();
+ void sfPlaySound2();
+ void sfClearScreen();
+ void sfHandleInput();
+ void sfRunOptionsScreen();
+ void sfPrecacheSprites();
+ void sfPrecacheSounds1();
+ void sfDeleteAllPbfFilesByExternalArray();
+ void sfPrecacheSounds2();
+ void sfRestoreStackPtr();
+ void sfSaveStackPtr();
+ void sfPlayMovie();
+
};
Commit: af7e1c16833c2fb3df5c6079262d1e18d7959365
https://github.com/scummvm/scummvm/commit/af7e1c16833c2fb3df5c6079262d1e18d7959365
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: - Fixed sound playing
- Renaming
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/script.h
engines/toltecs/sound.cpp
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 6d4976d..188cb82 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -127,8 +127,8 @@ void ScriptInterpreter::setupScriptFunctions() {
RegisterScriptFunction(sfStopShakeScreen);
RegisterScriptFunction(sfStartSequence);
RegisterScriptFunction(sfEndSequence);
- RegisterScriptFunction(sfSequenceVolumeStuff);
- RegisterScriptFunction(sfPlaySound1);
+ RegisterScriptFunction(sfSetSequenceVolume);
+ RegisterScriptFunction(sfPlayPositionalSound);
RegisterScriptFunction(sfPlaySound2);
RegisterScriptFunction(sfClearScreen);
RegisterScriptFunction(sfNop);
@@ -143,9 +143,6 @@ void ScriptInterpreter::setupScriptFunctions() {
RegisterScriptFunction(sfPlayMovie);
RegisterScriptFunction(sfNop);
-
-
-
}
void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
@@ -1045,18 +1042,20 @@ void ScriptInterpreter::sfStopShakeScreen() {
void ScriptInterpreter::sfStartSequence() {
// TODO
+ //_vm->_arc->dump(arg16(3));
}
void ScriptInterpreter::sfEndSequence() {
// TODO
}
-void ScriptInterpreter::sfSequenceVolumeStuff() {
+void ScriptInterpreter::sfSetSequenceVolume() {
// TODO
}
-void ScriptInterpreter::sfPlaySound1() {
+void ScriptInterpreter::sfPlayPositionalSound() {
// TODO
+ debug("ScriptInterpreter::sfPlayPositionalSound()");
}
void ScriptInterpreter::sfPlaySound2() {
@@ -1078,15 +1077,42 @@ void ScriptInterpreter::sfRunOptionsScreen() {
}
void ScriptInterpreter::sfPrecacheSprites() {
+#if 0
+ // DEBUG
+ int16 *resArray = (int16*)localPtr(arg16(3));
+ while (*resArray != -1) {
+ debug("ScriptInterpreter::sfPrecacheSprites() index = %d", *resArray);
+ _vm->_arc->dump(*resArray, "pc1");
+ resArray++;
+ }
+#endif
}
void ScriptInterpreter::sfPrecacheSounds1() {
+#if 0
+ // DEBUG
+ int16 *resArray = (int16*)localPtr(arg16(3));
+ while (*resArray != -1) {
+ debug("ScriptInterpreter::sfPrecacheSounds1() index = %d", *resArray);
+ _vm->_arc->dump(*resArray, "pc2");
+ resArray++;
+ }
+#endif
}
void ScriptInterpreter::sfDeleteAllPbfFilesByExternalArray() {
}
void ScriptInterpreter::sfPrecacheSounds2() {
+#if 0
+ // DEBUG
+ int16 *resArray = (int16*)localPtr(arg16(3));
+ while (*resArray != -1) {
+ debug("ScriptInterpreter::sfPrecacheSounds2() index = %d", *resArray);
+ _vm->_arc->dump(*resArray, "pc3");
+ resArray++;
+ }
+#endif
}
void ScriptInterpreter::sfRestoreStackPtr() {
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index c35a2e4..746a2fc 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -176,8 +176,8 @@ protected:
void sfStopShakeScreen();
void sfStartSequence();
void sfEndSequence();
- void sfSequenceVolumeStuff();
- void sfPlaySound1();
+ void sfSetSequenceVolume();
+ void sfPlayPositionalSound();
void sfPlaySound2();
void sfClearScreen();
void sfHandleInput();
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 3f1be4b..08df1ce 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -116,7 +116,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
}
} else {
- if (type == kChannelTypeSpeech) {
+ if (type == -2) {
// Stop speech and play new sound
stopSpeech();
}
@@ -124,7 +124,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
// Play new sound in empty channel
int freeChannel = -1;
for (int i = 0; i < 4; i++) {
- if (channels[i].type == kChannelTypeEmpty) {
+ if (channels[i].type == kChannelTypeEmpty || !_vm->_mixer->isSoundHandleActive(channels[i].handle)) {
freeChannel = i;
break;
}
Commit: ce7febcd70092ce0015e952af6dbfaae23bed22d
https://github.com/scummvm/scummvm/commit/ce7febcd70092ce0015e952af6dbfaae23bed22d
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:07-08:00
Commit Message:
TOLTECS: Reworked the ArchiveReader and ResourceCache classes.
ResourceCache needs more work since resources are never freed (which is bad).
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
engines/toltecs/palette.cpp
engines/toltecs/render.cpp
engines/toltecs/resource.cpp
engines/toltecs/resource.h
engines/toltecs/screen.cpp
engines/toltecs/script.cpp
engines/toltecs/sound.cpp
engines/toltecs/sprite.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 9061ff5..0052d50 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -54,9 +54,9 @@ void Widget::redraw() {
Widget *Widget::getHoveredWidget(int mouseX, int mouseY) {
if (_rect.contains(mouseX, mouseY))
- return this;
+ return this;
else
- return NULL;
+ return NULL;
}
void Widget::calcDimensions() {
@@ -86,13 +86,13 @@ LabelWidget::~LabelWidget() {
}
void LabelWidget::redraw() {
- _vm->_screen->drawString(_rect.left, _rect.top, _fontColor, 14, (byte*)_caption.c_str(), -1, NULL, true);
+ _vm->_screen->drawString(_rect.left, _rect.top, _fontColor, 14, (byte*)_caption.c_str(), -1, NULL, true);
}
void LabelWidget::calcDimensions() {
- Font font(_vm->_res->load(14));
- _rect.setWidth(font.getTextWidth((byte*)_caption.c_str()));
- _rect.setHeight(font.getHeight());
+ Font font(_vm->_res->load(14)->data);
+ _rect.setWidth(font.getTextWidth((byte*)_caption.c_str()));
+ _rect.setHeight(font.getHeight());
}
void LabelWidget::setCaption(Common::String caption) {
@@ -109,15 +109,15 @@ void LabelWidget::onMouseEnter() {
}
void LabelWidget::onMouseLeave() {
- setFontColor(kFontColorMenuDefault);
+ setFontColor(kFontColorMenuDefault);
}
VolumeControlWidget::VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags) :
Widget(_vm, x, y), _activeWidget(NULL) {
- _label = new LabelWidget(vm, x, y, caption, flags);
- _up = new LabelWidget(vm, x + 350, y + 4, "[", flags);
+ _label = new LabelWidget(vm, x, y, caption, flags);
+ _up = new LabelWidget(vm, x + 350, y + 4, "[", flags);
_down = new LabelWidget(vm, x + 350 + 24, y + 4, "]", flags);
_indicator = new LabelWidget(vm, x + 350 + 24 + 24 + 8, y, "||||||||||", flags);
@@ -148,16 +148,16 @@ void VolumeControlWidget::calcDimensions() {
}
void VolumeControlWidget::onMouseEnter() {
- _label->setFontColor(kFontColorMenuActive);
- _indicator->setFontColor(kFontColorMenuActive);
+ _label->setFontColor(kFontColorMenuActive);
+ _indicator->setFontColor(kFontColorMenuActive);
_activeWidget = NULL;
}
void VolumeControlWidget::onMouseLeave() {
- _label->setFontColor(kFontColorMenuDefault);
- _up->setFontColor(kFontColorMenuDefault);
+ _label->setFontColor(kFontColorMenuDefault);
+ _up->setFontColor(kFontColorMenuDefault);
_down->setFontColor(kFontColorMenuDefault);
- _indicator->setFontColor(kFontColorMenuDefault);
+ _indicator->setFontColor(kFontColorMenuDefault);
}
void VolumeControlWidget::onMouseMove(int mouseX, int mouseY) {
@@ -166,19 +166,19 @@ void VolumeControlWidget::onMouseMove(int mouseX, int mouseY) {
hoveredWidget = _up->getHoveredWidget(mouseX, mouseY);
if (!hoveredWidget)
- hoveredWidget = _down->getHoveredWidget(mouseX, mouseY);
+ hoveredWidget = _down->getHoveredWidget(mouseX, mouseY);
if (_activeWidget != hoveredWidget) {
- _activeWidget = hoveredWidget;
- if (!_activeWidget) {
- _up->setFontColor(kFontColorMenuDefault);
- _down->setFontColor(kFontColorMenuDefault);
+ _activeWidget = hoveredWidget;
+ if (!_activeWidget) {
+ _up->setFontColor(kFontColorMenuDefault);
+ _down->setFontColor(kFontColorMenuDefault);
} else if (_activeWidget == _up) {
- _up->setFontColor(kFontColorMenuActive);
- _down->setFontColor(kFontColorMenuDefault);
+ _up->setFontColor(kFontColorMenuActive);
+ _down->setFontColor(kFontColorMenuDefault);
} else if (_activeWidget == _down) {
- _up->setFontColor(kFontColorMenuDefault);
- _down->setFontColor(kFontColorMenuActive);
+ _up->setFontColor(kFontColorMenuDefault);
+ _down->setFontColor(kFontColorMenuActive);
}
}
@@ -197,24 +197,24 @@ void MenuPage::addWidget(Widget *widget) {
void MenuPage::redraw() {
for (WidgetArray::iterator iter = _widgets.begin(); iter != _widgets.end(); iter++) {
- (*iter)->redraw();
+ (*iter)->redraw();
}
}
Widget *MenuPage::getHoveredWidget(int mouseX, int mouseY) {
- Widget *hoveredWidget = NULL;
+ Widget *hoveredWidget = NULL;
for (WidgetArray::iterator iter = _widgets.begin(); iter != _widgets.end() && !hoveredWidget; iter++) {
- hoveredWidget = (*iter)->getHoveredWidget(mouseX, mouseY);
+ hoveredWidget = (*iter)->getHoveredWidget(mouseX, mouseY);
}
return hoveredWidget;
}
MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm), _activeWidget(NULL), _oldMouseX(-1), _oldMouseY(-1) {
- _page = new MenuPage("Welcome");
- _page->addWidget(new LabelWidget(_vm, 10, 10, "Load game", 0));
- _page->addWidget(new LabelWidget(_vm, 10, 35, "Save game", 0));
- _page->addWidget(new VolumeControlWidget(_vm, 10, 60, "Master volume", 0));
- _page->addWidget(new VolumeControlWidget(_vm, 10, 90, "Some other volume", 0));
+ _page = new MenuPage("Welcome");
+ _page->addWidget(new LabelWidget(_vm, 10, 10, "Load game", 0));
+ _page->addWidget(new LabelWidget(_vm, 10, 35, "Save game", 0));
+ _page->addWidget(new VolumeControlWidget(_vm, 10, 60, "Master volume", 0));
+ _page->addWidget(new VolumeControlWidget(_vm, 10, 90, "Some other volume", 0));
}
MenuSystem::~MenuSystem() {
@@ -227,20 +227,20 @@ void MenuSystem::update() {
if (_vm->_mouseX != _oldMouseX || _vm->_mouseY != _oldMouseY) {
- _oldMouseX = _vm->_mouseX;
- _oldMouseY = _vm->_mouseY;
+ _oldMouseX = _vm->_mouseX;
+ _oldMouseY = _vm->_mouseY;
Widget *hoveredWidget = _page->getHoveredWidget(_vm->_mouseX, _vm->_mouseY);
if (_activeWidget != hoveredWidget) {
- if (_activeWidget)
- _activeWidget->onMouseLeave();
+ if (_activeWidget)
+ _activeWidget->onMouseLeave();
if (hoveredWidget)
- hoveredWidget->onMouseEnter();
- _activeWidget = hoveredWidget;
+ hoveredWidget->onMouseEnter();
+ _activeWidget = hoveredWidget;
}
if (_activeWidget) {
- _activeWidget->onMouseMove(_vm->_mouseX, _vm->_mouseY);
+ _activeWidget->onMouseMove(_vm->_mouseX, _vm->_mouseY);
}
}
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 15b73b7..dd75d66 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -51,35 +51,35 @@ const byte kFontColorMenuActive = 255;
class Widget {
public:
- Widget(ToltecsEngine *vm, int x, int y);
- virtual ~Widget();
- virtual void redraw();
- virtual Widget *getHoveredWidget(int mouseX, int mouseY);
- virtual void calcDimensions();
- void setRect(Common::Rect rect);
- //virtual void setHilighted(bool active);
- virtual void onMouseEnter();
- virtual void onMouseLeave();
- virtual void onMouseMove(int mouseX, int mouseY);
+ Widget(ToltecsEngine *vm, int x, int y);
+ virtual ~Widget();
+ virtual void redraw();
+ virtual Widget *getHoveredWidget(int mouseX, int mouseY);
+ virtual void calcDimensions();
+ void setRect(Common::Rect rect);
+ //virtual void setHilighted(bool active);
+ virtual void onMouseEnter();
+ virtual void onMouseLeave();
+ virtual void onMouseMove(int mouseX, int mouseY);
protected:
ToltecsEngine *_vm;
Common::Rect _rect;
//bool _hilighted;
};
-const int kLabelCentered = 1 << 1;
+const int kLabelCentered = 1 << 1;
const int kLabelHideOnMovie = 1 << 2;
class LabelWidget : public Widget {
public:
- LabelWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags);
- ~LabelWidget();
- void redraw();
+ LabelWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags);
+ ~LabelWidget();
+ void redraw();
void calcDimensions();
- void setCaption(Common::String caption);
- void setFontColor(byte fontColor);
- void onMouseEnter();
- void onMouseLeave();
+ void setCaption(Common::String caption);
+ void setFontColor(byte fontColor);
+ void onMouseEnter();
+ void onMouseLeave();
protected:
Common::String _caption;
uint _flags;
@@ -88,15 +88,15 @@ protected:
class VolumeControlWidget : public Widget {
public:
- VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags);
- ~VolumeControlWidget();
- void redraw();
- Widget *getHoveredWidget(int mouseX, int mouseY);
+ VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags);
+ ~VolumeControlWidget();
+ void redraw();
+ Widget *getHoveredWidget(int mouseX, int mouseY);
void calcDimensions();
//void setHilighted(bool active);
- void onMouseEnter();
- void onMouseLeave();
- void onMouseMove(int mouseX, int mouseY);
+ void onMouseEnter();
+ void onMouseLeave();
+ void onMouseMove(int mouseX, int mouseY);
protected:
uint _flags;
LabelWidget *_label, *_up, *_down, *_indicator;
@@ -105,33 +105,33 @@ protected:
class MenuPage {
public:
- MenuPage(Common::String caption);
- ~MenuPage();
- void addWidget(Widget *widget);
- void redraw();
- Widget *getHoveredWidget(int mouseX, int mouseY);
+ MenuPage(Common::String caption);
+ ~MenuPage();
+ void addWidget(Widget *widget);
+ void redraw();
+ Widget *getHoveredWidget(int mouseX, int mouseY);
protected:
typedef Common::Array<Widget*> WidgetArray;
- Common::String _caption;
- WidgetArray _widgets;
+ Common::String _caption;
+ WidgetArray _widgets;
};
class MenuSystem {
public:
- MenuSystem(ToltecsEngine *vm);
- ~MenuSystem();
-
+ MenuSystem(ToltecsEngine *vm);
+ ~MenuSystem();
+
void update();
protected:
- ToltecsEngine *_vm;
-
- //LabelWidget *label1, *label2;
- MenuPage *_page;
-
- Widget *_activeWidget;
- int16 _oldMouseX, _oldMouseY;
+ ToltecsEngine *_vm;
+
+ //LabelWidget *label1, *label2;
+ MenuPage *_page;
+
+ Widget *_activeWidget;
+ int16 _oldMouseX, _oldMouseY;
};
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 0d5faec..52f847e 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -102,8 +102,8 @@ void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 c
}
void Palette::loadAddPalette(uint resIndex, byte startIndex) {
- byte *data = _vm->_res->load(resIndex);
- memcpy(&_mainPalette[startIndex * 3], data, _vm->_res->getCurItemSize());
+ Resource *paletteResource = _vm->_res->load(resIndex);
+ memcpy(&_mainPalette[startIndex * 3], paletteResource->data, paletteResource->size);
}
void Palette::loadAddPaletteFrom(byte *source, byte startIndex, byte count) {
@@ -113,10 +113,10 @@ void Palette::loadAddPaletteFrom(byte *source, byte startIndex, byte count) {
void Palette::addFragment(uint resIndex, int16 id) {
debug(0, "Palette::addFragment(%d, %d)", resIndex, id);
- byte *fragmentData = _vm->_res->load(resIndex);
- byte count = _vm->_res->getCurItemSize() / 3;
+ Resource *fragmentResource = _vm->_res->load(resIndex);
+ byte count = fragmentResource->size / 3;
- memcpy(&_mainPalette[_fragmentIndex * 3], fragmentData, count * 3);
+ memcpy(&_mainPalette[_fragmentIndex * 3], fragmentResource->data, count * 3);
PaletteFragment fragment;
fragment.id = id;
diff --git a/engines/toltecs/render.cpp b/engines/toltecs/render.cpp
index 4ffb9f6..642b299 100644
--- a/engines/toltecs/render.cpp
+++ b/engines/toltecs/render.cpp
@@ -80,7 +80,7 @@ void RenderQueue::addSprite(SpriteDrawItem &sprite) {
void RenderQueue::addText(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len) {
- Font font(_vm->_res->load(fontResIndex));
+ Font font(_vm->_res->load(fontResIndex)->data);
RenderQueueItem item;
item.type = kText;
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index 9449fdf..aaff6e3 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -44,11 +44,16 @@ ArchiveReader::ArchiveReader() {
}
ArchiveReader::~ArchiveReader() {
+ delete[] _offsets;
}
void ArchiveReader::openArchive(const char *filename) {
open(filename);
- for (uint i = 0; i < 10000; i++)
+ uint32 firstOffs = readUint32LE();
+ uint count = firstOffs / 4;
+ _offsets = new uint32[count];
+ _offsets[0] = firstOffs;
+ for (uint i = 1; i < count; i++)
_offsets[i] = readUint32LE();
}
@@ -91,70 +96,30 @@ void ArchiveReader::dump(uint resIndex, const char *prefix) {
/* ResourceCache */
ResourceCache::ResourceCache(ToltecsEngine *vm) : _vm(vm) {
-
- _base = new byte[kMaxCacheSize];
- _bytesUsed = 0;
-
- memset(_cache, 0, sizeof(_cache));
- _cacheCount = 0;
-
- _curItemOffset = 0;
- _curItemSize = 0;
-
}
ResourceCache::~ResourceCache() {
- delete[] _base;
+ // TODO: Delete resources
}
-byte *ResourceCache::load(uint resIndex) {
- byte *data = NULL;
- if (existsItem(resIndex)) {
+Resource *ResourceCache::load(uint resIndex) {
+ ResourceMap::iterator item = _cache.find(resIndex);
+ if (item != _cache.end()) {
debug(1, "ResourceCache::load(%d) From cache", resIndex);
- data = _base + _curItemOffset;
+ return (*item)._value;
} else {
debug(1, "ResourceCache::load(%d) From disk", resIndex);
- uint32 size = _vm->_arc->openResource(resIndex);
- data = addItem(resIndex, size);
- _vm->_arc->read(data, size);
- _vm->_arc->closeResource();
- }
- return data;
-}
-
-bool ResourceCache::existsItem(uint resIndex) {
- for (uint i = 0; i < _cacheCount; i++) {
- if (_cache[i].resIndex == resIndex) {
- _curItemOffset = _cache[i].offset;
- _curItemSize = _cache[i].size;
- return true;
- }
- }
- return false;
-}
-byte *ResourceCache::addItem(uint resIndex, uint32 size) {
-
- checkCapacity(size);
-
- _curItemOffset = _bytesUsed;
- _curItemSize = size;
-
- _cache[_cacheCount].resIndex = resIndex;
- _cache[_cacheCount].offset = _curItemOffset;
- _cache[_cacheCount].size = _curItemSize;
- _cacheCount++;
-
- _bytesUsed += size;
-
- return _base + _curItemOffset;
-
-}
-
-void ResourceCache::checkCapacity(uint32 size) {
- if (_cacheCount > kMaxCacheItems || _bytesUsed + size > kMaxCacheSize) {
- _cacheCount = 0;
- _bytesUsed = 0;
+ Resource *resItem = new Resource();
+ resItem->size = _vm->_arc->openResource(resIndex);
+ resItem->data = new byte[resItem->size];
+ _vm->_arc->read(resItem->data, resItem->size);
+ _vm->_arc->closeResource();
+
+ _cache[resIndex] = resItem;
+
+ return resItem;
+
}
}
diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h
index ee1eb21..1c618ae 100644
--- a/engines/toltecs/resource.h
+++ b/engines/toltecs/resource.h
@@ -30,6 +30,7 @@
#include "common/file.h"
#include "common/savefile.h"
#include "common/system.h"
+#include "common/hashmap.h"
#include "common/hash-str.h"
#include "common/events.h"
#include "common/keyboard.h"
@@ -65,39 +66,28 @@ public:
void dump(uint resIndex, const char *prefix = NULL);
protected:
- uint32 _offsets[10000];
+ uint32 *_offsets;
};
+struct Resource {
+ uint32 size;
+ byte *data;
+};
+
class ResourceCache {
public:
ResourceCache(ToltecsEngine *vm);
~ResourceCache();
- byte *load(uint resIndex);
- uint32 getCurItemSize() const { return _curItemSize; }
+ Resource *load(uint resIndex);
protected:
-
- struct CacheItem {
- uint resIndex;
- //int value; // what is this?
- int32 offset; // offset into _base
- uint32 size; // size of the item
- };
+ typedef Common::HashMap<uint, Resource*> ResourceMap;
ToltecsEngine *_vm;
- byte *_base;
- uint32 _bytesUsed;
- uint32 _curItemOffset, _curItemSize;
-
- CacheItem _cache[kMaxCacheItems];
- uint _cacheCount;
-
- bool existsItem(uint resIndex);
- byte *addItem(uint resIndex, uint32 size);
- void checkCapacity(uint32 size);
+ ResourceMap _cache;
};
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 47c852d..c3487f4 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -109,7 +109,7 @@ void Screen::unpackRle(byte *source, byte *dest, uint16 width, uint16 height) {
void Screen::loadMouseCursor(uint resIndex) {
byte mouseCursor[16 * 16], *mouseCursorP = mouseCursor;
- byte *cursorData = _vm->_res->load(resIndex);
+ byte *cursorData = _vm->_res->load(resIndex)->data;
for (int i = 0; i < 32; i++) {
byte pixel;
byte mask1 = *cursorData++;
@@ -131,7 +131,7 @@ void Screen::loadMouseCursor(uint resIndex) {
void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
- byte *imageData = _vm->_res->load(resIndex);
+ byte *imageData = _vm->_res->load(resIndex)->data;
int16 headerSize = READ_LE_UINT16(imageData);
int16 width = imageData[2];
int16 height = imageData[3];
@@ -276,7 +276,7 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
debug(0, "Screen::updateVerbLine() _verbLineNum = %d; _verbLineX = %d; _verbLineY = %d; _verbLineWidth = %d; _verbLineCount = %d",
_verbLineNum, _verbLineX, _verbLineY, _verbLineWidth, _verbLineCount);
- Font font(_vm->_res->load(_fontResIndexArray[0]));
+ Font font(_vm->_res->load(_fontResIndexArray[0])->data);
_verbLineItems[_verbLineNum].slotIndex = slotIndex;
_verbLineItems[_verbLineNum].slotOffset = slotOffset;
@@ -392,7 +392,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
item->duration = 0;
item->lineCount = 0;
- Font font(_vm->_res->load(_fontResIndexArray[item->fontNum]));
+ Font font(_vm->_res->load(_fontResIndexArray[item->fontNum])->data);
int16 wordLength, wordWidth;
while (*textData < 0xF0) {
@@ -558,7 +558,7 @@ void Screen::drawGuiTextMulti(byte *textData) {
int16 Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState) {
- Font font(_vm->_res->load(fontResIndex));
+ Font font(_vm->_res->load(fontResIndex)->data);
int16 len = 0;
while (*wrapState.sourceString >= 0x20 && *wrapState.sourceString < 0xF0) {
@@ -594,7 +594,7 @@ int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *
debug(0, "Screen::drawString(%d, %d, %d, %d)", x, y, color, fontResIndex);
- Font font(_vm->_res->load(fontResIndex));
+ Font font(_vm->_res->load(fontResIndex)->data);
if (len == -1)
len = strlen((char*)text);
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 188cb82..602c3f5 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -150,10 +150,10 @@ void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
delete[] _slots[slotIndex].data;
_slots[slotIndex].resIndex = resIndex;
- byte *scriptData = _vm->_res->load(resIndex);
- _slots[slotIndex].size = _vm->_res->getCurItemSize();
+ Resource *scriptResource = _vm->_res->load(resIndex);
+ _slots[slotIndex].size = scriptResource->size;
_slots[slotIndex].data = new byte[_slots[slotIndex].size];
- memcpy(_slots[slotIndex].data, scriptData, _slots[slotIndex].size);
+ memcpy(_slots[slotIndex].data, scriptResource->data, _slots[slotIndex].size);
}
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 08df1ce..b3d327f 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -133,14 +133,13 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
// If all channels are in use no new sound will be played
if (freeChannel >= 0) {
- byte *soundData = _vm->_res->load(resIndex);
- uint32 soundSize = _vm->_res->getCurItemSize();
+ Resource *soundResource = _vm->_res->load(resIndex);
byte flags = Audio::Mixer::FLAG_UNSIGNED;
// Background sounds
if (type == kChannelTypeBackground)
flags |= Audio::Mixer::FLAG_LOOP;
- Audio::AudioStream *stream = Audio::makeLinearInputStream(soundData, soundSize, 22050, flags, 0, 0);
+ Audio::AudioStream *stream = Audio::makeLinearInputStream(soundResource->data, soundResource->size, 22050, flags, 0, 0);
channels[freeChannel].type = type;
channels[freeChannel].resIndex = resIndex;
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index 264216d..787f15c 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -216,7 +216,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.resIndex = drawRequest.resIndex;
sprite.frameNum = frameNum;
- spriteData = _vm->_res->load(drawRequest.resIndex);
+ spriteData = _vm->_res->load(drawRequest.resIndex)->data;
if (drawRequest.flags & 0x1000) {
sprite.flags |= 4;
@@ -405,7 +405,7 @@ void Screen::drawSprite(const SpriteDrawItem &sprite) {
debug(0, "Screen::drawSprite() width = %d; height = %d; origWidth = %d; origHeight = %d",
sprite.width, sprite.height, sprite.origWidth, sprite.origHeight);
- byte *source = _vm->_res->load(sprite.resIndex) + sprite.offset;
+ byte *source = _vm->_res->load(sprite.resIndex)->data + sprite.offset;
byte *dest = _frontScreen + sprite.x + sprite.y * 640;
SpriteReader spriteReader(source, sprite);
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 40b2388..80a77af 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -186,7 +186,8 @@ Common::Error ToltecsEngine::run() {
void ToltecsEngine::loadScene(uint resIndex) {
// TODO
- byte *scene = _res->load(resIndex);
+ Resource *sceneResource = _res->load(resIndex);
+ byte *scene = sceneResource->data;
uint32 imageSize = READ_LE_UINT32(scene);
_sceneResIndex = resIndex;
Commit: 9a84c13bef923eedc020b6706d0a7b6685bb42fd
https://github.com/scummvm/scummvm/commit/9a84c13bef923eedc020b6706d0a7b6685bb42fd
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: - Implemented playSoundAtPos and fixed sound panning (0 is center, not 64 like in the original)
- Minor cleanup
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/sound.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 602c3f5..920c0d0 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -1054,8 +1054,7 @@ void ScriptInterpreter::sfSetSequenceVolume() {
}
void ScriptInterpreter::sfPlayPositionalSound() {
- // TODO
- debug("ScriptInterpreter::sfPlayPositionalSound()");
+ _vm->_sound->playSoundAtPos(arg16(3), arg16(9), arg16(7));
}
void ScriptInterpreter::sfPlaySound2() {
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index b3d327f..012b5ee 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -56,47 +56,59 @@ Sound::~Sound() {
}
void Sound::playSpeech(int16 resIndex) {
-
- // TODO
-
debug(0, "playSpeech(%d)", resIndex);
-
- internalPlaySound(resIndex, kChannelTypeSpeech, 50 /*TODO*/, 64);
-
+ internalPlaySound(resIndex, kChannelTypeSpeech, 50 /*TODO*/, 0);
}
void Sound::playSound(int16 resIndex, int16 type, int16 volume) {
// TODO: Use the right volumes
- debug(0, "playSound(%d, %d, %d)", resIndex, type, volume);
+ debug("playSound(%d, %d, %d)", resIndex, type, volume);
if (volume == -1 || type == kChannelTypeSfx) {
if (type == kChannelTypeBackground) {
- internalPlaySound(resIndex, type, 50 /*TODO*/, 64);
+ internalPlaySound(resIndex, type, 50 /*TODO*/, 0);
} else {
- internalPlaySound(resIndex, type, 100 /*TODO*/, 64);
+ internalPlaySound(resIndex, type, 100 /*TODO*/, 0);
}
} else {
- internalPlaySound(resIndex, type, 100 /*TODO*/, 64);
+ internalPlaySound(resIndex, type, 100 /*TODO*/, 0);
}
}
void Sound::playSoundAtPos(int16 resIndex, int16 x, int16 y) {
- // TODO: Everything
-
debug(0, "playSoundAtPos(%d, %d, %d)", resIndex, x, y);
- internalPlaySound(resIndex, 1, 50, 64);
+ int16 volume, panning = 0, deltaX = 0;
+ int8 scaling = _vm->_segmap->getScalingAtPoint(x, y);
+
+ if (scaling >= 0)
+ volume = 50 + ABS(scaling) / 2;
+ else
+ volume = 50 - ABS(scaling) / 2;
+
+ if (_vm->_cameraX > x)
+ deltaX = _vm->_cameraX - x;
+ else if (_vm->_cameraX + 640 < x)
+ deltaX = x - (_vm->_cameraX + 640);
+ if (deltaX > 600)
+ deltaX = 600;
+
+ volume = ((100 - deltaX / 6) * volume) / 100;
+
+ if (_vm->_cameraX + 320 != x) {
+ panning = CLIP(x - (_vm->_cameraX + 320), -381, 381) / 3;
+ }
+
+ internalPlaySound(resIndex, 1, volume, panning);
}
void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning) {
- // TODO
-
if (resIndex == -1) {
// Stop all sounds
_vm->_mixer->stopAll();
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 80a77af..cd736fb 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -415,7 +415,6 @@ void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
byte *scanData = _script->getSlotData(slotIndex) + slotOffset;
while (*scanData < 0xF0) {
-
if (*scanData == 0x19) {
scanData++;
} else if (*scanData == 0x14) {
@@ -425,7 +424,6 @@ void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
} else if (*scanData < 0x0A) {
scanData++;
}
-
scanData++;
}
@@ -438,7 +436,7 @@ void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
if (_doText) {
_screen->updateTalkText(slotIndex, slotOffset);
} else {
- // TODO: font_sub_4B3E2
+ _screen->keepTalkTextItemsAlive();
}
} else {
_screen->updateTalkText(slotIndex, slotOffset);
@@ -446,23 +444,6 @@ void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) {
}
-void ToltecsEngine::playText(int16 slotIndex, int16 slotOffset) {
-
- byte *textData = _script->getSlotData(slotIndex) + slotOffset;
-
- debug(0, "ToltecsEngine::playText() [textData = %s]", (char*)textData);
-
- Common::String str;
- while (*textData < 0xF0) {
- if (*textData >= 32)
- str += (char)*textData;
- textData++;
- }
-
- debug(0, "ToltecsEngine::playText() [%s]", str.c_str());
-
-}
-
void ToltecsEngine::walk(byte *walkData) {
int16 xdelta, ydelta, v8, v10, v11;
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 7b7e1a3..b425af8 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -91,7 +91,6 @@ public:
void updateCamera();
void talk(int16 slotIndex, int16 slotOffset);
- void playText(int16 slotIndex, int16 slotOffset);
void walk(byte *walkData);
Commit: 22db6b155840c145864ccc219b21e197d5dce738
https://github.com/scummvm/scummvm/commit/22db6b155840c145864ccc219b21e197d5dce738
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: - Fixed clipping bugs (in 256-color sprites and scaled sprites)
- Minor cleanup
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/segmap.cpp
engines/toltecs/segmap.h
engines/toltecs/sound.cpp
engines/toltecs/sprite.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index c3487f4..9f77c05 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -805,10 +805,4 @@ void Screen::loadState(Common::ReadStream *in) {
}
-
-/*
-void Screen::update() {
-}
-*/
-
} // End of namespace Toltecs
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index b51886f..414ea46 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -362,7 +362,7 @@ int8 SegmentMap::getScalingAtPoint(int16 x, int16 y) {
if (_infoRects[i].id == 0 && _infoRects[i].isPointInside(x, y)) {
int8 topScaling = (int8)_infoRects[i].b;
int8 bottomScaling = (int8)_infoRects[i].c;
- if (y - _infoRects[i].y > 0) {
+ if (y - _infoRects[i].y != 0) {
scaling = (ABS(y - _infoRects[i].y) * (bottomScaling - topScaling) / _infoRects[i].height) + topScaling;
}
}
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index b860efb..394d4ae 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -79,7 +79,7 @@ public:
void getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byte &g, byte &b);
void addMasksToRenderQueue();
-
+
//protected:
public: // for debugging purposes
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 012b5ee..875fd0b 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -66,7 +66,7 @@ void Sound::playSound(int16 resIndex, int16 type, int16 volume) {
debug("playSound(%d, %d, %d)", resIndex, type, volume);
- if (volume == -1 || type == kChannelTypeSfx) {
+ if (volume == -1 || type == -2) {
if (type == kChannelTypeBackground) {
internalPlaySound(resIndex, type, 50 /*TODO*/, 0);
} else {
@@ -117,7 +117,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
channels[i].type = kChannelTypeEmpty;
channels[i].resIndex = -1;
}
- } else if (type == kChannelTypeSfx) {
+ } else if (type == -2) {
// Stop sounds with specified resIndex
for (int i = 0; i < 4; i++) {
if (channels[i].resIndex == resIndex) {
@@ -128,7 +128,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
}
} else {
- if (type == -2) {
+ if (type == -3) {
// Stop speech and play new sound
stopSpeech();
}
@@ -156,7 +156,13 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
channels[freeChannel].type = type;
channels[freeChannel].resIndex = resIndex;
- _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType/*TODO*/, &channels[freeChannel].handle,
+ Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
+ /*
+ switch (type) {
+ }
+ */
+
+ _vm->_mixer->playInputStream(soundType, &channels[freeChannel].handle,
stream, -1, volume, panning);
}
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index 787f15c..84b485d 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -287,7 +287,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.x -= xoffs;
sprite.y -= yoffs;
-
+
sprite.yerror = sprite.ydelta;
// Now we check if the sprite needs to be clipped
@@ -296,7 +296,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (sprite.y - _vm->_cameraY < 0) {
int16 clipHeight = ABS(sprite.y - _vm->_cameraY);
- int16 chopHeight, skipHeight, lineWidth;
+ int16 skipHeight = clipHeight;
byte *spriteFrameData;
sprite.height -= clipHeight;
@@ -307,8 +307,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
// If the sprite is scaled
if (sprite.flags & 3) {
- chopHeight = sprite.ydelta;
- skipHeight = clipHeight;
+ int16 chopHeight = sprite.ydelta;
if ((sprite.flags & 2) == 0) {
do {
chopHeight -= 100;
@@ -336,20 +335,21 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
// Now the sprite's offset is adjusted to point to the starting line
if ((sprite.flags & 0x10) == 0) {
- while (clipHeight--) {
- lineWidth = 0;
- while (lineWidth </*CHECKME was != */ sprite.origWidth) {
+ while (skipHeight--) {
+ int16 lineWidth = 0;
+ while (lineWidth < sprite.origWidth) {
sprite.offset++;
- lineWidth += (*spriteFrameData++) & 0x0F;
+ lineWidth += spriteFrameData[0] & 0x0F;
+ spriteFrameData++;
}
}
} else {
- lineWidth = 0;
- while (clipHeight--) {
+ while (skipHeight--) {
+ int16 lineWidth = 0;
while (lineWidth < sprite.origWidth) {
sprite.offset += 2;
- spriteFrameData++;
- lineWidth += *spriteFrameData++;
+ lineWidth += spriteFrameData[1];
+ spriteFrameData += 2;
}
}
}
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index cd736fb..a984ca7 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -147,6 +147,8 @@ Common::Error ToltecsEngine::run() {
_system->showMouse(true);
+ syncSoundSettings();
+
//#define TEST_MENU
#ifdef TEST_MENU
_screen->registerFont(0, 0x0D);
@@ -220,7 +222,7 @@ void ToltecsEngine::loadScene(uint resIndex) {
_screen->_fullRefresh = true;
_screen->_renderQueue->clear();
-
+
}
void ToltecsEngine::updateScreen() {
Commit: d6edbe97c91f54bb84ebc3b1cb14e6131cdf04b7
https://github.com/scummvm/scummvm/commit/d6edbe97c91f54bb84ebc3b1cb14e6131cdf04b7
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Oops, forgot to disable the debug path drawing.
Changed paths:
engines/toltecs/segmap.cpp
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 414ea46..37240db 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -341,7 +341,7 @@ void SegmentMap::findPath(int16 *pointsArray, int16 destX, int16 destY, int16 so
debug(0, "SegmentMap::findPath() count = %d", pointsArray[1]);
-#if 1 // DEBUG: Draw the path we found
+#if 0 // DEBUG: Draw the path we found
int sx = sourceX, sy = sourceY;
LineData ld;
ld.pitch = _vm->_sceneWidth;
Commit: 3c49d36d5fbd9eccd94c6d084422d6aa83ceb3e3
https://github.com/scummvm/scummvm/commit/3c49d36d5fbd9eccd94c6d084422d6aa83ceb3e3
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Fix compilation.
Changed paths:
engines/toltecs/screen.cpp
engines/toltecs/script.cpp
engines/toltecs/script.h
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 9f77c05..1abb057 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -399,7 +399,6 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
if (*textData == 0x1E) {
textData++;
addTalkTextRect(font, x, y, length, width, item);
- // CHECKME?
width = 0;
length = 0;
} else {
@@ -415,10 +414,6 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
wordWidth += font.getCharWidth(ch) + font.getSpacing() - 1;
}
}
-
- debug(0, "## width = %d; wordWidth = %d; width + wordWidth = %d; maxWidth + font.getWidth() = %d",
- width, wordWidth, width + wordWidth, maxWidth + font.getWidth());
-
if (width + wordWidth > maxWidth + font.getWidth()) {
addTalkTextRect(font, x, y, length, width, item);
width = wordWidth;
@@ -432,8 +427,6 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
addTalkTextRect(font, x, y, length, width, item);
- debug(0, "## item->lineCount = %d", item->lineCount);
-
if (item->lineCount > 0) {
int16 ysub = (font.getHeight() - 1) * item->lineCount;
if (item->lines[0].y - 4 < ysub)
@@ -531,7 +524,6 @@ void Screen::drawGuiTextMulti(byte *textData) {
wrapState.sourceString = textData;
do {
-
if (*wrapState.sourceString == 0x0A) {
// Set text position
y = wrapState.sourceString[1];
@@ -549,7 +541,6 @@ void Screen::drawGuiTextMulti(byte *textData) {
wrapState.len2 = wrapGuiText(_fontResIndexArray[1], 640, wrapState);
drawGuiText(x - wrapState.width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1], wrapState);
}
-
} while (*wrapState.sourceString != 0xFF);
_guiRefresh = true;
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 920c0d0..4aaa626 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -136,7 +136,7 @@ void ScriptInterpreter::setupScriptFunctions() {
RegisterScriptFunction(sfRunOptionsScreen);
RegisterScriptFunction(sfPrecacheSprites);
RegisterScriptFunction(sfPrecacheSounds1);
- RegisterScriptFunction(sfDeleteAllPbfFilesByExternalArray);
+ RegisterScriptFunction(sfDeletePrecachedFiles);
RegisterScriptFunction(sfPrecacheSounds2);
RegisterScriptFunction(sfRestoreStackPtr);
RegisterScriptFunction(sfSaveStackPtr);
@@ -600,7 +600,6 @@ int16 ScriptInterpreter::getGameVar(uint variable) {
warning("Getting unimplemented game variable %s (%d)", getVarName(variable), variable);
break;
}
-
return value;
@@ -678,7 +677,6 @@ void ScriptInterpreter::setGameVar(uint variable, int16 value) {
break;
}
-
}
byte ScriptInterpreter::arg8(int16 offset) {
@@ -700,27 +698,27 @@ int16 ScriptInterpreter::popInt16() {
}
void ScriptInterpreter::localWrite8(int16 offset, byte value) {
- debug(1, "localWrite8(%d, %d)", offset, value);
+ //debug(1, "localWrite8(%d, %d)", offset, value);
_localData[offset] = value;
}
byte ScriptInterpreter::localRead8(int16 offset) {
- debug(1, "localRead8(%d) -> %d", offset, _localData[offset]);
+ //debug(1, "localRead8(%d) -> %d", offset, _localData[offset]);
return _localData[offset];
}
void ScriptInterpreter::localWrite16(int16 offset, int16 value) {
- debug(1, "localWrite16(%d, %d)", offset, value);
+ //debug(1, "localWrite16(%d, %d)", offset, value);
WRITE_LE_UINT16(&_localData[offset], value);
}
int16 ScriptInterpreter::localRead16(int16 offset) {
- debug(1, "localRead16(%d) -> %d", offset, (int16)READ_LE_UINT16(&_localData[offset]));
+ //debug(1, "localRead16(%d) -> %d", offset, (int16)READ_LE_UINT16(&_localData[offset]));
return (int16)READ_LE_UINT16(&_localData[offset]);
}
byte *ScriptInterpreter::localPtr(int16 offset) {
- debug(1, "localPtr(%d)", offset);
+ //debug(1, "localPtr(%d)", offset);
return &_localData[offset];
}
@@ -1066,7 +1064,7 @@ void ScriptInterpreter::sfClearScreen() {
}
void ScriptInterpreter::sfHandleInput() {
- // TODO: Recheck what this does, I don't remember
+ // TODO: Recheck what this does
int16 varOfs = arg16(3);
localWrite16(varOfs, 0);
}
@@ -1075,43 +1073,26 @@ void ScriptInterpreter::sfRunOptionsScreen() {
// TODO
}
+/* NOTE: The opcodes sfPrecacheSprites, sfPrecacheSounds1, sfPrecacheSounds2 and
+ sfDeletePrecachedFiles were used by the original engine to handle precaching
+ of data so the game doesn't stall while playing (due to the slow speed of
+ CD-Drives back then). This is not needed in ScummVM since all supported
+ systems are fast enough to load data in-game. */
+
void ScriptInterpreter::sfPrecacheSprites() {
-#if 0
- // DEBUG
- int16 *resArray = (int16*)localPtr(arg16(3));
- while (*resArray != -1) {
- debug("ScriptInterpreter::sfPrecacheSprites() index = %d", *resArray);
- _vm->_arc->dump(*resArray, "pc1");
- resArray++;
- }
-#endif
+ // See note above
}
void ScriptInterpreter::sfPrecacheSounds1() {
-#if 0
- // DEBUG
- int16 *resArray = (int16*)localPtr(arg16(3));
- while (*resArray != -1) {
- debug("ScriptInterpreter::sfPrecacheSounds1() index = %d", *resArray);
- _vm->_arc->dump(*resArray, "pc2");
- resArray++;
- }
-#endif
+ // See note above
}
-void ScriptInterpreter::sfDeleteAllPbfFilesByExternalArray() {
+void ScriptInterpreter::sfDeletePrecachedFiles() {
+ // See note above
}
void ScriptInterpreter::sfPrecacheSounds2() {
-#if 0
- // DEBUG
- int16 *resArray = (int16*)localPtr(arg16(3));
- while (*resArray != -1) {
- debug("ScriptInterpreter::sfPrecacheSounds2() index = %d", *resArray);
- _vm->_arc->dump(*resArray, "pc3");
- resArray++;
- }
-#endif
+ // See note above
}
void ScriptInterpreter::sfRestoreStackPtr() {
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index 746a2fc..83ee628 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -184,7 +184,7 @@ protected:
void sfRunOptionsScreen();
void sfPrecacheSprites();
void sfPrecacheSounds1();
- void sfDeleteAllPbfFilesByExternalArray();
+ void sfDeletePrecachedFiles();
void sfPrecacheSounds2();
void sfRestoreStackPtr();
void sfSaveStackPtr();
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index a984ca7..214b71d 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -22,6 +22,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/keyboard.h"
#include "common/file.h"
#include "common/savefile.h"
@@ -67,7 +68,7 @@ ToltecsEngine::ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDe
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
_rnd = new Common::RandomSource();
- syst->getEventManager()->registerRandomSource(*_rnd, "toltecs");
+ g_eventRec.registerRandomSource(*_rnd, "toltecs");
int cd_num = ConfMan.getInt("cdrom");
if (cd_num >= 0)
Commit: eb04f8567348da085283a7e260fb55ad9331e7e5
https://github.com/scummvm/scummvm/commit/eb04f8567348da085283a7e260fb55ad9331e7e5
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: - Added detection entry for the German demo version
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index f92ba29..17d8716 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -91,6 +91,18 @@ static const ToltecsGameDescription gameDescriptions[] = {
},
},
+ {
+ // 3 Skulls of the Toltecs German Demo version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "1c85e82712d24f1d5c1ea2a66ddd75c2", 47730038),
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS
+ },
+ },
+
{ AD_TABLE_END_MARKER }
};
Commit: d93bd3c01c3952649c69091e8bf516880bce053b
https://github.com/scummvm/scummvm/commit/d93bd3c01c3952649c69091e8bf516880bce053b
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Silenced some warnings
Changed paths:
engines/toltecs/animation.h
engines/toltecs/menu.cpp
engines/toltecs/menu.h
diff --git a/engines/toltecs/animation.h b/engines/toltecs/animation.h
index 03aa18c..581934a 100644
--- a/engines/toltecs/animation.h
+++ b/engines/toltecs/animation.h
@@ -67,7 +67,7 @@ public:
// 262144
byte *_animBuffer;
- uint _resIndex;
+ uint16 _resIndex;
uint16 _width, _height;
uint16 _frameNumber, _frameCount;
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 0052d50..1d6a311 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -41,7 +41,7 @@ namespace Toltecs {
// This code is very experimental.
-Widget::Widget(ToltecsEngine *vm, int x, int y) : _vm(vm) {
+Widget::Widget(ToltecsEngine *vm, int16 x, int16 y) : _vm(vm) {
_rect.left = x;
_rect.top = y;
}
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index dd75d66..2ea9e1d 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -51,7 +51,7 @@ const byte kFontColorMenuActive = 255;
class Widget {
public:
- Widget(ToltecsEngine *vm, int x, int y);
+ Widget(ToltecsEngine *vm, int16 x, int16 y);
virtual ~Widget();
virtual void redraw();
virtual Widget *getHoveredWidget(int mouseX, int mouseY);
Commit: 284c358f7cab64b112770d66c090cb879897504e
https://github.com/scummvm/scummvm/commit/284c358f7cab64b112770d66c090cb879897504e
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Started implementing the menu from scratch
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 1d6a311..55cd755 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -39,212 +39,232 @@
namespace Toltecs {
-// This code is very experimental.
-
-Widget::Widget(ToltecsEngine *vm, int16 x, int16 y) : _vm(vm) {
- _rect.left = x;
- _rect.top = y;
-}
-
-Widget::~Widget() {
-}
-
-void Widget::redraw() {
-}
-
-Widget *Widget::getHoveredWidget(int mouseX, int mouseY) {
- if (_rect.contains(mouseX, mouseY))
- return this;
- else
- return NULL;
+MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
+ _background = new Graphics::Surface();
+ _background->create(520, 240, 1);
+ _currMenuID = kMenuIdNone;
+ _newMenuID = kMenuIdMain;
+ _currItemID = kItemIdNone;
+ _cfgText = true;
+ _cfgVoices = true;
}
-void Widget::calcDimensions() {
-}
-
-void Widget::setRect(Common::Rect rect) {
- _rect = rect;
-}
-
-void Widget::onMouseEnter() {
-}
-
-void Widget::onMouseLeave() {
-}
-
-void Widget::onMouseMove(int mouseX, int mouseY) {
-}
-
-LabelWidget::LabelWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags) :
- Widget(vm, x, y), _caption(caption), _flags(flags), _fontColor(kFontColorMenuDefault) {
-
- calcDimensions();
-
+MenuSystem::~MenuSystem() {
+ delete _background;
}
-LabelWidget::~LabelWidget() {
-}
+void MenuSystem::update() {
-void LabelWidget::redraw() {
- _vm->_screen->drawString(_rect.left, _rect.top, _fontColor, 14, (byte*)_caption.c_str(), -1, NULL, true);
-}
+ if (_currMenuID != _newMenuID) {
+ _currMenuID = _newMenuID;
+ debug("_currMenuID = %d", _currMenuID);
+ initMenu(_currMenuID);
+ }
-void LabelWidget::calcDimensions() {
- Font font(_vm->_res->load(14)->data);
- _rect.setWidth(font.getTextWidth((byte*)_caption.c_str()));
- _rect.setHeight(font.getHeight());
-}
+ handleEvents();
-void LabelWidget::setCaption(Common::String caption) {
- _caption = caption;
- calcDimensions();
-}
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen,
+ 640, 0, 0, 640, 400);
-void LabelWidget::setFontColor(byte fontColor) {
- _fontColor = fontColor;
-}
+ _vm->_system->delayMillis(5);
-void LabelWidget::onMouseEnter() {
- setFontColor(kFontColorMenuActive);
}
-void LabelWidget::onMouseLeave() {
- setFontColor(kFontColorMenuDefault);
-}
+void MenuSystem::handleEvents() {
+ Common::Event event;
+ Common::EventManager *eventMan = _vm->_system->getEventManager();
+ while (eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ break;
+ case Common::EVENT_QUIT:
+ // TODO: quitGame();
+ break;
+ case Common::EVENT_MOUSEMOVE:
+ handleMouseMove(event.mouse.x, event.mouse.y);
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ handleMouseClick(event.mouse.x, event.mouse.y);
+ break;
+ default:
+ break;
+ }
+ }
-VolumeControlWidget::VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags) :
- Widget(_vm, x, y), _activeWidget(NULL) {
-
- _label = new LabelWidget(vm, x, y, caption, flags);
- _up = new LabelWidget(vm, x + 350, y + 4, "[", flags);
- _down = new LabelWidget(vm, x + 350 + 24, y + 4, "]", flags);
- _indicator = new LabelWidget(vm, x + 350 + 24 + 24 + 8, y, "||||||||||", flags);
-
- _rect.setWidth(350 + 24 + 24 + 8 + 50);
- _rect.setHeight(20);
-
}
-VolumeControlWidget::~VolumeControlWidget() {
- delete _label;
- delete _up;
- delete _down;
- delete _indicator;
+void MenuSystem::addClickTextItem(ItemID id, int x, int y, int w, const byte *caption, byte defaultColor, byte activeColor) {
+ Item item;
+ item.id = id;
+ item.defaultColor = defaultColor;
+ item.activeColor = activeColor;
+ item.x = x;
+ item.y = y;
+ item.w = w;
+ setItemCaption(&item, caption);
+ _items.push_back(item);
}
-void VolumeControlWidget::redraw() {
- _label->redraw();
- _up->redraw();
- _down->redraw();
- _indicator->redraw();
+void MenuSystem::drawItem(ItemID itemID, bool active) {
+ Item *item = getItem(itemID);
+ if (item) {
+ byte color = active ? item->activeColor : item->defaultColor;
+ drawString(item->rect.left, item->rect.top, 0, color, (byte*)item->caption.c_str());
+ }
}
-Widget *VolumeControlWidget::getHoveredWidget(int mouseX, int mouseY) {
- return Widget::getHoveredWidget(mouseX, mouseY);
+void MenuSystem::handleMouseMove(int x, int y) {
+ ItemID newItemID = findItemAt(x, y);
+ if (_currItemID != newItemID) {
+ leaveItem(_currItemID);
+ _currItemID = newItemID;
+ enterItem(newItemID);
+ }
}
-void VolumeControlWidget::calcDimensions() {
+void MenuSystem::handleMouseClick(int x, int y) {
+ ItemID id = findItemAt(x, y);
+ clickItem(id);
}
-void VolumeControlWidget::onMouseEnter() {
- _label->setFontColor(kFontColorMenuActive);
- _indicator->setFontColor(kFontColorMenuActive);
- _activeWidget = NULL;
+ItemID MenuSystem::findItemAt(int x, int y) {
+ for (Common::Array<Item>::iterator iter = _items.begin(); iter != _items.end(); iter++) {
+ if ((*iter).rect.contains(x, y))
+ return (*iter).id;
+ }
+ return kItemIdNone;
}
-void VolumeControlWidget::onMouseLeave() {
- _label->setFontColor(kFontColorMenuDefault);
- _up->setFontColor(kFontColorMenuDefault);
- _down->setFontColor(kFontColorMenuDefault);
- _indicator->setFontColor(kFontColorMenuDefault);
+MenuSystem::Item *MenuSystem::getItem(ItemID id) {
+ for (Common::Array<Item>::iterator iter = _items.begin(); iter != _items.end(); iter++) {
+ if ((*iter).id == id)
+ return &(*iter);
+ }
+ return NULL;
}
-void VolumeControlWidget::onMouseMove(int mouseX, int mouseY) {
-
- Widget *hoveredWidget = NULL;
-
- hoveredWidget = _up->getHoveredWidget(mouseX, mouseY);
- if (!hoveredWidget)
- hoveredWidget = _down->getHoveredWidget(mouseX, mouseY);
+void MenuSystem::setItemCaption(Item *item, const byte *caption) {
+ Font font(_vm->_res->load(kFontResourceIndex)->data);
+ int width = font.getTextWidth((byte*)caption);
+ int height = font.getHeight();
+ item->rect = Common::Rect(item->x, item->y, item->x + width, item->y + height);
+ if (item->w) {
+ item->rect.translate(item->w - width / 2, 0);
+ debug("item->rect.width() = %d", item->rect.width());
+ }
+ item->caption = (const char*)caption;
+}
+
+void MenuSystem::initMenu(MenuID menuID) {
+
+ _items.clear();
+
+ switch (menuID) {
+ case kMenuIdMain:
+ drawString(0, 74, 320, 229, (byte*)"What can I do for you?");
+ addClickTextItem(kItemIdLoad, 0, 115, 320, (const byte*)"LOAD", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdSave, 0, 135, 320, (const byte*)"SAVE", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdToggleText, 0, 165, 320, (const byte*)"TEXT ON", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdToggleVoices, 0, 185, 320, (const byte*)"VOICES ON", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, (const byte*)"VOLUME", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdPlay, 0, 245, 320, (const byte*)"PLAY", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdQuit, 0, 275, 320, (const byte*)"QUIT", kFontColorMenuDefault, kFontColorMenuActive);
+ break;
+ case kMenuIdVolumes:
+ addClickTextItem(kItemIdCancel, 0, 275, 440, (const byte*)"CANCEL", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 440, (const byte*)"CANCEL", kFontColorMenuDefault, 253);
+ break;
+ default:
+ break;
+ }
- if (_activeWidget != hoveredWidget) {
- _activeWidget = hoveredWidget;
- if (!_activeWidget) {
- _up->setFontColor(kFontColorMenuDefault);
- _down->setFontColor(kFontColorMenuDefault);
- } else if (_activeWidget == _up) {
- _up->setFontColor(kFontColorMenuActive);
- _down->setFontColor(kFontColorMenuDefault);
- } else if (_activeWidget == _down) {
- _up->setFontColor(kFontColorMenuDefault);
- _down->setFontColor(kFontColorMenuActive);
- }
+ for (Common::Array<Item>::iterator iter = _items.begin(); iter != _items.end(); iter++) {
+ drawItem((*iter).id, false);
}
}
-MenuPage::MenuPage(Common::String caption) {
+void MenuSystem::enterItem(ItemID id) {
+ drawItem(id, true);
+}
+
+void MenuSystem::leaveItem(ItemID id) {
+ drawItem(id, false);
+}
+
+void MenuSystem::clickItem(ItemID id) {
+ Item *item = getItem(id);
+ switch (id) {
+ // Main menu
+ case kItemIdSave:
+ debug("kItemIdSave");
+ break;
+ case kItemIdLoad:
+ debug("kItemIdLoad");
+ break;
+ case kItemIdToggleText:
+ setCfgText(!_cfgText, true);
+ break;
+ case kItemIdToggleVoices:
+ setCfgVoices(!_cfgVoices, true);
+ break;
+ case kItemIdVolumesMenu:
+ debug("kItemIdVolumesMenu");
+ _newMenuID = kMenuIdVolumes;
+ break;
+ case kItemIdPlay:
+ debug("kItemIdPlay");
+ break;
+ case kItemIdQuit:
+ debug("kItemIdQuit");
+ break;
+ // Volumes menu
+ case kItemIdCancel:
+ _newMenuID = kMenuIdMain;
+ break;
+ // Save/Load menu
+ default:
+ break;
+ }
}
-MenuPage::~MenuPage() {
- // TODO: Delete widgets
+void MenuSystem::saveBackground() {
}
-void MenuPage::addWidget(Widget *widget) {
- _widgets.push_back(widget);
+void MenuSystem::restoreBackground() {
}
-void MenuPage::redraw() {
- for (WidgetArray::iterator iter = _widgets.begin(); iter != _widgets.end(); iter++) {
- (*iter)->redraw();
+void MenuSystem::drawString(int16 x, int16 y, int w, byte color, byte *text) {
+ if (w) {
+ Font font(_vm->_res->load(kFontResourceIndex)->data);
+ x = x + w - font.getTextWidth(text) / 2;
}
-}
-
-Widget *MenuPage::getHoveredWidget(int mouseX, int mouseY) {
- Widget *hoveredWidget = NULL;
- for (WidgetArray::iterator iter = _widgets.begin(); iter != _widgets.end() && !hoveredWidget; iter++) {
- hoveredWidget = (*iter)->getHoveredWidget(mouseX, mouseY);
+ _vm->_screen->drawString(x, y, color, kFontResourceIndex, text, -1, NULL, true);
+}
+
+void MenuSystem::setCfgText(bool value, bool active) {
+ if (_cfgText != value) {
+ Item *item = getItem(kItemIdToggleText);
+ _cfgText = value;
+ if (_cfgText)
+ setItemCaption(item, (const byte*)"TEXT ON");
+ else
+ setItemCaption(item, (const byte*)"TEXT OFF");
+ drawItem(kItemIdToggleText, true);
}
- return hoveredWidget;
}
-MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm), _activeWidget(NULL), _oldMouseX(-1), _oldMouseY(-1) {
- _page = new MenuPage("Welcome");
- _page->addWidget(new LabelWidget(_vm, 10, 10, "Load game", 0));
- _page->addWidget(new LabelWidget(_vm, 10, 35, "Save game", 0));
- _page->addWidget(new VolumeControlWidget(_vm, 10, 60, "Master volume", 0));
- _page->addWidget(new VolumeControlWidget(_vm, 10, 90, "Some other volume", 0));
-}
-
-MenuSystem::~MenuSystem() {
- delete _page;
-}
-
-void MenuSystem::update() {
-
- _page->redraw();
-
- if (_vm->_mouseX != _oldMouseX || _vm->_mouseY != _oldMouseY) {
-
- _oldMouseX = _vm->_mouseX;
- _oldMouseY = _vm->_mouseY;
-
- Widget *hoveredWidget = _page->getHoveredWidget(_vm->_mouseX, _vm->_mouseY);
- if (_activeWidget != hoveredWidget) {
- if (_activeWidget)
- _activeWidget->onMouseLeave();
- if (hoveredWidget)
- hoveredWidget->onMouseEnter();
- _activeWidget = hoveredWidget;
- }
-
- if (_activeWidget) {
- _activeWidget->onMouseMove(_vm->_mouseX, _vm->_mouseY);
- }
-
+void MenuSystem::setCfgVoices(bool value, bool active) {
+ if (_cfgVoices != value) {
+ Item *item = getItem(kItemIdToggleVoices);
+ _cfgVoices = value;
+ if (_cfgVoices)
+ setItemCaption(item, (const byte*)"VOICES ON");
+ else
+ setItemCaption(item, (const byte*)"VOICES OFF");
+ drawItem(kItemIdToggleVoices, true);
}
-
}
} // End of namespace Toltecs
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 2ea9e1d..9cb839a 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -46,74 +46,35 @@
namespace Toltecs {
-const byte kFontColorMenuDefault = 229;
-const byte kFontColorMenuActive = 255;
-
-class Widget {
-public:
- Widget(ToltecsEngine *vm, int16 x, int16 y);
- virtual ~Widget();
- virtual void redraw();
- virtual Widget *getHoveredWidget(int mouseX, int mouseY);
- virtual void calcDimensions();
- void setRect(Common::Rect rect);
- //virtual void setHilighted(bool active);
- virtual void onMouseEnter();
- virtual void onMouseLeave();
- virtual void onMouseMove(int mouseX, int mouseY);
-protected:
- ToltecsEngine *_vm;
- Common::Rect _rect;
- //bool _hilighted;
+const byte kFontColorMenuDefault = 229;
+const byte kFontColorMenuActive = 255;
+const uint kFontResourceIndex = 13;
+
+enum MenuID {
+ kMenuIdNone,
+ kMenuIdMain,
+ kMenuIdSave,
+ kMenuIdLoad,
+ kMenuIdVolumes
};
-const int kLabelCentered = 1 << 1;
-const int kLabelHideOnMovie = 1 << 2;
-
-class LabelWidget : public Widget {
-public:
- LabelWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags);
- ~LabelWidget();
- void redraw();
- void calcDimensions();
- void setCaption(Common::String caption);
- void setFontColor(byte fontColor);
- void onMouseEnter();
- void onMouseLeave();
-protected:
- Common::String _caption;
- uint _flags;
- byte _fontColor;
-};
-
-class VolumeControlWidget : public Widget {
-public:
- VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags);
- ~VolumeControlWidget();
- void redraw();
- Widget *getHoveredWidget(int mouseX, int mouseY);
- void calcDimensions();
- //void setHilighted(bool active);
- void onMouseEnter();
- void onMouseLeave();
- void onMouseMove(int mouseX, int mouseY);
-protected:
- uint _flags;
- LabelWidget *_label, *_up, *_down, *_indicator;
- Widget *_activeWidget;
-};
-
-class MenuPage {
-public:
- MenuPage(Common::String caption);
- ~MenuPage();
- void addWidget(Widget *widget);
- void redraw();
- Widget *getHoveredWidget(int mouseX, int mouseY);
-protected:
- typedef Common::Array<Widget*> WidgetArray;
- Common::String _caption;
- WidgetArray _widgets;
+enum ItemID {
+ kItemIdNone,
+ // Main menu
+ kItemIdSave,
+ kItemIdLoad,
+ kItemIdToggleText,
+ kItemIdToggleVoices,
+ kItemIdVolumesMenu,
+ kItemIdPlay,
+ kItemIdQuit,
+ // Volumes menu
+ // TODO: Up/down buttons
+ kItemIdDone,
+ kItemIdCancel,
+ // Save/load menu
+ // TODO
+ kMenuIdDummy
};
class MenuSystem {
@@ -123,15 +84,51 @@ public:
~MenuSystem();
void update();
+ void handleEvents();
protected:
+
+ struct Item {
+ Common::Rect rect;
+ ItemID id;
+ //const byte *caption;
+ Common::String caption;
+ byte defaultColor, activeColor;
+ int x, y, w;
+ };
+
ToltecsEngine *_vm;
+ Graphics::Surface *_background;
+
+ MenuID _currMenuID, _newMenuID;
+ ItemID _currItemID;
+
+ Common::Array<Item> _items;
+
+ bool _cfgText, _cfgVoices;
+
+ void addClickTextItem(ItemID id, int x, int y, int w, const byte *caption, byte defaultColor, byte activeColor);
+
+ void drawItem(ItemID itemID, bool active);
+ void handleMouseMove(int x, int y);
+ void handleMouseClick(int x, int y);
+
+ ItemID findItemAt(int x, int y);
+ Item *getItem(ItemID id);
+ void setItemCaption(Item *item, const byte *caption);
- //LabelWidget *label1, *label2;
- MenuPage *_page;
+ void initMenu(MenuID menuID);
+
+ void enterItem(ItemID id);
+ void leaveItem(ItemID id);
+ void clickItem(ItemID id);
- Widget *_activeWidget;
- int16 _oldMouseX, _oldMouseY;
+ void saveBackground();
+ void restoreBackground();
+ void drawString(int16 x, int16 y, int w, byte color, byte *text);
+
+ void setCfgText(bool value, bool active);
+ void setCfgVoices(bool value, bool active);
};
Commit: 3d0775bd8987c6d5a80da18a4d97eaf6d3adb77e
https://github.com/scummvm/scummvm/commit/3d0775bd8987c6d5a80da18a4d97eaf6d3adb77e
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: More work on the menu
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
engines/toltecs/screen.h
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 55cd755..a82477b 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -40,17 +40,35 @@
namespace Toltecs {
MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
- _background = new Graphics::Surface();
- _background->create(520, 240, 1);
_currMenuID = kMenuIdNone;
_newMenuID = kMenuIdMain;
_currItemID = kItemIdNone;
_cfgText = true;
_cfgVoices = true;
+ _cfgMasterVolume = 10;
+ _cfgVoicesVolume = 10;
+ _cfgMusicVolume = 10;
+ _cfgSoundFXVolume = 10;
+ _cfgBackgroundVolume = 10;
}
MenuSystem::~MenuSystem() {
+}
+
+int MenuSystem::run() {
+
+ _background = new Graphics::Surface();
+ _background->create(640, 400, 1);
+
+ memcpy(_background->pixels, _vm->_screen->_frontScreen, 640 * 400);
+
+ while (1) {
+ update();
+ _vm->updateScreen();
+ }
+
delete _background;
+
}
void MenuSystem::update() {
@@ -94,7 +112,7 @@ void MenuSystem::handleEvents() {
}
-void MenuSystem::addClickTextItem(ItemID id, int x, int y, int w, const byte *caption, byte defaultColor, byte activeColor) {
+void MenuSystem::addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const byte *caption, byte defaultColor, byte activeColor) {
Item item;
item.id = id;
item.defaultColor = defaultColor;
@@ -102,6 +120,7 @@ void MenuSystem::addClickTextItem(ItemID id, int x, int y, int w, const byte *ca
item.x = x;
item.y = y;
item.w = w;
+ item.fontNum = fontNum;
setItemCaption(&item, caption);
_items.push_back(item);
}
@@ -110,7 +129,7 @@ void MenuSystem::drawItem(ItemID itemID, bool active) {
Item *item = getItem(itemID);
if (item) {
byte color = active ? item->activeColor : item->defaultColor;
- drawString(item->rect.left, item->rect.top, 0, color, (byte*)item->caption.c_str());
+ drawString(item->rect.left, item->rect.top, 0, item->fontNum, color, (byte*)item->caption.c_str());
}
}
@@ -145,13 +164,12 @@ MenuSystem::Item *MenuSystem::getItem(ItemID id) {
}
void MenuSystem::setItemCaption(Item *item, const byte *caption) {
- Font font(_vm->_res->load(kFontResourceIndex)->data);
+ Font font(_vm->_res->load(_vm->_screen->getFontResIndex(item->fontNum))->data);
int width = font.getTextWidth((byte*)caption);
int height = font.getHeight();
item->rect = Common::Rect(item->x, item->y, item->x + width, item->y + height);
if (item->w) {
item->rect.translate(item->w - width / 2, 0);
- debug("item->rect.width() = %d", item->rect.width());
}
item->caption = (const char*)caption;
}
@@ -160,20 +178,43 @@ void MenuSystem::initMenu(MenuID menuID) {
_items.clear();
+ memcpy(_vm->_screen->_frontScreen, _background->pixels, 640 * 400);
+
switch (menuID) {
case kMenuIdMain:
- drawString(0, 74, 320, 229, (byte*)"What can I do for you?");
- addClickTextItem(kItemIdLoad, 0, 115, 320, (const byte*)"LOAD", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdSave, 0, 135, 320, (const byte*)"SAVE", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdToggleText, 0, 165, 320, (const byte*)"TEXT ON", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdToggleVoices, 0, 185, 320, (const byte*)"VOICES ON", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, (const byte*)"VOLUME", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdPlay, 0, 245, 320, (const byte*)"PLAY", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdQuit, 0, 275, 320, (const byte*)"QUIT", kFontColorMenuDefault, kFontColorMenuActive);
+ drawString(0, 74, 320, 1, 229, (byte*)"What can I do for you?");
+ addClickTextItem(kItemIdLoad, 0, 115, 320, 0, (const byte*)"LOAD", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdSave, 0, 135, 320, 0, (const byte*)"SAVE", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, (const byte*)"TEXT ON", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, (const byte*)"VOICES ON", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, 0, (const byte*)"VOLUME", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdPlay, 0, 245, 320, 0, (const byte*)"PLAY", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdQuit, 0, 275, 320, 0, (const byte*)"QUIT GAME", kFontColorMenuDefault, kFontColorMenuActive);
break;
case kMenuIdVolumes:
- addClickTextItem(kItemIdCancel, 0, 275, 440, (const byte*)"CANCEL", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdCancel, 0, 275, 440, (const byte*)"CANCEL", kFontColorMenuDefault, 253);
+ drawString(0, 74, 320, 1, 229, (byte*)"Adjust volume");
+ drawString(0, 130, 200, 0, 244, (byte*)"Master");
+ drawString(0, 155, 200, 0, 244, (byte*)"Voices");
+ drawString(0, 180, 200, 0, 244, (byte*)"Music");
+ drawString(0, 205, 200, 0, 244, (byte*)"Sound FX");
+ drawString(0, 230, 200, 0, 244, (byte*)"Background");
+ addClickTextItem(kItemIdDone, 0, 275, 200, 0, (const byte*)"DONE", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 440, 0, (const byte*)"CANCEL", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdMasterDown, 0, 130 + 25 * 0, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdVoicesDown, 0, 130 + 25 * 1, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdMusicDown, 0, 130 + 25 * 2, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdSoundFXDown, 0, 130 + 25 * 3, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdBackgroundDown, 0, 130 + 25 * 4, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdMasterUp, 0, 130 + 25 * 0, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdVoicesUp, 0, 130 + 25 * 1, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdMusicUp, 0, 130 + 25 * 2, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdSoundFXUp, 0, 130 + 25 * 3, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdBackgroundUp, 0, 130 + 25 * 4, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
+ drawVolumeBar(kItemIdMaster);
+ drawVolumeBar(kItemIdVoices);
+ drawVolumeBar(kItemIdMusic);
+ drawVolumeBar(kItemIdSoundFX);
+ drawVolumeBar(kItemIdBackground);
break;
default:
break;
@@ -220,6 +261,36 @@ void MenuSystem::clickItem(ItemID id) {
debug("kItemIdQuit");
break;
// Volumes menu
+ case kItemIdMasterUp:
+ changeVolumeBar(kItemIdMaster, +1);
+ break;
+ case kItemIdVoicesUp:
+ changeVolumeBar(kItemIdVoices, +1);
+ break;
+ case kItemIdMusicUp:
+ changeVolumeBar(kItemIdMusic, +1);
+ break;
+ case kItemIdSoundFXUp:
+ changeVolumeBar(kItemIdSoundFX, +1);
+ break;
+ case kItemIdBackgroundUp:
+ changeVolumeBar(kItemIdBackground, +1);
+ break;
+ case kItemIdMasterDown:
+ changeVolumeBar(kItemIdMaster, -1);
+ break;
+ case kItemIdVoicesDown:
+ changeVolumeBar(kItemIdVoices, -1);
+ break;
+ case kItemIdMusicDown:
+ changeVolumeBar(kItemIdMusic, -1);
+ break;
+ case kItemIdSoundFXDown:
+ changeVolumeBar(kItemIdSoundFX, -1);
+ break;
+ case kItemIdBackgroundDown:
+ changeVolumeBar(kItemIdBackground, -1);
+ break;
case kItemIdCancel:
_newMenuID = kMenuIdMain;
break;
@@ -235,12 +306,23 @@ void MenuSystem::saveBackground() {
void MenuSystem::restoreBackground() {
}
-void MenuSystem::drawString(int16 x, int16 y, int w, byte color, byte *text) {
+void MenuSystem::restoreRect(int x, int y, int w, int h) {
+ byte *src = (byte*)_background->getBasePtr(x, y);
+ byte *dst = _vm->_screen->_frontScreen + x + y * 640;
+ while (h--) {
+ memcpy(dst, src, w);
+ src += 640;
+ dst += 640;
+ }
+}
+
+void MenuSystem::drawString(int16 x, int16 y, int w, uint fontNum, byte color, byte *text) {
+ fontNum = _vm->_screen->getFontResIndex(fontNum);
if (w) {
- Font font(_vm->_res->load(kFontResourceIndex)->data);
+ Font font(_vm->_res->load(fontNum)->data);
x = x + w - font.getTextWidth(text) / 2;
}
- _vm->_screen->drawString(x, y, color, kFontResourceIndex, text, -1, NULL, true);
+ _vm->_screen->drawString(x, y, color, fontNum, text, -1, NULL, true);
}
void MenuSystem::setCfgText(bool value, bool active) {
@@ -267,4 +349,76 @@ void MenuSystem::setCfgVoices(bool value, bool active) {
}
}
+void MenuSystem::drawVolumeBar(ItemID itemID) {
+ int w = 440, y, volume;
+ char text[21];
+
+ switch (itemID) {
+ case kItemIdMaster:
+ y = 130 + 25 * 0;
+ volume = _cfgMasterVolume;
+ break;
+ case kItemIdVoices:
+ y = 130 + 25 * 1;
+ volume = _cfgVoicesVolume;
+ break;
+ case kItemIdMusic:
+ y = 130 + 25 * 2;
+ volume = _cfgMusicVolume;
+ break;
+ case kItemIdSoundFX:
+ y = 130 + 25 * 3;
+ volume = _cfgSoundFXVolume;
+ break;
+ case kItemIdBackground:
+ y = 130 + 25 * 4;
+ volume = _cfgBackgroundVolume;
+ break;
+ default:
+ return;
+ }
+
+ restoreRect(390, y, 100, 25);
+
+ for (int i = 0; i < volume; i++)
+ text[i] = '|';
+ text[volume] = 0;
+
+ drawString(0, y, w, 0, 246, (byte*)text);
+
+}
+
+void MenuSystem::changeVolumeBar(ItemID itemID, int delta) {
+
+ int *volume, newVolume;
+
+ switch (itemID) {
+ case kItemIdMaster:
+ volume = &_cfgMasterVolume;
+ break;
+ case kItemIdVoices:
+ volume = &_cfgVoicesVolume;
+ break;
+ case kItemIdMusic:
+ volume = &_cfgMusicVolume;
+ break;
+ case kItemIdSoundFX:
+ volume = &_cfgSoundFXVolume;
+ break;
+ case kItemIdBackground:
+ volume = &_cfgBackgroundVolume;
+ break;
+ default:
+ return;
+ }
+
+ newVolume = CLIP(*volume + delta, 0, 20);
+
+ if (newVolume != *volume) {
+ *volume = newVolume;
+ drawVolumeBar(itemID);
+ }
+
+}
+
} // End of namespace Toltecs
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 9cb839a..41541a8 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -48,7 +48,6 @@ namespace Toltecs {
const byte kFontColorMenuDefault = 229;
const byte kFontColorMenuActive = 255;
-const uint kFontResourceIndex = 13;
enum MenuID {
kMenuIdNone,
@@ -69,7 +68,21 @@ enum ItemID {
kItemIdPlay,
kItemIdQuit,
// Volumes menu
- // TODO: Up/down buttons
+ kItemIdMasterUp,
+ kItemIdVoicesUp,
+ kItemIdMusicUp,
+ kItemIdSoundFXUp,
+ kItemIdBackgroundUp,
+ kItemIdMasterDown,
+ kItemIdVoicesDown,
+ kItemIdMusicDown,
+ kItemIdSoundFXDown,
+ kItemIdBackgroundDown,
+ kItemIdMaster,
+ kItemIdVoices,
+ kItemIdMusic,
+ kItemIdSoundFX,
+ kItemIdBackground,
kItemIdDone,
kItemIdCancel,
// Save/load menu
@@ -83,6 +96,7 @@ public:
MenuSystem(ToltecsEngine *vm);
~MenuSystem();
+ int run();
void update();
void handleEvents();
@@ -95,6 +109,7 @@ protected:
Common::String caption;
byte defaultColor, activeColor;
int x, y, w;
+ uint fontNum;
};
ToltecsEngine *_vm;
@@ -106,8 +121,9 @@ protected:
Common::Array<Item> _items;
bool _cfgText, _cfgVoices;
+ int _cfgMasterVolume, _cfgVoicesVolume, _cfgMusicVolume, _cfgSoundFXVolume, _cfgBackgroundVolume;
- void addClickTextItem(ItemID id, int x, int y, int w, const byte *caption, byte defaultColor, byte activeColor);
+ void addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const byte *caption, byte defaultColor, byte activeColor);
void drawItem(ItemID itemID, bool active);
void handleMouseMove(int x, int y);
@@ -125,10 +141,13 @@ protected:
void saveBackground();
void restoreBackground();
- void drawString(int16 x, int16 y, int w, byte color, byte *text);
+ void restoreRect(int x, int y, int w, int h);
+ void drawString(int16 x, int16 y, int w, uint fontNum, byte color, byte *text);
void setCfgText(bool value, bool active);
void setCfgVoices(bool value, bool active);
+ void drawVolumeBar(ItemID itemID);
+ void changeVolumeBar(ItemID itemID, int delta);
};
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index ff27bb2..c9a7060 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -214,6 +214,8 @@ public:
void saveState(Common::WriteStream *out);
void loadState(Common::ReadStream *in);
+ uint getFontResIndex(int fontNum) const { return _fontResIndexArray[fontNum]; }
+
//protected:
public:
Commit: 28c74ff3b4c65be64636d0d679a88acc3fd23f84
https://github.com/scummvm/scummvm/commit/28c74ff3b4c65be64636d0d679a88acc3fd23f84
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: More work on the menu; started with the saveload menu page and fixed some early bugs
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index a82477b..62ff65e 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -34,6 +34,7 @@
#include "toltecs/toltecs.h"
#include "toltecs/menu.h"
+#include "toltecs/palette.h"
#include "toltecs/resource.h"
#include "toltecs/screen.h"
@@ -41,6 +42,7 @@ namespace Toltecs {
MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
_currMenuID = kMenuIdNone;
+ //_newMenuID = kMenuIdLoad;
_newMenuID = kMenuIdMain;
_currItemID = kItemIdNone;
_cfgText = true;
@@ -60,7 +62,15 @@ int MenuSystem::run() {
_background = new Graphics::Surface();
_background->create(640, 400, 1);
+ _top = 30 - _vm->_guiHeight / 2;
+
+ memset(_vm->_screen->_frontScreen, 250, 640 * 400);
+
memcpy(_background->pixels, _vm->_screen->_frontScreen, 640 * 400);
+
+ _vm->_palette->buildColorTransTable(0, 16, 7);
+
+ shadeRect(60, 39, 520, 246, 30, 94);
while (1) {
update();
@@ -129,7 +139,7 @@ void MenuSystem::drawItem(ItemID itemID, bool active) {
Item *item = getItem(itemID);
if (item) {
byte color = active ? item->activeColor : item->defaultColor;
- drawString(item->rect.left, item->rect.top, 0, item->fontNum, color, (byte*)item->caption.c_str());
+ drawString(item->rect.left, item->y, 0, item->fontNum, color, (byte*)item->caption.c_str());
}
}
@@ -167,7 +177,7 @@ void MenuSystem::setItemCaption(Item *item, const byte *caption) {
Font font(_vm->_res->load(_vm->_screen->getFontResIndex(item->fontNum))->data);
int width = font.getTextWidth((byte*)caption);
int height = font.getHeight();
- item->rect = Common::Rect(item->x, item->y, item->x + width, item->y + height);
+ item->rect = Common::Rect(item->x, item->y - height, item->x + width, item->y);
if (item->w) {
item->rect.translate(item->w - width / 2, 0);
}
@@ -191,6 +201,21 @@ void MenuSystem::initMenu(MenuID menuID) {
addClickTextItem(kItemIdPlay, 0, 245, 320, 0, (const byte*)"PLAY", kFontColorMenuDefault, kFontColorMenuActive);
addClickTextItem(kItemIdQuit, 0, 275, 320, 0, (const byte*)"QUIT GAME", kFontColorMenuDefault, kFontColorMenuActive);
break;
+ case kMenuIdLoad:
+ drawString(0, 74, 320, 1, 229, (byte*)"Load game");
+ addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, (const byte*)"^", 255, 253);
+ addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, (const byte*)"\\", 255, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 320, 0, (const byte*)"CANCEL", 255, 253);
+ addClickTextItem(kItemIdSavegame1, 0, 115 + 20 * 0, 300, 0, (const byte*)"SAVEGAME 1", 231, 234);
+ addClickTextItem(kItemIdSavegame2, 0, 115 + 20 * 1, 300, 0, (const byte*)"SAVEGAME 2", 231, 234);
+ addClickTextItem(kItemIdSavegame3, 0, 115 + 20 * 2, 300, 0, (const byte*)"SAVEGAME 3", 231, 234);
+ addClickTextItem(kItemIdSavegame4, 0, 115 + 20 * 3, 300, 0, (const byte*)"SAVEGAME 4", 231, 234);
+ addClickTextItem(kItemIdSavegame5, 0, 115 + 20 * 4, 300, 0, (const byte*)"SAVEGAME 5", 231, 234);
+ addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, (const byte*)"SAVEGAME 6", 231, 234);
+ addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, (const byte*)"SAVEGAME 7", 231, 234);
+ initSavegames();
+ setSavegameCaptions();
+ break;
case kMenuIdVolumes:
drawString(0, 74, 320, 1, 229, (byte*)"Adjust volume");
drawString(0, 130, 200, 0, 244, (byte*)"Master");
@@ -243,12 +268,17 @@ void MenuSystem::clickItem(ItemID id) {
break;
case kItemIdLoad:
debug("kItemIdLoad");
+ _newMenuID = kMenuIdLoad;
break;
case kItemIdToggleText:
setCfgText(!_cfgText, true);
+ if (!_cfgVoices && !_cfgText)
+ setCfgVoices(true, false);
break;
case kItemIdToggleVoices:
setCfgVoices(!_cfgVoices, true);
+ if (!_cfgVoices && !_cfgText)
+ setCfgText(true, false);
break;
case kItemIdVolumesMenu:
debug("kItemIdVolumesMenu");
@@ -295,6 +325,14 @@ void MenuSystem::clickItem(ItemID id) {
_newMenuID = kMenuIdMain;
break;
// Save/Load menu
+ case kItemIdSavegame1:
+ case kItemIdSavegame2:
+ case kItemIdSavegame3:
+ case kItemIdSavegame4:
+ case kItemIdSavegame5:
+ case kItemIdSavegame6:
+ clickSavegameItem(id);
+ break;
default:
break;
}
@@ -316,19 +354,109 @@ void MenuSystem::restoreRect(int x, int y, int w, int h) {
}
}
+void MenuSystem::shadeRect(int x, int y, int w, int h, byte color1, byte color2) {
+ byte *src = (byte*)_background->getBasePtr(x, y);
+ for (int xc = 0; xc < w; xc++) {
+ src[xc] = color1;
+ //src[xc] = 46;
+ }
+ src += 640;
+ w -= 2;
+ h -= 2;
+ while (h--) {
+ src[0] = color2;
+ src[w + 1] = color2;
+ for (int xc = 1; xc < w; xc++) {
+ src[xc] = _vm->_palette->getColorTransPixel(src[xc]);
+ }
+ src += 640;
+ }
+}
+
void MenuSystem::drawString(int16 x, int16 y, int w, uint fontNum, byte color, byte *text) {
fontNum = _vm->_screen->getFontResIndex(fontNum);
+ Font font(_vm->_res->load(fontNum)->data);
if (w) {
- Font font(_vm->_res->load(fontNum)->data);
x = x + w - font.getTextWidth(text) / 2;
}
- _vm->_screen->drawString(x, y, color, fontNum, text, -1, NULL, true);
+ _vm->_screen->drawString(x, y - font.getHeight(), color, fontNum, text, -1, NULL, true);
+}
+
+void MenuSystem::initSavegames() {
+
+ _savegameListTopIndex = 0;
+ _savegames.clear();
+
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Toltecs::ToltecsEngine::SaveHeader header;
+ Common::String pattern = _vm->getTargetName();
+ pattern += ".???";
+
+ Common::StringList filenames;
+ filenames = saveFileMan->listSavefiles(pattern.c_str());
+ Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ if (_vm->readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ _savegames.push_back(SavegameItem(*file, header.description));
+ debug("%s -> %s", file->c_str(), header.description.c_str());
+ }
+ delete in;
+ }
+ }
+
+}
+
+void MenuSystem::setSavegameCaptions() {
+ int index = _savegameListTopIndex;
+ setItemCaption(getItem(kItemIdSavegame1), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
+ setItemCaption(getItem(kItemIdSavegame2), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
+ setItemCaption(getItem(kItemIdSavegame3), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
+ setItemCaption(getItem(kItemIdSavegame4), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
+ setItemCaption(getItem(kItemIdSavegame5), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
+ setItemCaption(getItem(kItemIdSavegame6), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
+ setItemCaption(getItem(kItemIdSavegame7), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
+}
+
+void MenuSystem::clickSavegameItem(ItemID id) {
+ if (_currMenuID == kMenuIdLoad) {
+ SavegameItem *savegameItem;
+ switch (id) {
+ case kItemIdSavegame1:
+ savegameItem = &_savegames[_savegameListTopIndex + 0];
+ break;
+ case kItemIdSavegame2:
+ savegameItem = &_savegames[_savegameListTopIndex + 1];
+ break;
+ case kItemIdSavegame3:
+ savegameItem = &_savegames[_savegameListTopIndex + 2];
+ break;
+ case kItemIdSavegame4:
+ savegameItem = &_savegames[_savegameListTopIndex + 3];
+ break;
+ case kItemIdSavegame5:
+ savegameItem = &_savegames[_savegameListTopIndex + 4];
+ break;
+ case kItemIdSavegame6:
+ savegameItem = &_savegames[_savegameListTopIndex + 5];
+ break;
+ default:
+ return;
+ }
+
+ debug("filename = [%s]; description = [%s]", savegameItem->_filename.c_str(), savegameItem->_description.c_str());
+
+ } else {
+ }
}
void MenuSystem::setCfgText(bool value, bool active) {
if (_cfgText != value) {
Item *item = getItem(kItemIdToggleText);
_cfgText = value;
+ restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
if (_cfgText)
setItemCaption(item, (const byte*)"TEXT ON");
else
@@ -341,6 +469,7 @@ void MenuSystem::setCfgVoices(bool value, bool active) {
if (_cfgVoices != value) {
Item *item = getItem(kItemIdToggleVoices);
_cfgVoices = value;
+ restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
if (_cfgVoices)
setItemCaption(item, (const byte*)"VOICES ON");
else
@@ -378,7 +507,8 @@ void MenuSystem::drawVolumeBar(ItemID itemID) {
return;
}
- restoreRect(390, y, 100, 25);
+ Font font(_vm->_res->load(_vm->_screen->getFontResIndex(1))->data);
+ restoreRect(390, y - font.getHeight(), 100, 25);
for (int i = 0; i < volume; i++)
text[i] = '|';
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 41541a8..2709acf 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -86,6 +86,15 @@ enum ItemID {
kItemIdDone,
kItemIdCancel,
// Save/load menu
+ kItemIdSavegameUp,
+ kItemIdSavegameDown,
+ kItemIdSavegame1,
+ kItemIdSavegame2,
+ kItemIdSavegame3,
+ kItemIdSavegame4,
+ kItemIdSavegame5,
+ kItemIdSavegame6,
+ kItemIdSavegame7,
// TODO
kMenuIdDummy
};
@@ -111,14 +120,26 @@ protected:
int x, y, w;
uint fontNum;
};
+
+ struct SavegameItem {
+ Common::String _filename;
+ Common::String _description;
+ SavegameItem()
+ : _filename(""), _description("") {}
+ SavegameItem(Common::String filename, Common::String description)
+ : _filename(filename), _description(description) {}
+ };
ToltecsEngine *_vm;
Graphics::Surface *_background;
MenuID _currMenuID, _newMenuID;
ItemID _currItemID;
+ int _top;
+ int _savegameListTopIndex;
Common::Array<Item> _items;
+ Common::Array<SavegameItem> _savegames;
bool _cfgText, _cfgVoices;
int _cfgMasterVolume, _cfgVoicesVolume, _cfgMusicVolume, _cfgSoundFXVolume, _cfgBackgroundVolume;
@@ -142,8 +163,12 @@ protected:
void saveBackground();
void restoreBackground();
void restoreRect(int x, int y, int w, int h);
+ void shadeRect(int x, int y, int w, int h, byte color1, byte color2);
void drawString(int16 x, int16 y, int w, uint fontNum, byte color, byte *text);
-
+
+ void initSavegames();
+ void setSavegameCaptions();
+ void clickSavegameItem(ItemID id);
void setCfgText(bool value, bool active);
void setCfgVoices(bool value, bool active);
void drawVolumeBar(ItemID itemID);
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index b425af8..e870137 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -75,6 +75,7 @@ public:
const ToltecsGameDescription *_gameDescription;
uint32 getFeatures() const;
Common::Language getLanguage() const;
+ const Common::String& getTargetName() const { return _targetName; }
void loadScene(uint resIndex);
Commit: d80cc853471a41be4728dac450f61ec2b8949e45
https://github.com/scummvm/scummvm/commit/d80cc853471a41be4728dac450f61ec2b8949e45
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: More work on the menu; started the savegame page and implemented editing of the savegame description
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 62ff65e..1a7c5a4 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -42,9 +42,11 @@ namespace Toltecs {
MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
_currMenuID = kMenuIdNone;
- //_newMenuID = kMenuIdLoad;
_newMenuID = kMenuIdMain;
+ //_newMenuID = kMenuIdLoad;
+ _newMenuID = kMenuIdSave;
_currItemID = kItemIdNone;
+ _editingDescription = false;
_cfgText = true;
_cfgVoices = true;
_cfgMasterVolume = 10;
@@ -105,6 +107,7 @@ void MenuSystem::handleEvents() {
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
+ handleKeyDown(event.kbd);
break;
case Common::EVENT_QUIT:
// TODO: quitGame();
@@ -144,17 +147,44 @@ void MenuSystem::drawItem(ItemID itemID, bool active) {
}
void MenuSystem::handleMouseMove(int x, int y) {
- ItemID newItemID = findItemAt(x, y);
- if (_currItemID != newItemID) {
- leaveItem(_currItemID);
- _currItemID = newItemID;
- enterItem(newItemID);
+ if (!_editingDescription) {
+ ItemID newItemID = findItemAt(x, y);
+ if (_currItemID != newItemID) {
+ leaveItem(_currItemID);
+ _currItemID = newItemID;
+ enterItem(newItemID);
+ }
}
}
void MenuSystem::handleMouseClick(int x, int y) {
- ItemID id = findItemAt(x, y);
- clickItem(id);
+ if (!_editingDescription) {
+ ItemID id = findItemAt(x, y);
+ clickItem(id);
+ }
+}
+
+void MenuSystem::handleKeyDown(const Common::KeyState& kbd) {
+ if (_editingDescription) {
+ if (kbd.keycode >= Common::KEYCODE_SPACE && kbd.keycode <= Common::KEYCODE_z) {
+ debug("ascii = %c", kbd.ascii);
+ _editingDescriptionItem->caption += kbd.ascii;
+ restoreRect(_editingDescriptionItem->rect.left, _editingDescriptionItem->rect.top,
+ _editingDescriptionItem->rect.width() + 1, _editingDescriptionItem->rect.height() - 2);
+ setItemCaption(_editingDescriptionItem, (const byte*)_editingDescriptionItem->caption.c_str());
+ drawItem(_editingDescriptionID, true);
+ } else if (kbd.keycode == Common::KEYCODE_BACKSPACE) {
+ debug("backspace");
+ _editingDescriptionItem->caption.deleteLastChar();
+ restoreRect(_editingDescriptionItem->rect.left, _editingDescriptionItem->rect.top,
+ _editingDescriptionItem->rect.width() + 1, _editingDescriptionItem->rect.height() - 2);
+ setItemCaption(_editingDescriptionItem, (const byte*)_editingDescriptionItem->caption.c_str());
+ drawItem(_editingDescriptionID, true);
+ } else if (kbd.keycode == Common::KEYCODE_RETURN) {
+ debug("return");
+ _editingDescription = false;
+ }
+ }
}
ItemID MenuSystem::findItemAt(int x, int y) {
@@ -216,6 +246,22 @@ void MenuSystem::initMenu(MenuID menuID) {
initSavegames();
setSavegameCaptions();
break;
+ case kMenuIdSave:
+ drawString(0, 74, 320, 1, 229, (byte*)"Save game");
+ addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, (const byte*)"^", 255, 253);
+ addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, (const byte*)"\\", 255, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 320, 0, (const byte*)"CANCEL", 255, 253);
+ addClickTextItem(kItemIdSavegame1, 0, 115 + 20 * 0, 300, 0, (const byte*)"SAVEGAME 1", 231, 234);
+ addClickTextItem(kItemIdSavegame2, 0, 115 + 20 * 1, 300, 0, (const byte*)"SAVEGAME 2", 231, 234);
+ addClickTextItem(kItemIdSavegame3, 0, 115 + 20 * 2, 300, 0, (const byte*)"SAVEGAME 3", 231, 234);
+ addClickTextItem(kItemIdSavegame4, 0, 115 + 20 * 3, 300, 0, (const byte*)"SAVEGAME 4", 231, 234);
+ addClickTextItem(kItemIdSavegame5, 0, 115 + 20 * 4, 300, 0, (const byte*)"SAVEGAME 5", 231, 234);
+ addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, (const byte*)"SAVEGAME 6", 231, 234);
+ addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, (const byte*)"SAVEGAME 7", 231, 234);
+ initSavegames();
+ _savegames.push_back(SavegameItem("", Common::String::printf("GAME %03d", _savegames.size() + 1)));
+ setSavegameCaptions();
+ break;
case kMenuIdVolumes:
drawString(0, 74, 320, 1, 229, (byte*)"Adjust volume");
drawString(0, 130, 200, 0, 244, (byte*)"Master");
@@ -264,10 +310,9 @@ void MenuSystem::clickItem(ItemID id) {
switch (id) {
// Main menu
case kItemIdSave:
- debug("kItemIdSave");
+ _newMenuID = kMenuIdSave;
break;
case kItemIdLoad:
- debug("kItemIdLoad");
_newMenuID = kMenuIdLoad;
break;
case kItemIdToggleText:
@@ -410,7 +455,7 @@ void MenuSystem::initSavegames() {
}
void MenuSystem::setSavegameCaptions() {
- int index = _savegameListTopIndex;
+ uint index = _savegameListTopIndex;
setItemCaption(getItem(kItemIdSavegame1), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
setItemCaption(getItem(kItemIdSavegame2), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
setItemCaption(getItem(kItemIdSavegame3), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
@@ -445,10 +490,14 @@ void MenuSystem::clickSavegameItem(ItemID id) {
default:
return;
}
-
debug("filename = [%s]; description = [%s]", savegameItem->_filename.c_str(), savegameItem->_description.c_str());
-
} else {
+ _editingDescription = true;
+ _editingDescriptionItem = getItem(id);
+ _editingDescriptionID = id;
+ _editingDescriptionItem->activeColor = 230; // TODO: Correct color
+ _editingDescriptionItem->defaultColor = 230;
+ drawItem(_editingDescriptionID, true);
}
}
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 2709acf..4832e0c 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -137,6 +137,9 @@ protected:
ItemID _currItemID;
int _top;
int _savegameListTopIndex;
+ bool _editingDescription;
+ ItemID _editingDescriptionID;
+ Item *_editingDescriptionItem;
Common::Array<Item> _items;
Common::Array<SavegameItem> _savegames;
@@ -149,6 +152,7 @@ protected:
void drawItem(ItemID itemID, bool active);
void handleMouseMove(int x, int y);
void handleMouseClick(int x, int y);
+ void handleKeyDown(const Common::KeyState& kbd);
ItemID findItemAt(int x, int y);
Item *getItem(ItemID id);
Commit: 145a696fe0a92a7ba914a14428f2ab526ad04531
https://github.com/scummvm/scummvm/commit/145a696fe0a92a7ba914a14428f2ab526ad04531
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Implemented scrolling in the savegame list
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 1a7c5a4..3b703db 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -43,8 +43,8 @@ namespace Toltecs {
MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
_currMenuID = kMenuIdNone;
_newMenuID = kMenuIdMain;
- //_newMenuID = kMenuIdLoad;
_newMenuID = kMenuIdSave;
+ _newMenuID = kMenuIdLoad;
_currItemID = kItemIdNone;
_editingDescription = false;
_cfgText = true;
@@ -167,22 +167,20 @@ void MenuSystem::handleMouseClick(int x, int y) {
void MenuSystem::handleKeyDown(const Common::KeyState& kbd) {
if (_editingDescription) {
if (kbd.keycode >= Common::KEYCODE_SPACE && kbd.keycode <= Common::KEYCODE_z) {
- debug("ascii = %c", kbd.ascii);
_editingDescriptionItem->caption += kbd.ascii;
restoreRect(_editingDescriptionItem->rect.left, _editingDescriptionItem->rect.top,
_editingDescriptionItem->rect.width() + 1, _editingDescriptionItem->rect.height() - 2);
setItemCaption(_editingDescriptionItem, (const byte*)_editingDescriptionItem->caption.c_str());
drawItem(_editingDescriptionID, true);
} else if (kbd.keycode == Common::KEYCODE_BACKSPACE) {
- debug("backspace");
_editingDescriptionItem->caption.deleteLastChar();
restoreRect(_editingDescriptionItem->rect.left, _editingDescriptionItem->rect.top,
_editingDescriptionItem->rect.width() + 1, _editingDescriptionItem->rect.height() - 2);
setItemCaption(_editingDescriptionItem, (const byte*)_editingDescriptionItem->caption.c_str());
drawItem(_editingDescriptionID, true);
} else if (kbd.keycode == Common::KEYCODE_RETURN) {
- debug("return");
_editingDescription = false;
+ _newMenuID = kMenuIdMain;
}
}
}
@@ -264,7 +262,7 @@ void MenuSystem::initMenu(MenuID menuID) {
break;
case kMenuIdVolumes:
drawString(0, 74, 320, 1, 229, (byte*)"Adjust volume");
- drawString(0, 130, 200, 0, 244, (byte*)"Master");
+ drawString(0, 130, 200, 0, 246, (byte*)"Master");
drawString(0, 155, 200, 0, 244, (byte*)"Voices");
drawString(0, 180, 200, 0, 244, (byte*)"Music");
drawString(0, 205, 200, 0, 244, (byte*)"Sound FX");
@@ -376,8 +374,18 @@ void MenuSystem::clickItem(ItemID id) {
case kItemIdSavegame4:
case kItemIdSavegame5:
case kItemIdSavegame6:
+ case kItemIdSavegame7:
clickSavegameItem(id);
break;
+ case kItemIdDone:
+ _newMenuID = kMenuIdMain;
+ break;
+ case kItemIdSavegameUp:
+ scrollSavegames(-6);
+ break;
+ case kItemIdSavegameDown:
+ scrollSavegames(+6);
+ break;
default:
break;
}
@@ -452,6 +460,20 @@ void MenuSystem::initSavegames() {
}
}
+ // DEBUG: Add some more items
+ _savegames.push_back(SavegameItem("abc", "Test 1"));
+ _savegames.push_back(SavegameItem("abc", "Test 2"));
+ _savegames.push_back(SavegameItem("abc", "Test 3"));
+ _savegames.push_back(SavegameItem("abc", "Test 4"));
+ _savegames.push_back(SavegameItem("abc", "Test 5"));
+ _savegames.push_back(SavegameItem("abc", "Test 6"));
+ _savegames.push_back(SavegameItem("abc", "Test 7"));
+ _savegames.push_back(SavegameItem("abc", "Test 8"));
+ _savegames.push_back(SavegameItem("abc", "Test 9"));
+ _savegames.push_back(SavegameItem("abc", "Test 10"));
+ _savegames.push_back(SavegameItem("abc", "Test 11"));
+ _savegames.push_back(SavegameItem("abc", "Test 12"));
+
}
void MenuSystem::setSavegameCaptions() {
@@ -465,6 +487,20 @@ void MenuSystem::setSavegameCaptions() {
setItemCaption(getItem(kItemIdSavegame7), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
}
+void MenuSystem::scrollSavegames(int delta) {
+ int newPos = CLIP<int>(_savegameListTopIndex + delta, 0, _savegames.size() - 1);
+ _savegameListTopIndex = newPos;
+ restoreRect(80, 92, 440, 140);
+ setSavegameCaptions();
+ drawItem(kItemIdSavegame1, false);
+ drawItem(kItemIdSavegame2, false);
+ drawItem(kItemIdSavegame3, false);
+ drawItem(kItemIdSavegame4, false);
+ drawItem(kItemIdSavegame5, false);
+ drawItem(kItemIdSavegame6, false);
+ drawItem(kItemIdSavegame7, false);
+}
+
void MenuSystem::clickSavegameItem(ItemID id) {
if (_currMenuID == kMenuIdLoad) {
SavegameItem *savegameItem;
@@ -487,6 +523,9 @@ void MenuSystem::clickSavegameItem(ItemID id) {
case kItemIdSavegame6:
savegameItem = &_savegames[_savegameListTopIndex + 5];
break;
+ case kItemIdSavegame7:
+ savegameItem = &_savegames[_savegameListTopIndex + 6];
+ break;
default:
return;
}
@@ -495,8 +534,8 @@ void MenuSystem::clickSavegameItem(ItemID id) {
_editingDescription = true;
_editingDescriptionItem = getItem(id);
_editingDescriptionID = id;
- _editingDescriptionItem->activeColor = 230; // TODO: Correct color
- _editingDescriptionItem->defaultColor = 230;
+ _editingDescriptionItem->activeColor = 249;
+ _editingDescriptionItem->defaultColor = 249;
drawItem(_editingDescriptionID, true);
}
}
@@ -506,10 +545,7 @@ void MenuSystem::setCfgText(bool value, bool active) {
Item *item = getItem(kItemIdToggleText);
_cfgText = value;
restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
- if (_cfgText)
- setItemCaption(item, (const byte*)"TEXT ON");
- else
- setItemCaption(item, (const byte*)"TEXT OFF");
+ setItemCaption(item, _cfgText ? (const byte*)"TEXT ON" : (const byte*)"TEXT OFF");
drawItem(kItemIdToggleText, true);
}
}
@@ -519,10 +555,7 @@ void MenuSystem::setCfgVoices(bool value, bool active) {
Item *item = getItem(kItemIdToggleVoices);
_cfgVoices = value;
restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
- if (_cfgVoices)
- setItemCaption(item, (const byte*)"VOICES ON");
- else
- setItemCaption(item, (const byte*)"VOICES OFF");
+ setItemCaption(item, _cfgVoices ? (const byte*)"VOICES ON" : (const byte*)"VOICES OFF");
drawItem(kItemIdToggleVoices, true);
}
}
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 4832e0c..7ed15f7 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -172,6 +172,7 @@ protected:
void initSavegames();
void setSavegameCaptions();
+ void scrollSavegames(int delta);
void clickSavegameItem(ItemID id);
void setCfgText(bool value, bool active);
void setCfgVoices(bool value, bool active);
Commit: 54cb86950c3fd456d873ab43ff527fda294ad50e
https://github.com/scummvm/scummvm/commit/54cb86950c3fd456d873ab43ff527fda294ad50e
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Fixed odd bug in drawChar (I subtracted 2 from the font height before, though I don't recall why exactly I did that; now I use the font height as-is)
Changed paths:
engines/toltecs/screen.cpp
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 1abb057..6ac916e 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -617,10 +617,11 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
int16 charWidth, charHeight;
byte *charData;
- dest += x + (y * 640);
+ dest += x + y * 640;
charWidth = font.getCharWidth(ch);
- charHeight = font.getHeight() - 2;
+ //charHeight = font.getHeight() - 2;//Why was this here?!
+ charHeight = font.getHeight();
charData = font.getCharData(ch);
while (charHeight--) {
Commit: 4c7cef996afd2bf62f4085b8fffcedea13e28ca7
https://github.com/scummvm/scummvm/commit/4c7cef996afd2bf62f4085b8fffcedea13e28ca7
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Misc fixes in the menu system
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 3b703db..5c770ac 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -221,13 +221,13 @@ void MenuSystem::initMenu(MenuID menuID) {
switch (menuID) {
case kMenuIdMain:
drawString(0, 74, 320, 1, 229, (byte*)"What can I do for you?");
- addClickTextItem(kItemIdLoad, 0, 115, 320, 0, (const byte*)"LOAD", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdSave, 0, 135, 320, 0, (const byte*)"SAVE", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, (const byte*)"TEXT ON", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, (const byte*)"VOICES ON", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, 0, (const byte*)"VOLUME", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdPlay, 0, 245, 320, 0, (const byte*)"PLAY", kFontColorMenuDefault, kFontColorMenuActive);
- addClickTextItem(kItemIdQuit, 0, 275, 320, 0, (const byte*)"QUIT GAME", kFontColorMenuDefault, kFontColorMenuActive);
+ addClickTextItem(kItemIdLoad, 0, 115, 320, 0, (const byte*)"LOAD", 229, 255);
+ addClickTextItem(kItemIdSave, 0, 135, 320, 0, (const byte*)"SAVE", 229, 255);
+ addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, (const byte*)"TEXT ON", 229, 255);
+ addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, (const byte*)"VOICES ON", 229, 255);
+ addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, 0, (const byte*)"VOLUME", 229, 255);
+ addClickTextItem(kItemIdPlay, 0, 245, 320, 0, (const byte*)"PLAY", 229, 255);
+ addClickTextItem(kItemIdQuit, 0, 275, 320, 0, (const byte*)"QUIT GAME", 229, 255);
break;
case kMenuIdLoad:
drawString(0, 74, 320, 1, 229, (byte*)"Load game");
@@ -267,18 +267,18 @@ void MenuSystem::initMenu(MenuID menuID) {
drawString(0, 180, 200, 0, 244, (byte*)"Music");
drawString(0, 205, 200, 0, 244, (byte*)"Sound FX");
drawString(0, 230, 200, 0, 244, (byte*)"Background");
- addClickTextItem(kItemIdDone, 0, 275, 200, 0, (const byte*)"DONE", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdCancel, 0, 275, 440, 0, (const byte*)"CANCEL", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdMasterDown, 0, 130 + 25 * 0, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdVoicesDown, 0, 130 + 25 * 1, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdMusicDown, 0, 130 + 25 * 2, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdSoundFXDown, 0, 130 + 25 * 3, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdBackgroundDown, 0, 130 + 25 * 4, 348, 1, (const byte*)"[", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdMasterUp, 0, 130 + 25 * 0, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdVoicesUp, 0, 130 + 25 * 1, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdMusicUp, 0, 130 + 25 * 2, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdSoundFXUp, 0, 130 + 25 * 3, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
- addClickTextItem(kItemIdBackgroundUp, 0, 130 + 25 * 4, 372, 1, (const byte*)"]", kFontColorMenuDefault, 253);
+ addClickTextItem(kItemIdDone, 0, 275, 200, 0, (const byte*)"DONE", 229, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 440, 0, (const byte*)"CANCEL", 229, 253);
+ addClickTextItem(kItemIdMasterDown, 0, 130 + 25 * 0, 348, 1, (const byte*)"[", 229, 253);
+ addClickTextItem(kItemIdVoicesDown, 0, 130 + 25 * 1, 348, 1, (const byte*)"[", 229, 253);
+ addClickTextItem(kItemIdMusicDown, 0, 130 + 25 * 2, 348, 1, (const byte*)"[", 229, 253);
+ addClickTextItem(kItemIdSoundFXDown, 0, 130 + 25 * 3, 348, 1, (const byte*)"[", 229, 253);
+ addClickTextItem(kItemIdBackgroundDown, 0, 130 + 25 * 4, 348, 1, (const byte*)"[", 229, 253);
+ addClickTextItem(kItemIdMasterUp, 0, 130 + 25 * 0, 372, 1, (const byte*)"]", 229, 253);
+ addClickTextItem(kItemIdVoicesUp, 0, 130 + 25 * 1, 372, 1, (const byte*)"]", 229, 253);
+ addClickTextItem(kItemIdMusicUp, 0, 130 + 25 * 2, 372, 1, (const byte*)"]", 229, 253);
+ addClickTextItem(kItemIdSoundFXUp, 0, 130 + 25 * 3, 372, 1, (const byte*)"]", 229, 253);
+ addClickTextItem(kItemIdBackgroundUp, 0, 130 + 25 * 4, 372, 1, (const byte*)"]", 229, 253);
drawVolumeBar(kItemIdMaster);
drawVolumeBar(kItemIdVoices);
drawVolumeBar(kItemIdMusic);
@@ -391,12 +391,6 @@ void MenuSystem::clickItem(ItemID id) {
}
}
-void MenuSystem::saveBackground() {
-}
-
-void MenuSystem::restoreBackground() {
-}
-
void MenuSystem::restoreRect(int x, int y, int w, int h) {
byte *src = (byte*)_background->getBasePtr(x, y);
byte *dst = _vm->_screen->_frontScreen + x + y * 640;
@@ -411,14 +405,14 @@ void MenuSystem::shadeRect(int x, int y, int w, int h, byte color1, byte color2)
byte *src = (byte*)_background->getBasePtr(x, y);
for (int xc = 0; xc < w; xc++) {
src[xc] = color1;
- //src[xc] = 46;
+ src[xc + h * 640] = 46;
}
src += 640;
- w -= 2;
- h -= 2;
+ w -= 1;
+ h -= 1;
while (h--) {
src[0] = color2;
- src[w + 1] = color2;
+ src[w] = color2;
for (int xc = 1; xc < w; xc++) {
src[xc] = _vm->_palette->getColorTransPixel(src[xc]);
}
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 7ed15f7..2293670 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -46,9 +46,6 @@
namespace Toltecs {
-const byte kFontColorMenuDefault = 229;
-const byte kFontColorMenuActive = 255;
-
enum MenuID {
kMenuIdNone,
kMenuIdMain,
@@ -164,8 +161,6 @@ protected:
void leaveItem(ItemID id);
void clickItem(ItemID id);
- void saveBackground();
- void restoreBackground();
void restoreRect(int x, int y, int w, int h);
void shadeRect(int x, int y, int w, int h, byte color1, byte color2);
void drawString(int16 x, int16 y, int w, uint fontNum, byte color, byte *text);
Commit: b038d2e4f2473383b2c9fcccdaf0861f21c7a3d5
https://github.com/scummvm/scummvm/commit/b038d2e4f2473383b2c9fcccdaf0861f21c7a3d5
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Added GUI options to detection entries
Changed paths:
engines/toltecs/detection.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 17d8716..ce43927 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -63,7 +63,8 @@ static const ToltecsGameDescription gameDescriptions[] = {
AD_ENTRY1s("WESTERN", "05472037e9cfde146e953c434e74f0f4", 337643527),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
},
},
@@ -75,7 +76,8 @@ static const ToltecsGameDescription gameDescriptions[] = {
AD_ENTRY1s("WESTERN", "ba1742d3193b68ceb9434e2ab7a09a9b", 391462783),
Common::RU_RUS,
Common::kPlatformPC,
- ADGF_NO_FLAGS
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
},
},
@@ -87,7 +89,8 @@ static const ToltecsGameDescription gameDescriptions[] = {
AD_ENTRY1s("WESTERN", "1a3292bad8e0bb5701800c73531dd75e", 345176617),
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
},
},
@@ -99,7 +102,8 @@ static const ToltecsGameDescription gameDescriptions[] = {
AD_ENTRY1s("WESTERN", "1c85e82712d24f1d5c1ea2a66ddd75c2", 47730038),
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
},
},
@@ -124,7 +128,9 @@ static const ADParams detectionParams = {
// List of files for file-based fallback detection (optional)
0,
// Flags
- 0
+ 0,
+ // Additional GUI options (for every game}
+ Common::GUIO_NONE
};
class ToltecsMetaEngine : public AdvancedMetaEngine {
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 214b71d..ad40663 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -150,7 +150,7 @@ Common::Error ToltecsEngine::run() {
syncSoundSettings();
-//#define TEST_MENU
+#define TEST_MENU
#ifdef TEST_MENU
_screen->registerFont(0, 0x0D);
_screen->registerFont(1, 0x0E);
@@ -159,14 +159,17 @@ Common::Error ToltecsEngine::run() {
_palette->setDeltaPalette(_palette->getMainPalette(), 7, 0, 31, 224);
_screen->finishTalkTextItems();
_screen->clearSprites();
+ _menuSystem->run();
+ /*
while (1) {
- updateInput();
+ //updateInput();
_menuSystem->update();
updateScreen();
}
+ */
#endif
-#if 1
+#if 0
_script->loadScript(0, 0);
_script->runScript(0);
#endif
Commit: cb5c0e698667ff0e277be19b01b406367a0747c9
https://github.com/scummvm/scummvm/commit/cb5c0e698667ff0e277be19b01b406367a0747c9
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Sync with ScummVM rev. 46379
Changed paths:
engines/toltecs/saveload.cpp
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index d758fa7..cccc3e6 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -79,7 +79,7 @@ ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::Seekab
header.gameID = in->readByte();
header.flags = in->readUint32LE();
- return (in->ioFailed() ? kRSHEIoError : kRSHENoError);
+ return ((in->eos() || in->err()) ? kRSHEIoError : kRSHENoError);
}
void ToltecsEngine::savegame(const char *filename, const char *description) {
Commit: a0432fd54641381d88b3fb91b2669ed0072f32b1
https://github.com/scummvm/scummvm/commit/a0432fd54641381d88b3fb91b2669ed0072f32b1
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Fixed compilation
Changed paths:
engines/toltecs/movie.cpp
engines/toltecs/movie.h
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index eedf496..8cd1452 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -78,7 +78,7 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_cameraX = 0;
_vm->_cameraY = 0;
- _audioStream = Audio::makeAppendableAudioStream(22050, Audio::Mixer::FLAG_UNSIGNED);
+ _audioStream = Audio::makeQueuingAudioStream(22050, false);
_vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
@@ -197,7 +197,7 @@ void MoviePlayer::fetchAudioChunks() {
if (chunkType == 4) {
byte *chunkBuffer = new byte[chunkSize];
_vm->_arc->read(chunkBuffer, chunkSize);
- _audioStream->queueBuffer(chunkBuffer, chunkSize);
+ _audioStream->queueBuffer(chunkBuffer, chunkSize, Audio::Mixer::FLAG_UNSIGNED);
chunkBuffer = NULL;
prefetchChunkCount++;
_soundChunkFramesLeft += _framesPerSoundChunk;
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
index abb7532..00af2ee 100644
--- a/engines/toltecs/movie.h
+++ b/engines/toltecs/movie.h
@@ -54,7 +54,7 @@ public:
protected:
ToltecsEngine *_vm;
- Audio::AppendableAudioStream *_audioStream;
+ Audio::QueuingAudioStream *_audioStream;
Audio::SoundHandle _audioStreamHandle;
uint32 _chunkCount, _frameCount, _lastPrefetchOfs;
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index ad40663..6e9df70 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -150,7 +150,7 @@ Common::Error ToltecsEngine::run() {
syncSoundSettings();
-#define TEST_MENU
+//#define TEST_MENU
#ifdef TEST_MENU
_screen->registerFont(0, 0x0D);
_screen->registerFont(1, 0x0E);
@@ -167,9 +167,10 @@ Common::Error ToltecsEngine::run() {
updateScreen();
}
*/
+ return Common::kNoError;
#endif
-#if 0
+#if 1
_script->loadScript(0, 0);
_script->runScript(0);
#endif
Commit: ac97b441ec5cfae02db056138fdba0d96198b233
https://github.com/scummvm/scummvm/commit/ac97b441ec5cfae02db056138fdba0d96198b233
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Silenced warning
Changed paths:
engines/toltecs/menu.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 5c770ac..e433025 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -304,7 +304,7 @@ void MenuSystem::leaveItem(ItemID id) {
}
void MenuSystem::clickItem(ItemID id) {
- Item *item = getItem(id);
+ //Item *item = getItem(id);
switch (id) {
// Main menu
case kItemIdSave:
Commit: 5948672be5bda52ec5143016cb8b02a29e7d9276
https://github.com/scummvm/scummvm/commit/5948672be5bda52ec5143016cb8b02a29e7d9276
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Fixed compilation with the latest sound changes in the trunk
Changed paths:
engines/toltecs/movie.cpp
engines/toltecs/sound.cpp
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 8cd1452..ab920d5 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -197,7 +197,7 @@ void MoviePlayer::fetchAudioChunks() {
if (chunkType == 4) {
byte *chunkBuffer = new byte[chunkSize];
_vm->_arc->read(chunkBuffer, chunkSize);
- _audioStream->queueBuffer(chunkBuffer, chunkSize, Audio::Mixer::FLAG_UNSIGNED);
+ _audioStream->queueBuffer(chunkBuffer, chunkSize, DisposeAfterUse::YES, Audio::Mixer::FLAG_UNSIGNED);
chunkBuffer = NULL;
prefetchChunkCount++;
_soundChunkFramesLeft += _framesPerSoundChunk;
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 875fd0b..d479b86 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -33,6 +33,7 @@
#include "graphics/cursorman.h"
#include "sound/mixer.h"
+#include "sound/raw.h"
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
@@ -151,7 +152,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
// Background sounds
if (type == kChannelTypeBackground)
flags |= Audio::Mixer::FLAG_LOOP;
- Audio::AudioStream *stream = Audio::makeLinearInputStream(soundResource->data, soundResource->size, 22050, flags, 0, 0);
+ Audio::AudioStream *stream = Audio::makeRawMemoryStream(soundResource->data, soundResource->size, DisposeAfterUse::YES, 22050, flags, 0, 0);
channels[freeChannel].type = type;
channels[freeChannel].resIndex = resIndex;
Commit: 69f35c87092568901e42c897ac08a786c7a46a30
https://github.com/scummvm/scummvm/commit/69f35c87092568901e42c897ac08a786c7a46a30
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Fixed compilation
Changed paths:
engines/toltecs/movie.cpp
engines/toltecs/sound.cpp
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index ab920d5..8cc6274 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -31,6 +31,7 @@
#include "base/version.h"
#include "sound/mixer.h"
+#include "sound/raw.h"
#include "toltecs/toltecs.h"
#include "toltecs/movie.h"
@@ -197,7 +198,7 @@ void MoviePlayer::fetchAudioChunks() {
if (chunkType == 4) {
byte *chunkBuffer = new byte[chunkSize];
_vm->_arc->read(chunkBuffer, chunkSize);
- _audioStream->queueBuffer(chunkBuffer, chunkSize, DisposeAfterUse::YES, Audio::Mixer::FLAG_UNSIGNED);
+ _audioStream->queueBuffer(chunkBuffer, chunkSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
chunkBuffer = NULL;
prefetchChunkCount++;
_soundChunkFramesLeft += _framesPerSoundChunk;
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index d479b86..42f4e10 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -148,11 +148,11 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
Resource *soundResource = _vm->_res->load(resIndex);
- byte flags = Audio::Mixer::FLAG_UNSIGNED;
+ byte flags = Audio::FLAG_UNSIGNED;
// Background sounds
if (type == kChannelTypeBackground)
- flags |= Audio::Mixer::FLAG_LOOP;
- Audio::AudioStream *stream = Audio::makeRawMemoryStream(soundResource->data, soundResource->size, DisposeAfterUse::YES, 22050, flags, 0, 0);
+ flags |= Audio::FLAG_LOOP;
+ Audio::AudioStream *stream = Audio::makeRawMemoryStream(soundResource->data, soundResource->size, DisposeAfterUse::YES/*CHECKME*/, 22050, flags, 0, 0);
channels[freeChannel].type = type;
channels[freeChannel].resIndex = resIndex;
Commit: baf4218b0503f56cfd7b3e20df9ff30623c37c8d
https://github.com/scummvm/scummvm/commit/baf4218b0503f56cfd7b3e20df9ff30623c37c8d
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:08-08:00
Commit Message:
TOLTECS: Fixed compilation with the latest trunk changes
Changed paths:
engines/toltecs/sound.cpp
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 42f4e10..c9ca777 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -148,11 +148,9 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
Resource *soundResource = _vm->_res->load(resIndex);
- byte flags = Audio::FLAG_UNSIGNED;
- // Background sounds
- if (type == kChannelTypeBackground)
- flags |= Audio::FLAG_LOOP;
- Audio::AudioStream *stream = Audio::makeRawMemoryStream(soundResource->data, soundResource->size, DisposeAfterUse::YES/*CHECKME*/, 22050, flags, 0, 0);
+ Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
+ Audio::makeRawMemoryStream(soundResource->data, soundResource->size, DisposeAfterUse::YES/*CHECKME*/, 22050, Audio::FLAG_UNSIGNED),
+ type == kChannelTypeBackground ? 0 : 1);
channels[freeChannel].type = type;
channels[freeChannel].resIndex = resIndex;
Commit: 16baa44a2fa60170858b138d77b74944121247e6
https://github.com/scummvm/scummvm/commit/16baa44a2fa60170858b138d77b74944121247e6
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fixed compilation with the latest trunk
Changed paths:
engines/toltecs/sound.cpp
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index c9ca777..d4f18be 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -149,7 +149,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
Resource *soundResource = _vm->_res->load(resIndex);
Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawMemoryStream(soundResource->data, soundResource->size, DisposeAfterUse::YES/*CHECKME*/, 22050, Audio::FLAG_UNSIGNED),
+ Audio::makeRawMemoryStream(soundResource->data, soundResource->size, 22050, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES/*CHECKME*/),
type == kChannelTypeBackground ? 0 : 1);
channels[freeChannel].type = type;
Commit: 89a5208a58500ab12ccfb7893abf67add4afc0e9
https://github.com/scummvm/scummvm/commit/89a5208a58500ab12ccfb7893abf67add4afc0e9
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fixed compilation with the latest trunk changes.
This change also unveiled a serious problem: the same include files are used EVERYWHERE (e.g. code manipulating the screen is using sound includes). Added a FIXME concerning this
Changed paths:
engines/toltecs/animation.h
engines/toltecs/menu.h
engines/toltecs/movie.cpp
engines/toltecs/movie.h
engines/toltecs/palette.h
engines/toltecs/render.h
engines/toltecs/resource.h
engines/toltecs/screen.h
engines/toltecs/script.h
engines/toltecs/segmap.h
engines/toltecs/sound.cpp
engines/toltecs/sound.h
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/animation.h b/engines/toltecs/animation.h
index 581934a..8b1ac7b 100644
--- a/engines/toltecs/animation.h
+++ b/engines/toltecs/animation.h
@@ -35,11 +35,6 @@
#include "common/keyboard.h"
#include "common/array.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "engines/engine.h"
#include "toltecs/toltecs.h"
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 2293670..5860afd 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -37,11 +37,6 @@
#include "common/rect.h"
#include "common/str.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "engines/engine.h"
namespace Toltecs {
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 8cc6274..2fd0d18 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -31,7 +31,7 @@
#include "base/version.h"
#include "sound/mixer.h"
-#include "sound/raw.h"
+#include "sound/decoders/raw.h"
#include "toltecs/toltecs.h"
#include "toltecs/movie.h"
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
index 00af2ee..0a6a865 100644
--- a/engines/toltecs/movie.h
+++ b/engines/toltecs/movie.h
@@ -35,11 +35,6 @@
#include "common/keyboard.h"
#include "common/array.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "engines/engine.h"
namespace Toltecs {
diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h
index 6a2bb59..920aded 100644
--- a/engines/toltecs/palette.h
+++ b/engines/toltecs/palette.h
@@ -36,11 +36,6 @@
#include "common/keyboard.h"
#include "common/array.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "engines/engine.h"
namespace Toltecs {
diff --git a/engines/toltecs/render.h b/engines/toltecs/render.h
index 0f5554b..ce8faeb 100644
--- a/engines/toltecs/render.h
+++ b/engines/toltecs/render.h
@@ -39,11 +39,6 @@
#include "graphics/surface.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "engines/engine.h"
#include "toltecs/segmap.h"
diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h
index 1c618ae..8164b9e 100644
--- a/engines/toltecs/resource.h
+++ b/engines/toltecs/resource.h
@@ -36,11 +36,6 @@
#include "common/keyboard.h"
#include "common/array.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "engines/engine.h"
namespace Toltecs {
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index c9a7060..4aeeb78 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -38,11 +38,6 @@
#include "graphics/surface.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "engines/engine.h"
namespace Toltecs {
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index 83ee628..e82e3da 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -36,11 +36,6 @@
#include "common/array.h"
#include "common/func.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "engines/engine.h"
namespace Toltecs {
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index 394d4ae..3fcf5bf 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -35,11 +35,6 @@
#include "common/keyboard.h"
#include "common/array.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/voc.h"
-#include "sound/audiocd.h"
-
#include "graphics/surface.h"
#include "engines/engine.h"
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index d4f18be..655da3c 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -33,7 +33,7 @@
#include "graphics/cursorman.h"
#include "sound/mixer.h"
-#include "sound/raw.h"
+#include "sound/decoders/raw.h"
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
index 7552d85..1f82378 100644
--- a/engines/toltecs/sound.h
+++ b/engines/toltecs/sound.h
@@ -37,8 +37,8 @@
#include "sound/audiostream.h"
#include "sound/mixer.h"
-#include "sound/voc.h"
#include "sound/audiocd.h"
+#include "sound/decoders/voc.h"
#include "engines/engine.h"
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index e870137..9a2ed70 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -36,7 +36,7 @@
#include "sound/audiostream.h"
#include "sound/mixer.h"
-#include "sound/voc.h"
+#include "sound/decoders/voc.h"
#include "sound/audiocd.h"
#include "engines/engine.h"
@@ -57,6 +57,8 @@ class Screen;
class SegmentMap;
class Sound;
+// TODO/FIXME: The includes of the Toltecs engine need serious clean-up
+
class ToltecsEngine : public ::Engine {
Common::KeyState _keyPressed;
Commit: e8ec5148a211208e3e243dc20e2322ed8682c678
https://github.com/scummvm/scummvm/commit/e8ec5148a211208e3e243dc20e2322ed8682c678
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fixed compilation
Changed paths:
engines/toltecs/sound.cpp
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 655da3c..263766f 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -149,7 +149,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
Resource *soundResource = _vm->_res->load(resIndex);
Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawMemoryStream(soundResource->data, soundResource->size, 22050, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES/*CHECKME*/),
+ Audio::makeRawStream(soundResource->data, soundResource->size, 22050, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES/*CHECKME*/),
type == kChannelTypeBackground ? 0 : 1);
channels[freeChannel].type = type;
Commit: 0d1a9148f3a24be60c4924875886a2ff60624b77
https://github.com/scummvm/scummvm/commit/0d1a9148f3a24be60c4924875886a2ff60624b77
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fix bug caused by most recent revision (don't free the audio data in makeRawStream)
Changed paths:
engines/toltecs/sound.cpp
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 263766f..7be5dba 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -149,7 +149,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
Resource *soundResource = _vm->_res->load(resIndex);
Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(soundResource->data, soundResource->size, 22050, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES/*CHECKME*/),
+ Audio::makeRawStream(soundResource->data, soundResource->size, 22050, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO),
type == kChannelTypeBackground ? 0 : 1);
channels[freeChannel].type = type;
Commit: 34eb899b25edb462267b3a0593fd4b3f324b3546
https://github.com/scummvm/scummvm/commit/34eb899b25edb462267b3a0593fd4b3f324b3546
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fixed compilation
Changed paths:
engines/toltecs/detection.cpp
engines/toltecs/menu.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index ce43927..f64461b 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -183,12 +183,12 @@ SaveStateList ToltecsMetaEngine::listSaves(const char *target) const {
Common::String pattern = target;
pattern += ".???";
- Common::StringList filenames;
+ Common::StringArray filenames;
filenames = saveFileMan->listSavefiles(pattern.c_str());
Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
SaveStateList saveList;
- for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
// Obtain the last 3 digits of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 3);
@@ -220,13 +220,13 @@ void ToltecsMetaEngine::removeSaveState(const char *target, int slot) const {
saveFileMan->removeSavefile(filename.c_str());
- Common::StringList filenames;
+ Common::StringArray filenames;
Common::String pattern = target;
pattern += ".???";
filenames = saveFileMan->listSavefiles(pattern.c_str());
Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
- for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
// Obtain the last 3 digits of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 3);
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index e433025..0fe8d76 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -439,11 +439,11 @@ void MenuSystem::initSavegames() {
Common::String pattern = _vm->getTargetName();
pattern += ".???";
- Common::StringList filenames;
+ Common::StringArray filenames;
filenames = saveFileMan->listSavefiles(pattern.c_str());
Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
- for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
if (_vm->readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 9a2ed70..7816b3b 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -28,6 +28,7 @@
#include "common/endian.h"
#include "common/util.h"
#include "common/file.h"
+#include "common/random.h"
#include "common/savefile.h"
#include "common/system.h"
#include "common/hash-str.h"
Commit: 7f78f62467af6a1e65e06a155ada3c07ce94db47
https://github.com/scummvm/scummvm/commit/7f78f62467af6a1e65e06a155ada3c07ce94db47
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fixed compilation with current SVN changes
Changed paths:
engines/toltecs/movie.cpp
engines/toltecs/sound.cpp
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 2fd0d18..d5839cb 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -81,7 +81,7 @@ void MoviePlayer::playMovie(uint resIndex) {
_audioStream = Audio::makeQueuingAudioStream(22050, false);
- _vm->_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
+ _vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
_soundChunkFramesLeft = 0;
_lastPrefetchOfs = 0;
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 7be5dba..d015720 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -161,7 +161,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
}
*/
- _vm->_mixer->playInputStream(soundType, &channels[freeChannel].handle,
+ _vm->_mixer->playStream(soundType, &channels[freeChannel].handle,
stream, -1, volume, panning);
}
Commit: fc324073d54376d21a8d58bc4199f529266d9ec4
https://github.com/scummvm/scummvm/commit/fc324073d54376d21a8d58bc4199f529266d9ec4
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Rename savegame version define
Changed paths:
engines/toltecs/saveload.cpp
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index cccc3e6..018fe35 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -51,12 +51,12 @@ namespace Toltecs {
- Maybe switch to SCUMM/Tinsel serialization approach?
*/
-#define SAVEGAME_VERSION 0 // 0 is dev version until in official SVN
+#define TOLTECS_SAVEGAME_VERSION 0 // 0 is dev version until in official SVN
ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
header.version = in->readUint32LE();
- if (header.version != SAVEGAME_VERSION)
+ if (header.version != TOLTECS_SAVEGAME_VERSION)
return kRSHEInvalidVersion;
byte descriptionLen = in->readByte();
@@ -90,7 +90,7 @@ void ToltecsEngine::savegame(const char *filename, const char *description) {
return;
}
- out->writeUint32LE(SAVEGAME_VERSION);
+ out->writeUint32LE(TOLTECS_SAVEGAME_VERSION);
byte descriptionLen = strlen(description);
out->writeByte(descriptionLen);
Commit: d885aedd488f3a62701d2bcfb06012d543f0ab29
https://github.com/scummvm/scummvm/commit/d885aedd488f3a62701d2bcfb06012d543f0ab29
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fix compilation with trunk
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 6e9df70..2e4d4f6 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -36,6 +36,8 @@
#include "graphics/cursorman.h"
#include "graphics/primitives.h"
+#include "engines/util.h"
+
#include "sound/mixer.h"
#include "toltecs/toltecs.h"
Commit: 2e06f4b088f51ed312388e9f8452eb25531054e5
https://github.com/scummvm/scummvm/commit/2e06f4b088f51ed312388e9f8452eb25531054e5
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Added detection entries for French and Spanish versions
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index f64461b..acb9edf 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -107,6 +107,32 @@ static const ToltecsGameDescription gameDescriptions[] = {
},
},
+ {
+ // 3 Skulls of the Toltecs French version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "4fb845635cbdac732453fe23be350df9", 327269545),
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ },
+
+ {
+ // 3 Skulls of the Toltecs Spanish version
+ {
+ "toltecs",
+ 0,
+ AD_ENTRY1s("WESTERN", "479f468beccc1b0ce5873ec523d1380e", 308391018),
+ Common::ES_ESP,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ },
+
{ AD_TABLE_END_MARKER }
};
Commit: 39b8bda921b88a60bc912464ed33885f7670997d
https://github.com/scummvm/scummvm/commit/39b8bda921b88a60bc912464ed33885f7670997d
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fix warning
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index acb9edf..391f578 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -156,7 +156,9 @@ static const ADParams detectionParams = {
// Flags
0,
// Additional GUI options (for every game}
- Common::GUIO_NONE
+ Common::GUIO_NONE,
+ // Maximum directory depth
+ 1
};
class ToltecsMetaEngine : public AdvancedMetaEngine {
Commit: 8ea6831825f2d16ca03a8bc5be946465f9bb3fd9
https://github.com/scummvm/scummvm/commit/8ea6831825f2d16ca03a8bc5be946465f9bb3fd9
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Fix warning
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 391f578..a341bea 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -158,7 +158,9 @@ static const ADParams detectionParams = {
// Additional GUI options (for every game}
Common::GUIO_NONE,
// Maximum directory depth
- 1
+ 1,
+ // List of directory globs
+ 0
};
class ToltecsMetaEngine : public AdvancedMetaEngine {
Commit: 2acf1bf6f589f162908b456cb69cb03df6e798e7
https://github.com/scummvm/scummvm/commit/2acf1bf6f589f162908b456cb69cb03df6e798e7
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: - Hopefully fixed a bug in findRectAtPoint which causes the game to crash before the first scene
- sfHandleInput
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 4aaa626..d062f46 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -920,10 +920,12 @@ void ScriptInterpreter::sfSetGuiHeight() {
void ScriptInterpreter::sfFindMouseInRectIndex1() {
int16 index = -1;
if (_vm->_mouseY < _vm->_cameraHeight) {
- index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
+ int16 slotIndex = arg16(5);
+ index = _vm->findRectAtPoint(getSlotData(slotIndex) + arg16(3),
_vm->_mouseX + _vm->_cameraX,
_vm->_mouseY + _vm->_cameraY,
- arg16(11) + 1, arg16(7));
+ arg16(11) + 1, arg16(7),
+ getSlotData(slotIndex) + _slots[slotIndex].size);
}
localWrite16(arg16(9), index);
}
@@ -932,10 +934,12 @@ void ScriptInterpreter::sfFindMouseInRectIndex2() {
int16 index = -1;
if (_vm->_sceneResIndex != 0) {
if (_vm->_mouseY < _vm->_cameraHeight) {
- index = _vm->findRectAtPoint(getSlotData(arg16(5)) + arg16(3),
+ int16 slotIndex = arg16(5);
+ index = _vm->findRectAtPoint(getSlotData(slotIndex) + arg16(3),
_vm->_mouseX + _vm->_cameraX,
_vm->_mouseY + _vm->_cameraY,
- 0, arg16(7));
+ 0, arg16(7),
+ getSlotData(slotIndex) + _slots[slotIndex].size);
}
}
localWrite16(arg16(9), index);
@@ -1066,7 +1070,14 @@ void ScriptInterpreter::sfClearScreen() {
void ScriptInterpreter::sfHandleInput() {
// TODO: Recheck what this does
int16 varOfs = arg16(3);
- localWrite16(varOfs, 0);
+ int16 keyCode = 0;
+ if (_vm->_rightButtonDown) {
+ keyCode = 1;
+ } else {
+ // TODO: Handle Escape
+ // TODO: Set keyboard scancode
+ }
+ localWrite16(varOfs, keyCode);
}
void ScriptInterpreter::sfRunOptionsScreen() {
@@ -1074,7 +1085,7 @@ void ScriptInterpreter::sfRunOptionsScreen() {
}
/* NOTE: The opcodes sfPrecacheSprites, sfPrecacheSounds1, sfPrecacheSounds2 and
- sfDeletePrecachedFiles were used by the original engine to handle precaching
+ sfDeletePrecachedFiles were used by the original engine to handle precaching
of data so the game doesn't stall while playing (due to the slow speed of
CD-Drives back then). This is not needed in ScummVM since all supported
systems are fast enough to load data in-game. */
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 2e4d4f6..62bf2500 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -245,6 +245,7 @@ void ToltecsEngine::updateScreen() {
//printf("_guiHeight = %d\n", _guiHeight); fflush(stdout);
if (_screen->_guiRefresh && _guiHeight > 0 && _cameraHeight > 0) {
+ // Update the GUI when needed and it's visible
_system->copyRectToScreen((const byte *)_screen->_frontScreen + _cameraHeight * 640,
640, 0, _cameraHeight, 640, _guiHeight);
_screen->_guiRefresh = false;
@@ -263,6 +264,9 @@ void ToltecsEngine::updateInput() {
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
+ _keyState = event.kbd;
+
+ //debug("key: flags = %02X; keycode = %d", _keyState.flags, _keyState.keycode);
// FIXME: This is just for debugging
switch (event.kbd.keycode) {
@@ -277,6 +281,9 @@ void ToltecsEngine::updateInput() {
}
break;
+ case Common::EVENT_KEYUP:
+ _keyState.reset();
+ break;
case Common::EVENT_QUIT:
quitGame();
break;
@@ -540,11 +547,12 @@ void ToltecsEngine::walk(byte *walkData) {
}
-int16 ToltecsEngine::findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize) {
+int16 ToltecsEngine::findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize,
+ byte *rectDataEnd) {
rectData += index * itemSize;
- while (1) {
+ while (rectData < rectDataEnd) {
int16 rectY = READ_LE_UINT16(rectData);
if (rectY == -10)
break;
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 7816b3b..bcd2c3d 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -98,7 +98,8 @@ public:
void walk(byte *walkData);
- int16 findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize);
+ int16 findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize,
+ byte *rectDataEnd);
public:
@@ -130,6 +131,7 @@ public:
int16 _walkSpeedY, _walkSpeedX;
+ Common::KeyState _keyState;
int16 _mouseX, _mouseY;
int16 _mouseCounter;
bool _mouseButtonPressedFlag;
Commit: 99bd410cb35e0635f40598368dab76d70ba3abd5
https://github.com/scummvm/scummvm/commit/99bd410cb35e0635f40598368dab76d70ba3abd5
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Sync with the latest ScummVM changes (renamed skipThumbnailHeader to skipThumbnail)
Changed paths:
engines/toltecs/saveload.cpp
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 018fe35..3196ca4 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -72,7 +72,7 @@ ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::Seekab
header.thumbnail = 0;
}
} else {
- Graphics::skipThumbnailHeader(*in);
+ Graphics::skipThumbnail(*in);
}
// Not used yet, reserved for future usage
Commit: 6034e4ffb4228b36af19142e7d98827197296b39
https://github.com/scummvm/scummvm/commit/6034e4ffb4228b36af19142e7d98827197296b39
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: - Don't add test entries to the save/loadgame menu
Changed paths:
engines/toltecs/menu.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 0fe8d76..648f429 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -454,6 +454,7 @@ void MenuSystem::initSavegames() {
}
}
+#if 0
// DEBUG: Add some more items
_savegames.push_back(SavegameItem("abc", "Test 1"));
_savegames.push_back(SavegameItem("abc", "Test 2"));
@@ -467,6 +468,7 @@ void MenuSystem::initSavegames() {
_savegames.push_back(SavegameItem("abc", "Test 10"));
_savegames.push_back(SavegameItem("abc", "Test 11"));
_savegames.push_back(SavegameItem("abc", "Test 12"));
+#endif
}
Commit: 8f3b287db139383c45a04e729b85474a9129578c
https://github.com/scummvm/scummvm/commit/8f3b287db139383c45a04e729b85474a9129578c
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:09-08:00
Commit Message:
TOLTECS: Update todo (no real fixes, though)
Changed paths:
engines/toltecs/TODO.txt
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 6cf06a4..248fe41 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -21,7 +21,6 @@ TODO
BUGS
------
-- Still some clipping issues (walking upstairs in the saloon, when on top of the tower in the hideout)
- Crashes sometimes on scene changes
(I guess because some talktext is still running although the slot used by it has changed)
- Crashes sometimes (e.g. when inside the barn and going up the ladder)
@@ -32,3 +31,4 @@ DONE
- Optimize segment mask redrawing (only redraw what's neccessary)
- Add movie playback functionality (movie format is known, needs implementing)
- Add sound support (after rewrite of the resource system)
+- Still some clipping issues (walking upstairs in the saloon, when on top of the tower in the hideout)
Commit: 9c3a4bc055243af586f7ab091ba802e5274943b5
https://github.com/scummvm/scummvm/commit/9c3a4bc055243af586f7ab091ba802e5274943b5
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: - Implement kSupportsLoadingDuringStartup
Changed paths:
engines/toltecs/detection.cpp
engines/toltecs/script.cpp
engines/toltecs/script.h
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index a341bea..1c113dd 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -172,7 +172,7 @@ public:
}
virtual const char *getOriginalCopyright() const {
- return "Toltecs Engine (C) 1996";
+ return "Toltecs Engine Revistronic (C) 1996";
}
virtual bool hasFeature(MetaEngineFeature f) const;
@@ -186,7 +186,7 @@ public:
bool ToltecsMetaEngine::hasFeature(MetaEngineFeature f) const {
return
(f == kSupportsListSaves) ||
-// (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsLoadingDuringStartup) ||
// (f == kSupportsDeleteSave) ||
(f == kSavesSupportMetaInfo) ||
(f == kSavesSupportThumbnail);
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index d062f46..4e15fa3 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -157,13 +157,11 @@ void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) {
}
-void ScriptInterpreter::runScript(uint slotIndex) {
-
+void ScriptInterpreter::setMainScript(uint slotIndex) {
_switchLocalDataNear = true;
_switchLocalDataFar = false;
_switchLocalDataToStack = false;
_cmpBitTest = false;
-
_regs.reg0 = 0;
_regs.reg1 = 0;
_regs.reg2 = 0;
@@ -173,8 +171,10 @@ void ScriptInterpreter::runScript(uint slotIndex) {
_regs.reg6 = 0;
_regs.sp = 4096;
_regs.reg8 = 0;
-
_code = getSlotData(_regs.reg4);
+}
+
+void ScriptInterpreter::runScript() {
while (!_vm->shouldQuit()) {
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index e82e3da..966ed3d 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -56,7 +56,8 @@ public:
~ScriptInterpreter();
void loadScript(uint resIndex, uint slotIndex);
- void runScript(uint slotIndex);
+ void setMainScript(uint slotIndex);
+ void runScript();
byte *getSlotData(int slotIndex) const { return _slots[slotIndex].data; }
@@ -102,7 +103,7 @@ protected:
ScriptRegs _regs;
int16 _savedSp;
-
+
byte readByte();
int16 readInt16();
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 62bf2500..0c8d565 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -174,7 +174,14 @@ Common::Error ToltecsEngine::run() {
#if 1
_script->loadScript(0, 0);
- _script->runScript(0);
+ _script->setMainScript(0);
+ if (ConfMan.hasKey("save_slot")) {
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0 && saveSlot <= 99) {
+ loadGameState(saveSlot);
+ }
+ }
+ _script->runScript();
#endif
delete _arc;
Commit: 5e154f634a47524fe5d2d260c25812d40802fbc9
https://github.com/scummvm/scummvm/commit/5e154f634a47524fe5d2d260c25812d40802fbc9
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Fixed compilation
Changed paths:
engines/toltecs/resource.cpp
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index aaff6e3..c8cf2cc 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -86,9 +86,11 @@ void ArchiveReader::dump(uint resIndex, const char *prefix) {
read(data, resourceSize);
closeResource();
+#if 0
FILE *o = fopen(fn, "wb");
fwrite(data, resourceSize, 1, o);
fclose(o);
+#endif
delete[] data;
}
Commit: ce7f9a088c03e502eaf0709b18c6c02937673f9f
https://github.com/scummvm/scummvm/commit/ce7f9a088c03e502eaf0709b18c6c02937673f9f
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: - Work on the menu system (use strings from resources instead of hardcoded ones)
- ...and load the system strings from the resource on startup
- Only redraw menu screen when required
- Change parameters for some text functions from byte* to const byte*
- Rename some mouse vars
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
engines/toltecs/screen.cpp
engines/toltecs/screen.h
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 648f429..2747858 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -47,6 +47,7 @@ MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
_newMenuID = kMenuIdLoad;
_currItemID = kItemIdNone;
_editingDescription = false;
+ _needRedraw = false;
_cfgText = true;
_cfgVoices = true;
_cfgMasterVolume = 10;
@@ -65,6 +66,7 @@ int MenuSystem::run() {
_background->create(640, 400, 1);
_top = 30 - _vm->_guiHeight / 2;
+ _needRedraw = false;
memset(_vm->_screen->_frontScreen, 250, 640 * 400);
@@ -73,14 +75,17 @@ int MenuSystem::run() {
_vm->_palette->buildColorTransTable(0, 16, 7);
shadeRect(60, 39, 520, 246, 30, 94);
-
+
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, 400);
+
while (1) {
update();
_vm->updateScreen();
}
delete _background;
-
+
+ return 0;
}
void MenuSystem::update() {
@@ -93,8 +98,11 @@ void MenuSystem::update() {
handleEvents();
- _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen,
- 640, 0, 0, 640, 400);
+ if (_needRedraw) {
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen + 39 * 640 + 60, 640, 60, 39, 520, 247);
+ debug("redraw");
+ _needRedraw = false;
+ }
_vm->_system->delayMillis(5);
@@ -125,7 +133,7 @@ void MenuSystem::handleEvents() {
}
-void MenuSystem::addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const byte *caption, byte defaultColor, byte activeColor) {
+void MenuSystem::addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const char *caption, byte defaultColor, byte activeColor) {
Item item;
item.id = id;
item.defaultColor = defaultColor;
@@ -142,7 +150,7 @@ void MenuSystem::drawItem(ItemID itemID, bool active) {
Item *item = getItem(itemID);
if (item) {
byte color = active ? item->activeColor : item->defaultColor;
- drawString(item->rect.left, item->y, 0, item->fontNum, color, (byte*)item->caption.c_str());
+ drawString(item->rect.left, item->y, 0, item->fontNum, color, item->caption.c_str());
}
}
@@ -170,13 +178,13 @@ void MenuSystem::handleKeyDown(const Common::KeyState& kbd) {
_editingDescriptionItem->caption += kbd.ascii;
restoreRect(_editingDescriptionItem->rect.left, _editingDescriptionItem->rect.top,
_editingDescriptionItem->rect.width() + 1, _editingDescriptionItem->rect.height() - 2);
- setItemCaption(_editingDescriptionItem, (const byte*)_editingDescriptionItem->caption.c_str());
+ setItemCaption(_editingDescriptionItem, _editingDescriptionItem->caption.c_str());
drawItem(_editingDescriptionID, true);
} else if (kbd.keycode == Common::KEYCODE_BACKSPACE) {
_editingDescriptionItem->caption.deleteLastChar();
restoreRect(_editingDescriptionItem->rect.left, _editingDescriptionItem->rect.top,
_editingDescriptionItem->rect.width() + 1, _editingDescriptionItem->rect.height() - 2);
- setItemCaption(_editingDescriptionItem, (const byte*)_editingDescriptionItem->caption.c_str());
+ setItemCaption(_editingDescriptionItem, _editingDescriptionItem->caption.c_str());
drawItem(_editingDescriptionID, true);
} else if (kbd.keycode == Common::KEYCODE_RETURN) {
_editingDescription = false;
@@ -201,15 +209,15 @@ MenuSystem::Item *MenuSystem::getItem(ItemID id) {
return NULL;
}
-void MenuSystem::setItemCaption(Item *item, const byte *caption) {
+void MenuSystem::setItemCaption(Item *item, const char *caption) {
Font font(_vm->_res->load(_vm->_screen->getFontResIndex(item->fontNum))->data);
- int width = font.getTextWidth((byte*)caption);
+ int width = font.getTextWidth((const byte*)caption);
int height = font.getHeight();
item->rect = Common::Rect(item->x, item->y - height, item->x + width, item->y);
if (item->w) {
item->rect.translate(item->w - width / 2, 0);
}
- item->caption = (const char*)caption;
+ item->caption = caption;
}
void MenuSystem::initMenu(MenuID menuID) {
@@ -220,65 +228,65 @@ void MenuSystem::initMenu(MenuID menuID) {
switch (menuID) {
case kMenuIdMain:
- drawString(0, 74, 320, 1, 229, (byte*)"What can I do for you?");
- addClickTextItem(kItemIdLoad, 0, 115, 320, 0, (const byte*)"LOAD", 229, 255);
- addClickTextItem(kItemIdSave, 0, 135, 320, 0, (const byte*)"SAVE", 229, 255);
- addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, (const byte*)"TEXT ON", 229, 255);
- addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, (const byte*)"VOICES ON", 229, 255);
- addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, 0, (const byte*)"VOLUME", 229, 255);
- addClickTextItem(kItemIdPlay, 0, 245, 320, 0, (const byte*)"PLAY", 229, 255);
- addClickTextItem(kItemIdQuit, 0, 275, 320, 0, (const byte*)"QUIT GAME", 229, 255);
+ drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrWhatCanIDoForYou));
+ addClickTextItem(kItemIdLoad, 0, 115, 320, 0, _vm->getSysString(kStrLoad), 229, 255);
+ addClickTextItem(kItemIdSave, 0, 135, 320, 0, _vm->getSysString(kStrSave), 229, 255);
+ addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, _vm->getSysString(kStrTextOn), 229, 255);
+ addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, _vm->getSysString(kStrVoicesOn), 229, 255);
+ addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, 0, _vm->getSysString(kStrVolume), 229, 255);
+ addClickTextItem(kItemIdPlay, 0, 245, 320, 0, _vm->getSysString(kStrPlay), 229, 255);
+ addClickTextItem(kItemIdQuit, 0, 275, 320, 0, _vm->getSysString(kStrQuit), 229, 255);
break;
case kMenuIdLoad:
- drawString(0, 74, 320, 1, 229, (byte*)"Load game");
- addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, (const byte*)"^", 255, 253);
- addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, (const byte*)"\\", 255, 253);
- addClickTextItem(kItemIdCancel, 0, 275, 320, 0, (const byte*)"CANCEL", 255, 253);
- addClickTextItem(kItemIdSavegame1, 0, 115 + 20 * 0, 300, 0, (const byte*)"SAVEGAME 1", 231, 234);
- addClickTextItem(kItemIdSavegame2, 0, 115 + 20 * 1, 300, 0, (const byte*)"SAVEGAME 2", 231, 234);
- addClickTextItem(kItemIdSavegame3, 0, 115 + 20 * 2, 300, 0, (const byte*)"SAVEGAME 3", 231, 234);
- addClickTextItem(kItemIdSavegame4, 0, 115 + 20 * 3, 300, 0, (const byte*)"SAVEGAME 4", 231, 234);
- addClickTextItem(kItemIdSavegame5, 0, 115 + 20 * 4, 300, 0, (const byte*)"SAVEGAME 5", 231, 234);
- addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, (const byte*)"SAVEGAME 6", 231, 234);
- addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, (const byte*)"SAVEGAME 7", 231, 234);
+ drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrLoadGame));
+ addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, "^", 255, 253);
+ addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, "\\", 255, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 320, 0, _vm->getSysString(kStrCancel), 255, 253);
+ addClickTextItem(kItemIdSavegame1, 0, 115 + 20 * 0, 300, 0, "SAVEGAME 1", 231, 234);
+ addClickTextItem(kItemIdSavegame2, 0, 115 + 20 * 1, 300, 0, "SAVEGAME 2", 231, 234);
+ addClickTextItem(kItemIdSavegame3, 0, 115 + 20 * 2, 300, 0, "SAVEGAME 3", 231, 234);
+ addClickTextItem(kItemIdSavegame4, 0, 115 + 20 * 3, 300, 0, "SAVEGAME 4", 231, 234);
+ addClickTextItem(kItemIdSavegame5, 0, 115 + 20 * 4, 300, 0, "SAVEGAME 5", 231, 234);
+ addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, "SAVEGAME 6", 231, 234);
+ addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, "SAVEGAME 7", 231, 234);
initSavegames();
setSavegameCaptions();
break;
case kMenuIdSave:
- drawString(0, 74, 320, 1, 229, (byte*)"Save game");
- addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, (const byte*)"^", 255, 253);
- addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, (const byte*)"\\", 255, 253);
- addClickTextItem(kItemIdCancel, 0, 275, 320, 0, (const byte*)"CANCEL", 255, 253);
- addClickTextItem(kItemIdSavegame1, 0, 115 + 20 * 0, 300, 0, (const byte*)"SAVEGAME 1", 231, 234);
- addClickTextItem(kItemIdSavegame2, 0, 115 + 20 * 1, 300, 0, (const byte*)"SAVEGAME 2", 231, 234);
- addClickTextItem(kItemIdSavegame3, 0, 115 + 20 * 2, 300, 0, (const byte*)"SAVEGAME 3", 231, 234);
- addClickTextItem(kItemIdSavegame4, 0, 115 + 20 * 3, 300, 0, (const byte*)"SAVEGAME 4", 231, 234);
- addClickTextItem(kItemIdSavegame5, 0, 115 + 20 * 4, 300, 0, (const byte*)"SAVEGAME 5", 231, 234);
- addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, (const byte*)"SAVEGAME 6", 231, 234);
- addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, (const byte*)"SAVEGAME 7", 231, 234);
+ drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrSaveGame));
+ addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, "^", 255, 253);
+ addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, "\\", 255, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 320, 0, _vm->getSysString(kStrCancel), 255, 253);
+ addClickTextItem(kItemIdSavegame1, 0, 115 + 20 * 0, 300, 0, "SAVEGAME 1", 231, 234);
+ addClickTextItem(kItemIdSavegame2, 0, 115 + 20 * 1, 300, 0, "SAVEGAME 2", 231, 234);
+ addClickTextItem(kItemIdSavegame3, 0, 115 + 20 * 2, 300, 0, "SAVEGAME 3", 231, 234);
+ addClickTextItem(kItemIdSavegame4, 0, 115 + 20 * 3, 300, 0, "SAVEGAME 4", 231, 234);
+ addClickTextItem(kItemIdSavegame5, 0, 115 + 20 * 4, 300, 0, "SAVEGAME 5", 231, 234);
+ addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, "SAVEGAME 6", 231, 234);
+ addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, "SAVEGAME 7", 231, 234);
initSavegames();
_savegames.push_back(SavegameItem("", Common::String::printf("GAME %03d", _savegames.size() + 1)));
setSavegameCaptions();
break;
case kMenuIdVolumes:
- drawString(0, 74, 320, 1, 229, (byte*)"Adjust volume");
- drawString(0, 130, 200, 0, 246, (byte*)"Master");
- drawString(0, 155, 200, 0, 244, (byte*)"Voices");
- drawString(0, 180, 200, 0, 244, (byte*)"Music");
- drawString(0, 205, 200, 0, 244, (byte*)"Sound FX");
- drawString(0, 230, 200, 0, 244, (byte*)"Background");
- addClickTextItem(kItemIdDone, 0, 275, 200, 0, (const byte*)"DONE", 229, 253);
- addClickTextItem(kItemIdCancel, 0, 275, 440, 0, (const byte*)"CANCEL", 229, 253);
- addClickTextItem(kItemIdMasterDown, 0, 130 + 25 * 0, 348, 1, (const byte*)"[", 229, 253);
- addClickTextItem(kItemIdVoicesDown, 0, 130 + 25 * 1, 348, 1, (const byte*)"[", 229, 253);
- addClickTextItem(kItemIdMusicDown, 0, 130 + 25 * 2, 348, 1, (const byte*)"[", 229, 253);
- addClickTextItem(kItemIdSoundFXDown, 0, 130 + 25 * 3, 348, 1, (const byte*)"[", 229, 253);
- addClickTextItem(kItemIdBackgroundDown, 0, 130 + 25 * 4, 348, 1, (const byte*)"[", 229, 253);
- addClickTextItem(kItemIdMasterUp, 0, 130 + 25 * 0, 372, 1, (const byte*)"]", 229, 253);
- addClickTextItem(kItemIdVoicesUp, 0, 130 + 25 * 1, 372, 1, (const byte*)"]", 229, 253);
- addClickTextItem(kItemIdMusicUp, 0, 130 + 25 * 2, 372, 1, (const byte*)"]", 229, 253);
- addClickTextItem(kItemIdSoundFXUp, 0, 130 + 25 * 3, 372, 1, (const byte*)"]", 229, 253);
- addClickTextItem(kItemIdBackgroundUp, 0, 130 + 25 * 4, 372, 1, (const byte*)"]", 229, 253);
+ drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrAdjustVolume));
+ drawString(0, 130, 200, 0, 246, _vm->getSysString(kStrMaster));
+ drawString(0, 155, 200, 0, 244, _vm->getSysString(kStrVoices));
+ drawString(0, 180, 200, 0, 244, _vm->getSysString(kStrMusic));
+ drawString(0, 205, 200, 0, 244, _vm->getSysString(kStrSoundFx));
+ drawString(0, 230, 200, 0, 244, _vm->getSysString(kStrBackground));
+ addClickTextItem(kItemIdDone, 0, 275, 200, 0, _vm->getSysString(kStrDone), 229, 253);
+ addClickTextItem(kItemIdCancel, 0, 275, 440, 0, _vm->getSysString(kStrCancel), 229, 253);
+ addClickTextItem(kItemIdMasterDown, 0, 130 + 25 * 0, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdVoicesDown, 0, 130 + 25 * 1, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdMusicDown, 0, 130 + 25 * 2, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdSoundFXDown, 0, 130 + 25 * 3, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdBackgroundDown, 0, 130 + 25 * 4, 348, 1, "[", 229, 253);
+ addClickTextItem(kItemIdMasterUp, 0, 130 + 25 * 0, 372, 1, "]", 229, 253);
+ addClickTextItem(kItemIdVoicesUp, 0, 130 + 25 * 1, 372, 1, "]", 229, 253);
+ addClickTextItem(kItemIdMusicUp, 0, 130 + 25 * 2, 372, 1, "]", 229, 253);
+ addClickTextItem(kItemIdSoundFXUp, 0, 130 + 25 * 3, 372, 1, "]", 229, 253);
+ addClickTextItem(kItemIdBackgroundUp, 0, 130 + 25 * 4, 372, 1, "]", 229, 253);
drawVolumeBar(kItemIdMaster);
drawVolumeBar(kItemIdVoices);
drawVolumeBar(kItemIdMusic);
@@ -420,13 +428,14 @@ void MenuSystem::shadeRect(int x, int y, int w, int h, byte color1, byte color2)
}
}
-void MenuSystem::drawString(int16 x, int16 y, int w, uint fontNum, byte color, byte *text) {
+void MenuSystem::drawString(int16 x, int16 y, int w, uint fontNum, byte color, const char *text) {
fontNum = _vm->_screen->getFontResIndex(fontNum);
Font font(_vm->_res->load(fontNum)->data);
if (w) {
- x = x + w - font.getTextWidth(text) / 2;
+ x = x + w - font.getTextWidth((const byte*)text) / 2;
}
- _vm->_screen->drawString(x, y - font.getHeight(), color, fontNum, text, -1, NULL, true);
+ _vm->_screen->drawString(x, y - font.getHeight(), color, fontNum, (const byte*)text, -1, NULL, true);
+ _needRedraw = true;
}
void MenuSystem::initSavegames() {
@@ -474,13 +483,13 @@ void MenuSystem::initSavegames() {
void MenuSystem::setSavegameCaptions() {
uint index = _savegameListTopIndex;
- setItemCaption(getItem(kItemIdSavegame1), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
- setItemCaption(getItem(kItemIdSavegame2), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
- setItemCaption(getItem(kItemIdSavegame3), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
- setItemCaption(getItem(kItemIdSavegame4), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
- setItemCaption(getItem(kItemIdSavegame5), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
- setItemCaption(getItem(kItemIdSavegame6), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
- setItemCaption(getItem(kItemIdSavegame7), index < _savegames.size() ? (const byte*)_savegames[index++]._description.c_str() : (const byte*)"");
+ setItemCaption(getItem(kItemIdSavegame1), index < _savegames.size() ? _savegames[index++]._description.c_str() : "");
+ setItemCaption(getItem(kItemIdSavegame2), index < _savegames.size() ? _savegames[index++]._description.c_str() : "");
+ setItemCaption(getItem(kItemIdSavegame3), index < _savegames.size() ? _savegames[index++]._description.c_str() : "");
+ setItemCaption(getItem(kItemIdSavegame4), index < _savegames.size() ? _savegames[index++]._description.c_str() : "");
+ setItemCaption(getItem(kItemIdSavegame5), index < _savegames.size() ? _savegames[index++]._description.c_str() : "");
+ setItemCaption(getItem(kItemIdSavegame6), index < _savegames.size() ? _savegames[index++]._description.c_str() : "");
+ setItemCaption(getItem(kItemIdSavegame7), index < _savegames.size() ? _savegames[index++]._description.c_str() : "");
}
void MenuSystem::scrollSavegames(int delta) {
@@ -540,8 +549,8 @@ void MenuSystem::setCfgText(bool value, bool active) {
if (_cfgText != value) {
Item *item = getItem(kItemIdToggleText);
_cfgText = value;
- restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
- setItemCaption(item, _cfgText ? (const byte*)"TEXT ON" : (const byte*)"TEXT OFF");
+ restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
+ setItemCaption(item, _vm->getSysString(_cfgText ? kStrTextOn : kStrTextOff));
drawItem(kItemIdToggleText, true);
}
}
@@ -551,7 +560,7 @@ void MenuSystem::setCfgVoices(bool value, bool active) {
Item *item = getItem(kItemIdToggleVoices);
_cfgVoices = value;
restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
- setItemCaption(item, _cfgVoices ? (const byte*)"VOICES ON" : (const byte*)"VOICES OFF");
+ setItemCaption(item, _vm->getSysString(_cfgVoices ? kStrVoicesOn : kStrVoicesOff));
drawItem(kItemIdToggleVoices, true);
}
}
@@ -592,7 +601,7 @@ void MenuSystem::drawVolumeBar(ItemID itemID) {
text[i] = '|';
text[volume] = 0;
- drawString(0, y, w, 0, 246, (byte*)text);
+ drawString(0, y, w, 0, 246, text);
}
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 5860afd..e71557e 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -132,6 +132,7 @@ protected:
bool _editingDescription;
ItemID _editingDescriptionID;
Item *_editingDescriptionItem;
+ bool _needRedraw;
Common::Array<Item> _items;
Common::Array<SavegameItem> _savegames;
@@ -139,7 +140,7 @@ protected:
bool _cfgText, _cfgVoices;
int _cfgMasterVolume, _cfgVoicesVolume, _cfgMusicVolume, _cfgSoundFXVolume, _cfgBackgroundVolume;
- void addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const byte *caption, byte defaultColor, byte activeColor);
+ void addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const char *caption, byte defaultColor, byte activeColor);
void drawItem(ItemID itemID, bool active);
void handleMouseMove(int x, int y);
@@ -148,7 +149,7 @@ protected:
ItemID findItemAt(int x, int y);
Item *getItem(ItemID id);
- void setItemCaption(Item *item, const byte *caption);
+ void setItemCaption(Item *item, const char *caption);
void initMenu(MenuID menuID);
@@ -158,7 +159,7 @@ protected:
void restoreRect(int x, int y, int w, int h);
void shadeRect(int x, int y, int w, int h, byte color1, byte color2);
- void drawString(int16 x, int16 y, int w, uint fontNum, byte color, byte *text);
+ void drawString(int16 x, int16 y, int w, uint fontNum, byte color, const char *text);
void initSavegames();
void setSavegameCaptions();
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 6ac916e..9f0ff51 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -140,7 +140,7 @@ void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
byte *dest = _frontScreen + x + (y + _vm->_cameraHeight) * 640;
- debug(0, "Screen::drawGuiImage() x = %d; y = %d; w = %d; h = %d; resIndex = %d", x, y, width, height, resIndex);
+ //debug(0, "Screen::drawGuiImage() x = %d; y = %d; w = %d; h = %d; resIndex = %d", x, y, width, height, resIndex);
while (workHeight > 0) {
int count = 1;
@@ -202,7 +202,7 @@ void Screen::addStaticSprite(byte *spriteItem) {
drawRequest.flags = READ_LE_UINT16(spriteItem + 8);
drawRequest.scaling = 0;
- debug(0, "Screen::addStaticSprite() x = %d; y = %d; baseColor = %d; resIndex = %d; flags = %04X", drawRequest.x, drawRequest.y, drawRequest.baseColor, drawRequest.resIndex, drawRequest.flags);
+ //debug(0, "Screen::addStaticSprite() x = %d; y = %d; baseColor = %d; resIndex = %d; flags = %04X", drawRequest.x, drawRequest.y, drawRequest.baseColor, drawRequest.resIndex, drawRequest.flags);
addDrawRequest(drawRequest);
@@ -210,7 +210,7 @@ void Screen::addStaticSprite(byte *spriteItem) {
void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, int16 *spriteArray, bool loop, int mode) {
- debug(0, "Screen::addAnimatedSprite(%d, %d, %d)", x, y, fragmentId);
+ //debug(0, "Screen::addAnimatedSprite(%d, %d, %d)", x, y, fragmentId);
DrawRequest drawRequest;
memset(&drawRequest, 0, sizeof(drawRequest));
@@ -227,7 +227,7 @@ void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, i
int16 count = spriteArray[0];
- debug(0, "count = %d", count);
+ //debug(0, "count = %d", count);
for (int16 index = 1; index <= count; index++) {
@@ -581,14 +581,14 @@ void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uin
}
-int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len, int16 *ywobble, bool outline) {
+int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const byte *text, int len, int16 *ywobble, bool outline) {
- debug(0, "Screen::drawString(%d, %d, %d, %d)", x, y, color, fontResIndex);
+ //debug(0, "Screen::drawString(%d, %d, %d, %d)", x, y, color, fontResIndex);
Font font(_vm->_res->load(fontResIndex)->data);
if (len == -1)
- len = strlen((char*)text);
+ len = strlen((const char*)text);
int16 yadd = 0;
if (ywobble)
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index 4aeeb78..bd332a9 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -98,7 +98,7 @@ public:
byte *getCharData(byte ch) const {
return _fontData + 0x298 + READ_LE_UINT16(&_fontData[0xE0 + (ch - 0x21) * 2]);
}
- int16 getTextWidth(byte *text) {
+ int16 getTextWidth(const byte *text) {
int16 width = 0;
while (*text && *text < 0xF0) {
byte ch = *text++;
@@ -201,7 +201,7 @@ public:
int16 wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState);
void drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex, GuiTextWrapState &wrapState);
- int16 drawString(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len = -1, int16 *ywobble = NULL, bool outline = false);
+ int16 drawString(int16 x, int16 y, byte color, uint fontResIndex, const byte *text, int len = -1, int16 *ywobble = NULL, bool outline = false);
void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline);
void drawSurface(int16 x, int16 y, Graphics::Surface *surface);
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 0c8d565..93d4325 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -125,8 +125,8 @@ Common::Error ToltecsEngine::run() {
_mouseX = 0;
_mouseY = 0;
- _mouseCounter = 0;
- _mouseButtonPressedFlag = false;
+ _mouseDblClickTicks = 60;
+ _mouseWaitForRelease = false;
_mouseButton = 0;
_mouseDisabled = 0;
_leftButtonDown = false;
@@ -152,7 +152,9 @@ Common::Error ToltecsEngine::run() {
syncSoundSettings();
-//#define TEST_MENU
+ setupSysStrings();
+
+#define TEST_MENU
#ifdef TEST_MENU
_screen->registerFont(0, 0x0D);
_screen->registerFont(1, 0x0E);
@@ -199,6 +201,17 @@ Common::Error ToltecsEngine::run() {
return Common::kNoError;
}
+void ToltecsEngine::setupSysStrings() {
+ Resource *sysStringsResource = _res->load(15);
+ const char *sysStrings = (const char*)sysStringsResource->data;
+ for (int i = 0; i < kSysStrCount; i++) {
+ debug(1, "sysStrings[%d] = [%s]", i, sysStrings);
+ _sysStrings[i] = sysStrings;
+ sysStrings += strlen(sysStrings) + 1;
+ }
+ // TODO: Set yes/no chars
+}
+
void ToltecsEngine::loadScene(uint resIndex) {
// TODO
@@ -323,10 +336,10 @@ void ToltecsEngine::updateInput() {
}
}
- if (_mouseDisabled == 0) {
+ if (!_mouseDisabled) {
- if (_mouseCounter > 0)
- _mouseCounter--;
+ if (_mouseDblClickTicks > 0)
+ _mouseDblClickTicks--;
byte mouseButtons = 0;
if (_leftButtonDown)
@@ -335,17 +348,18 @@ void ToltecsEngine::updateInput() {
mouseButtons |= 2;
if (mouseButtons != 0) {
- if (!_mouseButtonPressedFlag) {
+ if (!_mouseWaitForRelease) {
_mouseButton = mouseButtons;
- if (_mouseCounter != 0)
- _mouseButton |= 0x80;
- _mouseCounter = 30; // maybe TODO
- _mouseButtonPressedFlag = true;
+ if (_mouseDblClickTicks > 0)
+ _mouseButton = 0x80;
+ //if (_mouseButton == 0x80) debug("DBL!");
+ _mouseDblClickTicks = 30; // maybe TODO
+ _mouseWaitForRelease = true;
} else {
_mouseButton = 0;
}
} else {
- _mouseButtonPressedFlag = false;
+ _mouseWaitForRelease = false;
_mouseButton = 0;
}
@@ -429,7 +443,7 @@ void ToltecsEngine::updateCamera() {
_screen->finishTalkTextItems();
}
- debug(0, "ToltecsEngine::updateCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
+ //debug(0, "ToltecsEngine::updateCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY);
}
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index bcd2c3d..851e28c 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -60,6 +60,34 @@ class Sound;
// TODO/FIXME: The includes of the Toltecs engine need serious clean-up
+enum SysString {
+ kStrLoadingPleaseWait,
+ kStrWhatCanIDoForYou,
+ kStrLoad,
+ kStrSave,
+ kStrTextOn,
+ kStrTextOff,
+ kStrVoicesOn,
+ kStrVoicesOff,
+ kStrVolume,
+ kStrPlay,
+ kStrQuit,
+ kStrLoadGame,
+ kStrSaveGame,
+ kStrAdjustVolume,
+ kStrMaster,
+ kStrVoices,
+ kStrMusic,
+ kStrSoundFx,
+ kStrBackground,
+ kStrCancel,
+ kStrDone,
+ kStrAreYouSure,
+ kStrYes,
+ kStrNo,
+ kSysStrCount
+};
+
class ToltecsEngine : public ::Engine {
Common::KeyState _keyPressed;
@@ -80,6 +108,8 @@ public:
Common::Language getLanguage() const;
const Common::String& getTargetName() const { return _targetName; }
+ void setupSysStrings();
+
void loadScene(uint resIndex);
void updateScreen();
@@ -115,6 +145,8 @@ public:
SegmentMap *_segmap;
Sound *_sound;
+ Common::String _sysStrings[kSysStrCount];
+
uint _sceneResIndex;
int16 _sceneWidth, _sceneHeight;
@@ -133,12 +165,14 @@ public:
Common::KeyState _keyState;
int16 _mouseX, _mouseY;
- int16 _mouseCounter;
- bool _mouseButtonPressedFlag;
+ int16 _mouseDblClickTicks;
+ bool _mouseWaitForRelease;
byte _mouseButton;
int16 _mouseDisabled;
bool _leftButtonDown, _rightButtonDown;
+ const char *getSysString(int index) const { return _sysStrings[index].c_str(); }
+
/* Save/load */
enum kReadSaveHeaderError {
Commit: 9698127c5d78c92f99032d55dec5fe1feb773ae4
https://github.com/scummvm/scummvm/commit/9698127c5d78c92f99032d55dec5fe1feb773ae4
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: - Undef menu test code (oops)
- Rename updateScreen to drawScreen
- Move code from sfUpdateScreen to engine updateScreen
- Use better screen sync code to get closer to the original game's speed
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 4e15fa3..0c9f89e 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -806,38 +806,7 @@ void ScriptInterpreter::sfSetGameVar() {
}
void ScriptInterpreter::sfUpdateScreen() {
-
- _vm->_sound->updateSpeech();
-
- _vm->_screen->updateShakeScreen();
-
- // TODO: Set quit flag
- if (_vm->shouldQuit())
- return;
-
- if (!_vm->_movieSceneFlag)
- _vm->updateInput();
- else
- _vm->_mouseButton = 0;
-
- // TODO? Check keyb
-
- _vm->_counter01--;
- if (_vm->_counter01 <= 0) {
- _vm->_counter01 = MIN(_vm->_counter02, 30);
- _vm->_counter02 = 0;
- _vm->updateScreen();
- _vm->_flag01 = 1;
- _vm->_system->delayMillis(5);
- _vm->_counter02 = 1; // ?
- } else {
- _vm->_screen->clearSprites();
- _vm->_flag01 = 0;
- //_vm->_system->updateScreen();
- }
-
- // TODO
-
+ _vm->updateScreen();
}
void ScriptInterpreter::sfGetRandomNumber() {
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 93d4325..7fde696 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -154,7 +154,7 @@ Common::Error ToltecsEngine::run() {
setupSysStrings();
-#define TEST_MENU
+//#define TEST_MENU
#ifdef TEST_MENU
_screen->registerFont(0, 0x0D);
_screen->registerFont(1, 0x0E);
@@ -254,6 +254,45 @@ void ToltecsEngine::loadScene(uint resIndex) {
void ToltecsEngine::updateScreen() {
+ _sound->updateSpeech();
+
+ _screen->updateShakeScreen();
+
+ // TODO: Set quit flag
+ if (shouldQuit())
+ return;
+
+ if (!_movieSceneFlag)
+ updateInput();
+ else
+ _mouseButton = 0;
+
+ // TODO? Check keyb
+
+ _counter01--;
+ if (_counter01 <= 0) {
+ _counter01 = MIN(_counter02, 30);
+ _counter02 = 0;
+ drawScreen();
+ _flag01 = 1;
+ _counter02 = 1;
+ } else {
+ _screen->clearSprites();
+ _flag01 = 0;
+ }
+
+ static uint32 prevUpdateTime = 0;
+ uint32 currUpdateTime;
+ do {
+ currUpdateTime = _system->getMillis();
+ _counter02 = (currUpdateTime - prevUpdateTime) / 13;
+ } while (_counter02 == 0);
+ prevUpdateTime = currUpdateTime;
+
+}
+
+void ToltecsEngine::drawScreen() {
+
// FIXME: Quick hack, sometimes cameraY was negative (the code in updateCamera was at fault)
if (_cameraY < 0) _cameraY = 0;
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 851e28c..9d7a767 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -113,6 +113,7 @@ public:
void loadScene(uint resIndex);
void updateScreen();
+ void drawScreen();
void updateInput();
void setGuiHeight(int16 guiHeight);
Commit: 1cb95f36e72dd4b4e86a0a1bf49e1b797c5781c2
https://github.com/scummvm/scummvm/commit/1cb95f36e72dd4b4e86a0a1bf49e1b797c5781c2
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: - More work on the menu system, saving and loading from there is now possible
- Add blastSprite method which draws a sprite directly to the frontScreen without the renderQueue
- Add F10 scancode in sfHandleInput to open the menu
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/menu.h
engines/toltecs/palette.cpp
engines/toltecs/palette.h
engines/toltecs/screen.cpp
engines/toltecs/screen.h
engines/toltecs/script.cpp
engines/toltecs/sprite.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 2747858..cbb27cd 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -35,16 +35,27 @@
#include "toltecs/toltecs.h"
#include "toltecs/menu.h"
#include "toltecs/palette.h"
+#include "toltecs/render.h"
#include "toltecs/resource.h"
#include "toltecs/screen.h"
namespace Toltecs {
MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
+}
+
+MenuSystem::~MenuSystem() {
+}
+
+int MenuSystem::run() {
+
+ debug("MenuSystem::run()");
+
+ _background = new Graphics::Surface();
+ _background->create(640, 400, 1);
+
_currMenuID = kMenuIdNone;
_newMenuID = kMenuIdMain;
- _newMenuID = kMenuIdSave;
- _newMenuID = kMenuIdLoad;
_currItemID = kItemIdNone;
_editingDescription = false;
_needRedraw = false;
@@ -55,32 +66,23 @@ MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm) {
_cfgMusicVolume = 10;
_cfgSoundFXVolume = 10;
_cfgBackgroundVolume = 10;
-}
-
-MenuSystem::~MenuSystem() {
-}
-
-int MenuSystem::run() {
-
- _background = new Graphics::Surface();
- _background->create(640, 400, 1);
-
+ _running = true;
_top = 30 - _vm->_guiHeight / 2;
_needRedraw = false;
- memset(_vm->_screen->_frontScreen, 250, 640 * 400);
+ // TODO: buildColorTransTable2
+ _vm->_palette->buildColorTransTable(0, 16, 7);
- memcpy(_background->pixels, _vm->_screen->_frontScreen, 640 * 400);
+ _vm->_screen->_renderQueue->clear();
+ _vm->_screen->blastSprite(0x140 + _vm->_cameraX, 0x175 + _vm->_cameraY, 0, 1, 0x4000);
- _vm->_palette->buildColorTransTable(0, 16, 7);
+ memcpy(_background->pixels, _vm->_screen->_frontScreen, 640 * 400);
shadeRect(60, 39, 520, 246, 30, 94);
- _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, 400);
-
- while (1) {
+ while (_running) {
update();
- _vm->updateScreen();
+ _vm->_system->updateScreen();
}
delete _background;
@@ -99,7 +101,8 @@ void MenuSystem::update() {
handleEvents();
if (_needRedraw) {
- _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen + 39 * 640 + 60, 640, 60, 39, 520, 247);
+ //_vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen + 39 * 640 + 60, 640, 60, 39, 520, 247);
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, 400);
debug("redraw");
_needRedraw = false;
}
@@ -118,7 +121,7 @@ void MenuSystem::handleEvents() {
handleKeyDown(event.kbd);
break;
case Common::EVENT_QUIT:
- // TODO: quitGame();
+ _running = false;
break;
case Common::EVENT_MOUSEMOVE:
handleMouseMove(event.mouse.x, event.mouse.y);
@@ -187,8 +190,12 @@ void MenuSystem::handleKeyDown(const Common::KeyState& kbd) {
setItemCaption(_editingDescriptionItem, _editingDescriptionItem->caption.c_str());
drawItem(_editingDescriptionID, true);
} else if (kbd.keycode == Common::KEYCODE_RETURN) {
+ SavegameItem *savegameItem = getSavegameItemByID(_editingDescriptionID);
+ _editingDescription = false;
+ _vm->requestSavegame(savegameItem->_slotNum, _editingDescriptionItem->caption);
+ _running = false;
+ } else if (kbd.keycode == Common::KEYCODE_ESCAPE) {
_editingDescription = false;
- _newMenuID = kMenuIdMain;
}
}
}
@@ -222,6 +229,8 @@ void MenuSystem::setItemCaption(Item *item, const char *caption) {
void MenuSystem::initMenu(MenuID menuID) {
+ int newSlotNum;
+
_items.clear();
memcpy(_vm->_screen->_frontScreen, _background->pixels, 640 * 400);
@@ -249,7 +258,7 @@ void MenuSystem::initMenu(MenuID menuID) {
addClickTextItem(kItemIdSavegame5, 0, 115 + 20 * 4, 300, 0, "SAVEGAME 5", 231, 234);
addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, "SAVEGAME 6", 231, 234);
addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, "SAVEGAME 7", 231, 234);
- initSavegames();
+ loadSavegamesList();
setSavegameCaptions();
break;
case kMenuIdSave:
@@ -264,8 +273,8 @@ void MenuSystem::initMenu(MenuID menuID) {
addClickTextItem(kItemIdSavegame5, 0, 115 + 20 * 4, 300, 0, "SAVEGAME 5", 231, 234);
addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, "SAVEGAME 6", 231, 234);
addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, "SAVEGAME 7", 231, 234);
- initSavegames();
- _savegames.push_back(SavegameItem("", Common::String::printf("GAME %03d", _savegames.size() + 1)));
+ newSlotNum = loadSavegamesList() + 1;
+ _savegames.push_back(SavegameItem(newSlotNum, Common::String::printf("GAME %03d", _savegames.size() + 1)));
setSavegameCaptions();
break;
case kMenuIdVolumes:
@@ -337,6 +346,7 @@ void MenuSystem::clickItem(ItemID id) {
break;
case kItemIdPlay:
debug("kItemIdPlay");
+ _running = false;
break;
case kItemIdQuit:
debug("kItemIdQuit");
@@ -410,6 +420,7 @@ void MenuSystem::restoreRect(int x, int y, int w, int h) {
}
void MenuSystem::shadeRect(int x, int y, int w, int h, byte color1, byte color2) {
+#if 0
byte *src = (byte*)_background->getBasePtr(x, y);
for (int xc = 0; xc < w; xc++) {
src[xc] = color1;
@@ -426,6 +437,20 @@ void MenuSystem::shadeRect(int x, int y, int w, int h, byte color1, byte color2)
}
src += 640;
}
+#endif
+ byte *src = (byte*)_background->getBasePtr(x, y);
+ for (int xc = 0; xc < w; xc++) {
+ src[xc] = color2;
+ src[xc + h * 640] = color1;
+ }
+ src += 640;
+ w -= 1;
+ h -= 1;
+ while (h--) {
+ src[0] = color2;
+ src[w] = color1;
+ src += 640;
+ }
}
void MenuSystem::drawString(int16 x, int16 y, int w, uint fontNum, byte color, const char *text) {
@@ -438,11 +463,13 @@ void MenuSystem::drawString(int16 x, int16 y, int w, uint fontNum, byte color, c
_needRedraw = true;
}
-void MenuSystem::initSavegames() {
+int MenuSystem::loadSavegamesList() {
+
+ int maxSlotNum = -1;
_savegameListTopIndex = 0;
_savegames.clear();
-
+
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Toltecs::ToltecsEngine::SaveHeader header;
Common::String pattern = _vm->getTargetName();
@@ -453,32 +480,45 @@ void MenuSystem::initSavegames() {
Common::sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
- Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
- if (in) {
- if (_vm->readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
- _savegames.push_back(SavegameItem(*file, header.description));
- debug("%s -> %s", file->c_str(), header.description.c_str());
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 3);
+ if (slotNum > maxSlotNum)
+ maxSlotNum = slotNum;
+
+ if (slotNum >= 0 && slotNum <= 999) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+ if (in) {
+ if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ _savegames.push_back(SavegameItem(slotNum, header.description));
+ debug("%s -> %s", file->c_str(), header.description.c_str());
+ }
+ delete in;
}
- delete in;
}
}
-#if 0
- // DEBUG: Add some more items
- _savegames.push_back(SavegameItem("abc", "Test 1"));
- _savegames.push_back(SavegameItem("abc", "Test 2"));
- _savegames.push_back(SavegameItem("abc", "Test 3"));
- _savegames.push_back(SavegameItem("abc", "Test 4"));
- _savegames.push_back(SavegameItem("abc", "Test 5"));
- _savegames.push_back(SavegameItem("abc", "Test 6"));
- _savegames.push_back(SavegameItem("abc", "Test 7"));
- _savegames.push_back(SavegameItem("abc", "Test 8"));
- _savegames.push_back(SavegameItem("abc", "Test 9"));
- _savegames.push_back(SavegameItem("abc", "Test 10"));
- _savegames.push_back(SavegameItem("abc", "Test 11"));
- _savegames.push_back(SavegameItem("abc", "Test 12"));
-#endif
+ return maxSlotNum;
+}
+MenuSystem::SavegameItem *MenuSystem::getSavegameItemByID(ItemID id) {
+ switch (id) {
+ case kItemIdSavegame1:
+ return &_savegames[_savegameListTopIndex + 0];
+ case kItemIdSavegame2:
+ return &_savegames[_savegameListTopIndex + 1];
+ case kItemIdSavegame3:
+ return &_savegames[_savegameListTopIndex + 2];
+ case kItemIdSavegame4:
+ return &_savegames[_savegameListTopIndex + 3];
+ case kItemIdSavegame5:
+ return &_savegames[_savegameListTopIndex + 4];
+ case kItemIdSavegame6:
+ return &_savegames[_savegameListTopIndex + 5];
+ case kItemIdSavegame7:
+ return &_savegames[_savegameListTopIndex + 6];
+ default:
+ return NULL;
+ }
}
void MenuSystem::setSavegameCaptions() {
@@ -508,33 +548,11 @@ void MenuSystem::scrollSavegames(int delta) {
void MenuSystem::clickSavegameItem(ItemID id) {
if (_currMenuID == kMenuIdLoad) {
- SavegameItem *savegameItem;
- switch (id) {
- case kItemIdSavegame1:
- savegameItem = &_savegames[_savegameListTopIndex + 0];
- break;
- case kItemIdSavegame2:
- savegameItem = &_savegames[_savegameListTopIndex + 1];
- break;
- case kItemIdSavegame3:
- savegameItem = &_savegames[_savegameListTopIndex + 2];
- break;
- case kItemIdSavegame4:
- savegameItem = &_savegames[_savegameListTopIndex + 3];
- break;
- case kItemIdSavegame5:
- savegameItem = &_savegames[_savegameListTopIndex + 4];
- break;
- case kItemIdSavegame6:
- savegameItem = &_savegames[_savegameListTopIndex + 5];
- break;
- case kItemIdSavegame7:
- savegameItem = &_savegames[_savegameListTopIndex + 6];
- break;
- default:
- return;
- }
- debug("filename = [%s]; description = [%s]", savegameItem->_filename.c_str(), savegameItem->_description.c_str());
+ SavegameItem *savegameItem = getSavegameItemByID(id);
+ debug("slotNum = [%d]; description = [%s]", savegameItem->_slotNum, savegameItem->_description.c_str());
+ //_vm->loadgame(savegameItem->_filename.c_str());
+ _vm->requestLoadgame(savegameItem->_slotNum);
+ _running = false;
} else {
_editingDescription = true;
_editingDescriptionItem = getItem(id);
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index e71557e..12f48ca 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -114,17 +114,18 @@ protected:
};
struct SavegameItem {
- Common::String _filename;
+ int _slotNum;
Common::String _description;
SavegameItem()
- : _filename(""), _description("") {}
- SavegameItem(Common::String filename, Common::String description)
- : _filename(filename), _description(description) {}
+ : _slotNum(-1), _description("") {}
+ SavegameItem(int slotNum, Common::String description)
+ : _slotNum(slotNum), _description(description) {}
};
ToltecsEngine *_vm;
Graphics::Surface *_background;
+ bool _running;
MenuID _currMenuID, _newMenuID;
ItemID _currItemID;
int _top;
@@ -161,7 +162,9 @@ protected:
void shadeRect(int x, int y, int w, int h, byte color1, byte color2);
void drawString(int16 x, int16 y, int w, uint fontNum, byte color, const char *text);
- void initSavegames();
+ SavegameItem *getSavegameItemByID(ItemID id);
+
+ int loadSavegamesList();
void setSavegameCaptions();
void scrollSavegames(int delta);
void clickSavegameItem(ItemID id);
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 52f847e..1236d98 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -199,6 +199,12 @@ void Palette::buildColorTransTable(byte limit, char deltaValue, byte mask) {
}
+void Palette::buildColorTransTable2(byte limit, char deltaValue, byte mask) {
+
+ // TODO
+
+}
+
void Palette::saveState(Common::WriteStream *out) {
// Save currently active palette
diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h
index 920aded..59f0504 100644
--- a/engines/toltecs/palette.h
+++ b/engines/toltecs/palette.h
@@ -60,6 +60,7 @@ public:
void clearFragments();
void buildColorTransTable(byte limit, char deltaValue, byte mask);
+ void buildColorTransTable2(byte limit, char deltaValue, byte mask);
byte getColorTransPixel(byte pixel) const { return _colorTransTable[pixel]; }
byte *getMainPalette() { return _mainPalette; }
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 9f0ff51..91527bd 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -70,7 +70,7 @@ Screen::Screen(ToltecsEngine *vm) : _vm(vm) {
// Talk text
_talkTextItemNum = 0;
memset(_talkTextItems, 0, sizeof(_talkTextItems));
- _talkTextX = 0;//TODO correct init values
+ _talkTextX = 0;
_talkTextY = 0;
_talkTextFontColor = 0;
_talkTextMaxWidth = 520;
@@ -202,7 +202,7 @@ void Screen::addStaticSprite(byte *spriteItem) {
drawRequest.flags = READ_LE_UINT16(spriteItem + 8);
drawRequest.scaling = 0;
- //debug(0, "Screen::addStaticSprite() x = %d; y = %d; baseColor = %d; resIndex = %d; flags = %04X", drawRequest.x, drawRequest.y, drawRequest.baseColor, drawRequest.resIndex, drawRequest.flags);
+ debug(0, "Screen::addStaticSprite() x = %d; y = %d; baseColor = %d; resIndex = %d; flags = %04X", drawRequest.x, drawRequest.y, drawRequest.baseColor, drawRequest.resIndex, drawRequest.flags);
addDrawRequest(drawRequest);
@@ -271,6 +271,26 @@ void Screen::clearSprites() {
}
+void Screen::blastSprite(int16 x, int16 y, int16 fragmentId, int16 resIndex, uint16 flags) {
+
+ DrawRequest drawRequest;
+ SpriteDrawItem sprite;
+
+ drawRequest.x = x;
+ drawRequest.y = y;
+ drawRequest.baseColor = _vm->_palette->findFragment(fragmentId) & 0xFF;
+ drawRequest.resIndex = resIndex;
+ drawRequest.flags = flags;
+ drawRequest.scaling = 0;
+
+ if (createSpriteDrawItem(drawRequest, sprite)) {
+ sprite.x -= _vm->_cameraX;
+ sprite.y -= _vm->_cameraY;
+ drawSprite(sprite);
+ }
+
+}
+
void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
debug(0, "Screen::updateVerbLine() _verbLineNum = %d; _verbLineX = %d; _verbLineY = %d; _verbLineWidth = %d; _verbLineCount = %d",
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index bd332a9..b7e1491 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -183,6 +183,7 @@ public:
// Sprite drawing
void drawSprite(const SpriteDrawItem &sprite);
void drawSpriteCore(byte *dest, SpriteFilter &reader, const SpriteDrawItem &sprite);
+ void blastSprite(int16 x, int16 y, int16 fragmentId, int16 resIndex, uint16 flags);
// Verb line
void updateVerbLine(int16 slotIndex, int16 slotOffset);
@@ -252,6 +253,7 @@ public:
bool _fullRefresh;
bool _guiRefresh;
+ bool createSpriteDrawItem(const DrawRequest &drawRequest, SpriteDrawItem &sprite);
void addDrawRequest(const DrawRequest &drawRequest);
};
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 0c9f89e..3c20600 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -36,6 +36,7 @@
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
+#include "toltecs/menu.h"
#include "toltecs/movie.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
@@ -180,6 +181,14 @@ void ScriptInterpreter::runScript() {
if (_vm->_movieSceneFlag)
_vm->_mouseButton = 0;
+
+ if (_vm->_saveLoadRequested != 0) {
+ if (_vm->_saveLoadRequested == 1)
+ _vm->loadGameState(_vm->_saveLoadSlot);
+ else if (_vm->_saveLoadRequested == 2)
+ _vm->saveGameState(_vm->_saveLoadSlot, _vm->_saveLoadDescription.c_str());
+ _vm->_saveLoadRequested = 0;
+ }
if (_switchLocalDataNear) {
_switchLocalDataNear = false;
@@ -1037,20 +1046,38 @@ void ScriptInterpreter::sfClearScreen() {
}
void ScriptInterpreter::sfHandleInput() {
- // TODO: Recheck what this does
int16 varOfs = arg16(3);
int16 keyCode = 0;
if (_vm->_rightButtonDown) {
keyCode = 1;
} else {
- // TODO: Handle Escape
- // TODO: Set keyboard scancode
+ /* Convert keyboard scancode to IBM PC scancode
+ Only scancodes known to be used (so far) are converted
+ */
+ switch (_vm->_keyState.keycode) {
+ case Common::KEYCODE_ESCAPE:
+ keyCode = 1;
+ break;
+ case Common::KEYCODE_F10:
+ keyCode = 68;
+ break;
+ default:
+ break;
+ }
}
localWrite16(varOfs, keyCode);
}
void ScriptInterpreter::sfRunOptionsScreen() {
- // TODO
+ _vm->_screen->loadMouseCursor(12);
+ _vm->_palette->loadAddPalette(9, 224);
+ _vm->_palette->setDeltaPalette(_vm->_palette->getMainPalette(), 7, 0, 31, 224);
+ _vm->_screen->finishTalkTextItems();
+ _vm->_screen->clearSprites();
+ _vm->_system->showMouse(true);
+ _vm->_menuSystem->run();
+ _vm->_keyState.reset();
+ _switchLocalDataNear = true;
}
/* NOTE: The opcodes sfPrecacheSprites, sfPrecacheSounds1, sfPrecacheSounds2 and
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index 84b485d..b6654b5 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -193,18 +193,16 @@ protected:
int _scalerStatus;
};
-void Screen::addDrawRequest(const DrawRequest &drawRequest) {
-
+bool Screen::createSpriteDrawItem(const DrawRequest &drawRequest, SpriteDrawItem &sprite) {
int16 scaleValueX, scaleValueY;
int16 xoffs, yoffs;
byte *spriteData;
int16 frameNum;
- SpriteDrawItem sprite;
memset(&sprite, 0, sizeof(SpriteDrawItem));
if (drawRequest.flags == 0xFFFF)
- return;
+ return false;
frameNum = drawRequest.flags & 0x0FFF;
@@ -215,7 +213,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.priority = drawRequest.y;
sprite.resIndex = drawRequest.resIndex;
sprite.frameNum = frameNum;
-
+
spriteData = _vm->_res->load(drawRequest.resIndex)->data;
if (drawRequest.flags & 0x1000) {
@@ -233,15 +231,14 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
// First initialize the sprite item with the values from the sprite resource
SpriteFrameEntry spriteFrameEntry(spriteData + frameNum * 12);
-
+
if (spriteFrameEntry.w == 0 || spriteFrameEntry.h == 0)
- return;
+ return false;
sprite.offset = spriteFrameEntry.offset;
sprite.width = spriteFrameEntry.w;
sprite.height = spriteFrameEntry.h;
-
sprite.origWidth = spriteFrameEntry.w;
sprite.origHeight = spriteFrameEntry.h;
@@ -278,7 +275,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.width = sprite.origWidth - scaleValueX;
sprite.height = sprite.origHeight - 1 - scaleValueY;
if (sprite.width <= 0 || sprite.height <= 0)
- return;
+ return false;
xoffs -= (xoffs * scaleValue) / 100;
yoffs -= (yoffs * scaleValue) / 100;
}
@@ -301,7 +298,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
sprite.height -= clipHeight;
if (sprite.height <= 0)
- return;
+ return false;
sprite.y = _vm->_cameraY;
@@ -332,7 +329,6 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
}
spriteFrameData = spriteData + sprite.offset;
-
// Now the sprite's offset is adjusted to point to the starting line
if ((sprite.flags & 0x10) == 0) {
while (skipHeight--) {
@@ -359,7 +355,7 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
if (sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight > 0)
sprite.height -= sprite.y + sprite.height - _vm->_cameraY - _vm->_cameraHeight;
if (sprite.height <= 0)
- return;
+ return false;
sprite.skipX = 0;
@@ -391,10 +387,15 @@ void Screen::addDrawRequest(const DrawRequest &drawRequest) {
}
if (sprite.width <= 0)
- return;
+ return false;
- _renderQueue->addSprite(sprite);
-
+ return true;
+}
+
+void Screen::addDrawRequest(const DrawRequest &drawRequest) {
+ SpriteDrawItem sprite;
+ if (createSpriteDrawItem(drawRequest, sprite))
+ _renderQueue->addSprite(sprite);
}
void Screen::drawSprite(const SpriteDrawItem &sprite) {
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 7fde696..9a0f669 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -105,7 +105,9 @@ Common::Error ToltecsEngine::run() {
_counter02 = 0;
_movieSceneFlag = false;
_flag01 = 0;
-
+
+ _saveLoadRequested = 0;
+
_cameraX = 0;
_cameraY = 0;
_newCameraX = 0;
@@ -148,10 +150,10 @@ Common::Error ToltecsEngine::run() {
_sound = new Sound(this);
- _system->showMouse(true);
-
syncSoundSettings();
+ _system->showMouse(true);
+
setupSysStrings();
//#define TEST_MENU
@@ -212,6 +214,17 @@ void ToltecsEngine::setupSysStrings() {
// TODO: Set yes/no chars
}
+void ToltecsEngine::requestSavegame(int slotNum, Common::String &description) {
+ _saveLoadRequested = 2;
+ _saveLoadSlot = slotNum;
+ _saveLoadDescription = description;
+}
+
+void ToltecsEngine::requestLoadgame(int slotNum) {
+ _saveLoadRequested = 1;
+ _saveLoadSlot = slotNum;
+}
+
void ToltecsEngine::loadScene(uint resIndex) {
// TODO
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 9d7a767..5d0f39b 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -109,6 +109,8 @@ public:
const Common::String& getTargetName() const { return _targetName; }
void setupSysStrings();
+ void requestSavegame(int slotNum, Common::String &description);
+ void requestLoadgame(int slotNum);
void loadScene(uint resIndex);
@@ -148,6 +150,10 @@ public:
Common::String _sysStrings[kSysStrCount];
+ int _saveLoadRequested;
+ int _saveLoadSlot;
+ Common::String _saveLoadDescription;
+
uint _sceneResIndex;
int16 _sceneWidth, _sceneHeight;
Commit: 661ce95478c49c72352bd7bd8c965ceab687ef4f
https://github.com/scummvm/scummvm/commit/661ce95478c49c72352bd7bd8c965ceab687ef4f
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: - Fix regression in movie player (use drawScreen instead of updateScreen)
Changed paths:
engines/toltecs/movie.cpp
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index d5839cb..0da981b 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -115,7 +115,7 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_screen->updateShakeScreen();
_vm->_screen->_fullRefresh = true;
_vm->updateInput();
- _vm->updateScreen();
+ _vm->drawScreen();
_soundChunkFramesLeft--;
if (_soundChunkFramesLeft <= _framesPerSoundChunk) {
Commit: 8203563c6920d6bbdbbd34a85cbd8685085ce4b9
https://github.com/scummvm/scummvm/commit/8203563c6920d6bbdbbd34a85cbd8685085ce4b9
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: - New constant kMaxChannels instead of number for clarity
Changed paths:
engines/toltecs/sound.cpp
engines/toltecs/sound.h
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index d015720..fa78134 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -47,7 +47,7 @@
namespace Toltecs {
Sound::Sound(ToltecsEngine *vm) : _vm(vm) {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < kMaxChannels; i++) {
channels[i].type = kChannelTypeEmpty;
channels[i].resIndex = -1;
}
@@ -114,13 +114,13 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
// Stop all sounds
_vm->_mixer->stopAll();
_vm->_screen->keepTalkTextItemsAlive();
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < kMaxChannels; i++) {
channels[i].type = kChannelTypeEmpty;
channels[i].resIndex = -1;
}
} else if (type == -2) {
// Stop sounds with specified resIndex
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < kMaxChannels; i++) {
if (channels[i].resIndex == resIndex) {
_vm->_mixer->stopHandle(channels[i].handle);
channels[i].type = kChannelTypeEmpty;
@@ -136,7 +136,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
// Play new sound in empty channel
int freeChannel = -1;
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < kMaxChannels; i++) {
if (channels[i].type == kChannelTypeEmpty || !_vm->_mixer->isSoundHandleActive(channels[i].handle)) {
freeChannel = i;
break;
@@ -171,7 +171,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
}
void Sound::updateSpeech() {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < kMaxChannels; i++) {
if (channels[i].type == kChannelTypeSpeech && _vm->_mixer->isSoundHandleActive(channels[i].handle)) {
_vm->_screen->keepTalkTextItemsAlive();
break;
@@ -180,7 +180,7 @@ void Sound::updateSpeech() {
}
void Sound::stopSpeech() {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < kMaxChannels; i++) {
if (channels[i].type == kChannelTypeSpeech) {
_vm->_mixer->stopHandle(channels[i].handle);
_vm->_screen->keepTalkTextItemsAlive();
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
index 1f82378..244fcc3 100644
--- a/engines/toltecs/sound.h
+++ b/engines/toltecs/sound.h
@@ -61,6 +61,8 @@ struct SoundChannel {
Audio::SoundHandle handle;
};
+const int kMaxChannels = 4;
+
class Sound {
public:
Sound(ToltecsEngine *vm);
@@ -75,7 +77,7 @@ public:
protected:
ToltecsEngine *_vm;
- SoundChannel channels[4];
+ SoundChannel channels[kMaxChannels];
void internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning);
Commit: dde75d709e219f97e0b5ab103da96fe734631acb
https://github.com/scummvm/scummvm/commit/dde75d709e219f97e0b5ab103da96fe734631acb
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Fix compilation
Changed paths:
engines/toltecs/menu.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index cbb27cd..f79d70b 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -274,7 +274,7 @@ void MenuSystem::initMenu(MenuID menuID) {
addClickTextItem(kItemIdSavegame6, 0, 115 + 20 * 5, 300, 0, "SAVEGAME 6", 231, 234);
addClickTextItem(kItemIdSavegame7, 0, 115 + 20 * 6, 300, 0, "SAVEGAME 7", 231, 234);
newSlotNum = loadSavegamesList() + 1;
- _savegames.push_back(SavegameItem(newSlotNum, Common::String::printf("GAME %03d", _savegames.size() + 1)));
+ _savegames.push_back(SavegameItem(newSlotNum, Common::String::format("GAME %03d", _savegames.size() + 1)));
setSavegameCaptions();
break;
case kMenuIdVolumes:
Commit: d3811422f82180e482fc9dc3aabca48df8844119
https://github.com/scummvm/scummvm/commit/d3811422f82180e482fc9dc3aabca48df8844119
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Fixed compilation and reduced header dependencies a bit
Changed paths:
engines/toltecs/sound.h
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
index 244fcc3..f560168 100644
--- a/engines/toltecs/sound.h
+++ b/engines/toltecs/sound.h
@@ -37,7 +37,6 @@
#include "sound/audiostream.h"
#include "sound/mixer.h"
-#include "sound/audiocd.h"
#include "sound/decoders/voc.h"
#include "engines/engine.h"
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 9a0f669..ae5e17c 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -39,6 +39,7 @@
#include "engines/util.h"
#include "sound/mixer.h"
+#include "backends/audiocd/audiocd.h"
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
@@ -74,7 +75,7 @@ ToltecsEngine::ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDe
int cd_num = ConfMan.getInt("cdrom");
if (cd_num >= 0)
- _system->openCD(cd_num);
+ _system->getAudioCDManager()->openCD(cd_num);
}
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 5d0f39b..e77a1bb 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -38,7 +38,6 @@
#include "sound/audiostream.h"
#include "sound/mixer.h"
#include "sound/decoders/voc.h"
-#include "sound/audiocd.h"
#include "engines/engine.h"
Commit: c52aa31a18e993dac95f8f0cf30591ea46b2c383
https://github.com/scummvm/scummvm/commit/c52aa31a18e993dac95f8f0cf30591ea46b2c383
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Added some FIXME comments
Changed paths:
engines/toltecs/microtiles.cpp
diff --git a/engines/toltecs/microtiles.cpp b/engines/toltecs/microtiles.cpp
index 7c82505..2e789e5 100644
--- a/engines/toltecs/microtiles.cpp
+++ b/engines/toltecs/microtiles.cpp
@@ -113,7 +113,8 @@ Common::Rect * MicroTileArray::getRectangles(int *num_rects, int min_x, int min_
x0 = CLIP (x0, min_x, max_x);
y0 = CLIP (y0, min_y, max_y);
y1 = CLIP (y1, min_y, max_y);
-
+
+ // FIXME: Why is the following code in an #if block?
#if 1
start = i;
@@ -143,6 +144,8 @@ Common::Rect * MicroTileArray::getRectangles(int *num_rects, int min_x, int min_
x1 = CLIP (x1, min_x, max_x);
+ // FIXME: Why is the following code in an #if block?
+
#if 1
rects[n_rects].left = x0;
@@ -154,6 +157,8 @@ Common::Rect * MicroTileArray::getRectangles(int *num_rects, int min_x, int min_
#else
+ // FIXME: Why is this code disabled?
+
if (glom [start] != -1 && /* try to glom */
rects [glom [start]].left == x0 &&
rects [glom [start]].right == x1 &&
Commit: febda31f5043a8064d2d9a365c2997df79c062f3
https://github.com/scummvm/scummvm/commit/febda31f5043a8064d2d9a365c2997df79c062f3
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Reduced header dependencies
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/script.h
engines/toltecs/segmap.cpp
engines/toltecs/segmap.h
engines/toltecs/sound.cpp
engines/toltecs/sound.h
engines/toltecs/sprite.cpp
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 3c20600..36a98ad 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -29,9 +29,6 @@
#include "common/savefile.h"
#include "common/config-manager.h"
-#include "base/plugins.h"
-#include "base/version.h"
-
#include "sound/mixer.h"
#include "toltecs/toltecs.h"
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index 966ed3d..04bebdd 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -24,20 +24,8 @@
#ifndef TOLTECS_SCRIPT_H
#define TOLTECS_SCRIPT_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/array.h"
#include "common/func.h"
-#include "engines/engine.h"
-
namespace Toltecs {
const int kMaxScriptSlots = 50;
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 37240db..40471fe 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -21,24 +21,8 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-#include "common/stream.h"
-
-#include "graphics/primitives.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
-#include "sound/mixer.h"
-
#include "toltecs/toltecs.h"
#include "toltecs/render.h"
-#include "toltecs/resource.h"
-#include "toltecs/screen.h"
#include "toltecs/segmap.h"
namespace Toltecs {
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index 3fcf5bf..92b6b19 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -24,21 +24,6 @@
#ifndef TOLTECS_SEGMAP_H
#define TOLTECS_SEGMAP_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/array.h"
-
-#include "graphics/surface.h"
-
-#include "engines/engine.h"
-
#include "toltecs/screen.h"
namespace Toltecs {
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index fa78134..5e63ee6 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -21,26 +21,11 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
-#include "graphics/cursorman.h"
-
#include "sound/mixer.h"
#include "sound/decoders/raw.h"
#include "toltecs/toltecs.h"
-#include "toltecs/palette.h"
-#include "toltecs/render.h"
#include "toltecs/resource.h"
-#include "toltecs/screen.h"
-#include "toltecs/script.h"
#include "toltecs/segmap.h"
#include "toltecs/sound.h"
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
index f560168..2514d4f 100644
--- a/engines/toltecs/sound.h
+++ b/engines/toltecs/sound.h
@@ -24,23 +24,6 @@
#ifndef TOLTECS_SOUND_H
#define TOLTECS_SOUND_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/array.h"
-
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/decoders/voc.h"
-
-#include "engines/engine.h"
-
#include "toltecs/toltecs.h"
namespace Toltecs {
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index b6654b5..08c7ef4 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -21,26 +21,10 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
-#include "graphics/cursorman.h"
-
-#include "sound/mixer.h"
-
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
#include "toltecs/render.h"
#include "toltecs/resource.h"
-#include "toltecs/screen.h"
-#include "toltecs/script.h"
-#include "toltecs/segmap.h"
namespace Toltecs {
Commit: e9dc0550894f3fbe129f5b28ded16fa7f19e5e7c
https://github.com/scummvm/scummvm/commit/e9dc0550894f3fbe129f5b28ded16fa7f19e5e7c
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Reduced header dependencies
Changed paths:
engines/toltecs/saveload.cpp
engines/toltecs/screen.cpp
engines/toltecs/screen.h
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 3196ca4..243b804 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -21,14 +21,7 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
#include "graphics/thumbnail.h"
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 91527bd..b2979b7 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -21,26 +21,14 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
#include "graphics/cursorman.h"
-#include "sound/mixer.h"
-
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
#include "toltecs/render.h"
#include "toltecs/resource.h"
#include "toltecs/screen.h"
#include "toltecs/script.h"
-#include "toltecs/segmap.h"
namespace Toltecs {
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index b7e1491..bf49569 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -24,21 +24,8 @@
#ifndef TOLTECS_SCREEN_H
#define TOLTECS_SCREEN_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/list.h"
-#include "common/array.h"
-
#include "graphics/surface.h"
-
-#include "engines/engine.h"
+#include "toltecs/toltecs.h"
namespace Toltecs {
Commit: a9f7094a680791d4fa57f630ab1c1b5f54ed3d82
https://github.com/scummvm/scummvm/commit/a9f7094a680791d4fa57f630ab1c1b5f54ed3d82
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Reduced header dependencies
Changed paths:
engines/toltecs/render.h
engines/toltecs/resource.cpp
engines/toltecs/resource.h
engines/toltecs/saveload.cpp
diff --git a/engines/toltecs/render.h b/engines/toltecs/render.h
index ce8faeb..bb9ec29 100644
--- a/engines/toltecs/render.h
+++ b/engines/toltecs/render.h
@@ -24,23 +24,8 @@
#ifndef TOLTECS_RENDER_H
#define TOLTECS_RENDER_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/list.h"
-#include "common/array.h"
-#include "common/rect.h"
-
#include "graphics/surface.h"
-#include "engines/engine.h"
-
#include "toltecs/segmap.h"
#include "toltecs/screen.h"
#include "toltecs/microtiles.h"
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index c8cf2cc..cb79f22 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -21,16 +21,7 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
-#include "sound/mixer.h"
#include "toltecs/toltecs.h"
#include "toltecs/resource.h"
diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h
index 8164b9e..0201bd5 100644
--- a/engines/toltecs/resource.h
+++ b/engines/toltecs/resource.h
@@ -24,17 +24,9 @@
#ifndef TOLTECS_RESOURCE_H
#define TOLTECS_RESOURCE_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/array.h"
#include "engines/engine.h"
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 243b804..f2bcc1a 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -25,15 +25,11 @@
#include "graphics/thumbnail.h"
-#include "sound/mixer.h"
-
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
#include "toltecs/palette.h"
-#include "toltecs/resource.h"
#include "toltecs/script.h"
#include "toltecs/screen.h"
-#include "toltecs/segmap.h"
namespace Toltecs {
Commit: 7746fbc5437c018e450e9673f978f02b27a60480
https://github.com/scummvm/scummvm/commit/7746fbc5437c018e450e9673f978f02b27a60480
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Reduced header dependencies
Changed paths:
engines/toltecs/detection.cpp
engines/toltecs/movie.h
engines/toltecs/palette.cpp
engines/toltecs/palette.h
engines/toltecs/render.cpp
engines/toltecs/segmap.h
engines/toltecs/sound.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 1c113dd..50d605d 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -24,7 +24,9 @@
#include "base/plugins.h"
#include "engines/advancedDetector.h"
-#include "common/file.h"
+#include "common/savefile.h"
+#include "common/str-array.h"
+#include "common/system.h"
#include "toltecs/toltecs.h"
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
index 0a6a865..46c2384 100644
--- a/engines/toltecs/movie.h
+++ b/engines/toltecs/movie.h
@@ -24,18 +24,7 @@
#ifndef TOLTECS_MOVIE_H
#define TOLTECS_MOVIE_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/array.h"
-
-#include "engines/engine.h"
+#include "sound/audiostream.h"
namespace Toltecs {
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 1236d98..0b5eb65 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -21,17 +21,6 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
-#include "sound/mixer.h"
-
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h
index 59f0504..140d59b 100644
--- a/engines/toltecs/palette.h
+++ b/engines/toltecs/palette.h
@@ -24,19 +24,10 @@
#ifndef TOLTECS_PALETTE_H
#define TOLTECS_PALETTE_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/stream.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
#include "common/array.h"
+#include "common/system.h"
-#include "engines/engine.h"
+#include "toltecs/toltecs.h"
namespace Toltecs {
diff --git a/engines/toltecs/render.cpp b/engines/toltecs/render.cpp
index 642b299..b7e859a 100644
--- a/engines/toltecs/render.cpp
+++ b/engines/toltecs/render.cpp
@@ -21,14 +21,7 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
+#include "common/system.h"
#include "toltecs/toltecs.h"
#include "toltecs/render.h"
@@ -80,6 +73,7 @@ void RenderQueue::addSprite(SpriteDrawItem &sprite) {
void RenderQueue::addText(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len) {
+ // TODO: Font caching?
Font font(_vm->_res->load(fontResIndex)->data);
RenderQueueItem item;
diff --git a/engines/toltecs/segmap.h b/engines/toltecs/segmap.h
index 92b6b19..30182a6 100644
--- a/engines/toltecs/segmap.h
+++ b/engines/toltecs/segmap.h
@@ -24,6 +24,8 @@
#ifndef TOLTECS_SEGMAP_H
#define TOLTECS_SEGMAP_H
+#include "common/array.h"
+
#include "toltecs/screen.h"
namespace Toltecs {
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 5e63ee6..c3b099d 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -21,6 +21,7 @@
*
*/
+#include "sound/audiostream.h"
#include "sound/mixer.h"
#include "sound/decoders/raw.h"
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index e77a1bb..24e7f16 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -26,21 +26,15 @@
#include "common/scummsys.h"
#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/random.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
#include "common/events.h"
+#include "common/file.h"
#include "common/keyboard.h"
-
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/decoders/voc.h"
+#include "common/random.h"
#include "engines/engine.h"
+#include "graphics/surface.h"
+
namespace Toltecs {
struct ToltecsGameDescription;
Commit: 26a7bf4eb5616dc4d5d5556050b0eb21ded2e934
https://github.com/scummvm/scummvm/commit/26a7bf4eb5616dc4d5d5556050b0eb21ded2e934
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Reduced header dependencies
Changed paths:
engines/toltecs/animation.cpp
engines/toltecs/animation.h
engines/toltecs/menu.cpp
engines/toltecs/menu.h
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
index 3175bf6..8c0337d 100644
--- a/engines/toltecs/animation.cpp
+++ b/engines/toltecs/animation.cpp
@@ -21,17 +21,6 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
-#include "sound/mixer.h"
-
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
#include "toltecs/palette.h"
diff --git a/engines/toltecs/animation.h b/engines/toltecs/animation.h
index 8b1ac7b..22576d7 100644
--- a/engines/toltecs/animation.h
+++ b/engines/toltecs/animation.h
@@ -24,19 +24,6 @@
#ifndef TOLTECS_ANIMATION_H
#define TOLTECS_ANIMATION_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/array.h"
-
-#include "engines/engine.h"
-
#include "toltecs/toltecs.h"
#include "toltecs/resource.h"
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index f79d70b..ac08d88 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -21,23 +21,13 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
-#include "sound/mixer.h"
#include "toltecs/toltecs.h"
#include "toltecs/menu.h"
#include "toltecs/palette.h"
#include "toltecs/render.h"
#include "toltecs/resource.h"
-#include "toltecs/screen.h"
namespace Toltecs {
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index 12f48ca..d4cbddc 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -24,20 +24,8 @@
#ifndef TOLTECS_MENU_H
#define TOLTECS_MENU_H
-#include "common/scummsys.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/hash-str.h"
-#include "common/events.h"
-#include "common/keyboard.h"
#include "common/array.h"
-#include "common/rect.h"
-#include "common/str.h"
-
-#include "engines/engine.h"
+#include "common/str-array.h"
namespace Toltecs {
Commit: e1f795fb6d5fc3b8e7b8f9130561bf4d2afe4b2d
https://github.com/scummvm/scummvm/commit/e1f795fb6d5fc3b8e7b8f9130561bf4d2afe4b2d
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Added ScummVM headers
Changed paths:
engines/toltecs/microtiles.cpp
engines/toltecs/microtiles.h
diff --git a/engines/toltecs/microtiles.cpp b/engines/toltecs/microtiles.cpp
index 2e789e5..7414eba 100644
--- a/engines/toltecs/microtiles.cpp
+++ b/engines/toltecs/microtiles.cpp
@@ -1,3 +1,26 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
#include "toltecs/microtiles.h"
namespace Toltecs {
diff --git a/engines/toltecs/microtiles.h b/engines/toltecs/microtiles.h
index 2135add..5393362 100644
--- a/engines/toltecs/microtiles.h
+++ b/engines/toltecs/microtiles.h
@@ -1,3 +1,26 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ */
+
#ifndef TOLTECS_MICROTILES_H
#define TOLTECS_MICROTILES_H
Commit: 4cc5934d840fb495ff7543c01ff053044f3fa64f
https://github.com/scummvm/scummvm/commit/4cc5934d840fb495ff7543c01ff053044f3fa64f
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Reduced header dependencies
Changed paths:
engines/toltecs/movie.cpp
engines/toltecs/movie.h
engines/toltecs/script.cpp
engines/toltecs/sound.h
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 0da981b..ba6771b 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -21,15 +21,6 @@
*
*/
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "base/plugins.h"
-#include "base/version.h"
-
#include "sound/mixer.h"
#include "sound/decoders/raw.h"
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
index 46c2384..38eafb1 100644
--- a/engines/toltecs/movie.h
+++ b/engines/toltecs/movie.h
@@ -25,6 +25,7 @@
#define TOLTECS_MOVIE_H
#include "sound/audiostream.h"
+#include "sound/mixer.h" // for Audio::SoundHandle
namespace Toltecs {
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 36a98ad..6ec2856 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -23,14 +23,6 @@
// TODO: Clean up game variable handling and move it to ToltecsEngine
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
-#include "common/config-manager.h"
-
-#include "sound/mixer.h"
-
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
#include "toltecs/menu.h"
@@ -38,7 +30,6 @@
#include "toltecs/palette.h"
#include "toltecs/resource.h"
#include "toltecs/script.h"
-#include "toltecs/screen.h"
#include "toltecs/segmap.h"
#include "toltecs/sound.h"
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
index 2514d4f..381c7d3 100644
--- a/engines/toltecs/sound.h
+++ b/engines/toltecs/sound.h
@@ -24,6 +24,8 @@
#ifndef TOLTECS_SOUND_H
#define TOLTECS_SOUND_H
+#include "sound/mixer.h" // for Audio::SoundHandle
+
#include "toltecs/toltecs.h"
namespace Toltecs {
Commit: e1abe47fbeeb277723a5a044c28a4acf990fac95
https://github.com/scummvm/scummvm/commit/e1abe47fbeeb277723a5a044c28a4acf990fac95
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Reduced header dependencies and removed a TODO
Changed paths:
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index ae5e17c..2092d03 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -21,25 +21,18 @@
*
*/
-#include "common/events.h"
#include "common/EventRecorder.h"
-#include "common/keyboard.h"
-#include "common/file.h"
-#include "common/savefile.h"
#include "common/config-manager.h"
#include "common/str.h"
#include "base/plugins.h"
#include "base/version.h"
-#include "graphics/surface.h"
#include "graphics/cursorman.h"
-#include "graphics/primitives.h"
#include "engines/util.h"
#include "sound/mixer.h"
-#include "backends/audiocd/audiocd.h"
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
@@ -72,11 +65,6 @@ ToltecsEngine::ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDe
_rnd = new Common::RandomSource();
g_eventRec.registerRandomSource(*_rnd, "toltecs");
-
- int cd_num = ConfMan.getInt("cdrom");
- if (cd_num >= 0)
- _system->getAudioCDManager()->openCD(cd_num);
-
}
ToltecsEngine::~ToltecsEngine() {
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 24e7f16..38a8952 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -51,8 +51,6 @@ class Screen;
class SegmentMap;
class Sound;
-// TODO/FIXME: The includes of the Toltecs engine need serious clean-up
-
enum SysString {
kStrLoadingPleaseWait,
kStrWhatCanIDoForYou,
Commit: 75842b031f69c5d3fb2d7962379642294d7b7373
https://github.com/scummvm/scummvm/commit/75842b031f69c5d3fb2d7962379642294d7b7373
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Added comments on main game loop, and added a FIXME
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index ac08d88..e8ae49d 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -410,6 +410,7 @@ void MenuSystem::restoreRect(int x, int y, int w, int h) {
}
void MenuSystem::shadeRect(int x, int y, int w, int h, byte color1, byte color2) {
+ // FIXME: Why is the following block disabled?
#if 0
byte *src = (byte*)_background->getBasePtr(x, y);
for (int xc = 0; xc < w; xc++) {
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 2092d03..a348456 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -165,7 +165,7 @@ Common::Error ToltecsEngine::run() {
return Common::kNoError;
#endif
-#if 1
+ // Start main game loop
_script->loadScript(0, 0);
_script->setMainScript(0);
if (ConfMan.hasKey("save_slot")) {
@@ -175,7 +175,6 @@ Common::Error ToltecsEngine::run() {
}
}
_script->runScript();
-#endif
delete _arc;
delete _res;
Commit: 3f78e1c8d90ef9d1726ffeb1e80c16445eefd777
https://github.com/scummvm/scummvm/commit/3f78e1c8d90ef9d1726ffeb1e80c16445eefd777
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Rewrote ArchiveReader::dump() to use Common::DumpFile()
Changed paths:
engines/toltecs/resource.cpp
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index cb79f22..cbd0bcb 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -77,11 +77,10 @@ void ArchiveReader::dump(uint resIndex, const char *prefix) {
read(data, resourceSize);
closeResource();
-#if 0
- FILE *o = fopen(fn, "wb");
- fwrite(data, resourceSize, 1, o);
- fclose(o);
-#endif
+ Common::DumpFile o;
+ o.open(fn);
+ o.write(data, resourceSize);
+ o.close();
delete[] data;
}
Commit: 581f0ba8b57458924a83d20eed55e577574cb1ac
https://github.com/scummvm/scummvm/commit/581f0ba8b57458924a83d20eed55e577574cb1ac
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Use CursorMan instead of OSystem for showMouse
Changed paths:
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 6ec2856..fa5eb4d 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -23,6 +23,8 @@
// TODO: Clean up game variable handling and move it to ToltecsEngine
+#include "graphics/cursorman.h"
+
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
#include "toltecs/menu.h"
@@ -608,7 +610,7 @@ void ScriptInterpreter::setGameVar(uint variable, int16 value) {
switch (variable) {
case 0:
_vm->_mouseDisabled = value;
- _vm->_system->showMouse(value == 0);
+ CursorMan.showMouse(value == 0);
break;
case 3:
_vm->_mouseButton = value;
@@ -1062,7 +1064,7 @@ void ScriptInterpreter::sfRunOptionsScreen() {
_vm->_palette->setDeltaPalette(_vm->_palette->getMainPalette(), 7, 0, 31, 224);
_vm->_screen->finishTalkTextItems();
_vm->_screen->clearSprites();
- _vm->_system->showMouse(true);
+ CursorMan.showMouse(true);
_vm->_menuSystem->run();
_vm->_keyState.reset();
_switchLocalDataNear = true;
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index a348456..12c7b53 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -141,7 +141,7 @@ Common::Error ToltecsEngine::run() {
syncSoundSettings();
- _system->showMouse(true);
+ CursorMan.showMouse(true);
setupSysStrings();
Commit: 02514db64fcae15c12f8d59662ae9ed43e60f887
https://github.com/scummvm/scummvm/commit/02514db64fcae15c12f8d59662ae9ed43e60f887
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Sync with the latest changes in trunk
Changed paths:
engines/toltecs/palette.cpp
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 0b5eb65..6fc6029 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -46,13 +46,13 @@ void Palette::setFullPalette(byte *palette) {
colors[i * 4 + 2] = palette[i * 3 + 2] << 2;
colors[i * 4 + 3] = 255;
}
- _vm->_system->setPalette((const byte *)colors, 0, 256);
+ _vm->_system->getPaletteManager()->setPalette((const byte *)colors, 0, 256);
_vm->_system->updateScreen();
}
void Palette::getFullPalette(byte *palette) {
byte colors[1024];
- _vm->_system->grabPalette(colors, 0, 256);
+ _vm->_system->getPaletteManager()->grabPalette(colors, 0, 256);
for (int i = 0; i < 256; i++) {
palette[i * 3 + 0] = colors[i * 4 + 0] >> 2;
palette[i * 3 + 1] = colors[i * 4 + 1] >> 2;
@@ -70,7 +70,7 @@ void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 c
count++;
- _vm->_system->grabPalette(colors, 0, 256);
+ _vm->_system->getPaletteManager()->grabPalette(colors, 0, 256);
deltaValue *= -1;
@@ -86,7 +86,7 @@ void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 c
debug(0, "startIndex = %d; colorCount = %d", startIndex, colorCount);
- _vm->_system->setPalette((const byte *)colors, 0, 256);
+ _vm->_system->getPaletteManager()->setPalette((const byte *)colors, 0, 256);
}
Commit: e4005ae92769f345f8fe83e4c6e7f90840ca1deb
https://github.com/scummvm/scummvm/commit/e4005ae92769f345f8fe83e4c6e7f90840ca1deb
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Fix compilation after sound->audio directory rename.
Changed paths:
engines/toltecs/movie.cpp
engines/toltecs/movie.h
engines/toltecs/sound.cpp
engines/toltecs/sound.h
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index ba6771b..36ba5c7 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -21,8 +21,8 @@
*
*/
-#include "sound/mixer.h"
-#include "sound/decoders/raw.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
#include "toltecs/toltecs.h"
#include "toltecs/movie.h"
diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h
index 38eafb1..aecfac2 100644
--- a/engines/toltecs/movie.h
+++ b/engines/toltecs/movie.h
@@ -24,8 +24,8 @@
#ifndef TOLTECS_MOVIE_H
#define TOLTECS_MOVIE_H
-#include "sound/audiostream.h"
-#include "sound/mixer.h" // for Audio::SoundHandle
+#include "audio/audiostream.h"
+#include "audio/mixer.h" // for Audio::SoundHandle
namespace Toltecs {
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index c3b099d..00b4a45 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -21,9 +21,9 @@
*
*/
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "sound/decoders/raw.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
#include "toltecs/toltecs.h"
#include "toltecs/resource.h"
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
index 381c7d3..1414631 100644
--- a/engines/toltecs/sound.h
+++ b/engines/toltecs/sound.h
@@ -24,7 +24,7 @@
#ifndef TOLTECS_SOUND_H
#define TOLTECS_SOUND_H
-#include "sound/mixer.h" // for Audio::SoundHandle
+#include "audio/mixer.h" // for Audio::SoundHandle
#include "toltecs/toltecs.h"
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 12c7b53..f1d6040 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -32,7 +32,7 @@
#include "engines/util.h"
-#include "sound/mixer.h"
+#include "audio/mixer.h"
#include "toltecs/toltecs.h"
#include "toltecs/animation.h"
Commit: e1fefefff2f2adc26cff5cc8f0c62cb210b31415
https://github.com/scummvm/scummvm/commit/e1fefefff2f2adc26cff5cc8f0c62cb210b31415
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Updated For OSystem Palette RGBA->RGB Change.
Changed paths:
engines/toltecs/palette.cpp
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 6fc6029..6155858 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -39,30 +39,28 @@ Palette::~Palette() {
}
void Palette::setFullPalette(byte *palette) {
- byte colors[1024];
+ byte colors[768];
for (int i = 0; i < 256; i++) {
- colors[i * 4 + 0] = palette[i * 3 + 0] << 2;
- colors[i * 4 + 1] = palette[i * 3 + 1] << 2;
- colors[i * 4 + 2] = palette[i * 3 + 2] << 2;
- colors[i * 4 + 3] = 255;
+ colors[i * 3 + 0] = palette[i * 3 + 0] << 2;
+ colors[i * 3 + 1] = palette[i * 3 + 1] << 2;
+ colors[i * 3 + 2] = palette[i * 3 + 2] << 2;
}
_vm->_system->getPaletteManager()->setPalette((const byte *)colors, 0, 256);
_vm->_system->updateScreen();
}
void Palette::getFullPalette(byte *palette) {
- byte colors[1024];
+ byte colors[768];
_vm->_system->getPaletteManager()->grabPalette(colors, 0, 256);
for (int i = 0; i < 256; i++) {
- palette[i * 3 + 0] = colors[i * 4 + 0] >> 2;
- palette[i * 3 + 1] = colors[i * 4 + 1] >> 2;
- palette[i * 3 + 2] = colors[i * 4 + 2] >> 2;
+ palette[i * 3 + 0] = colors[i * 3 + 0] >> 2;
+ palette[i * 3 + 1] = colors[i * 3 + 1] >> 2;
+ palette[i * 3 + 2] = colors[i * 3 + 2] >> 2;
}
}
void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 count, int16 startIndex) {
-
- byte colors[1024];
+ byte colors[768];
byte *palPtr = palette + startIndex * 3;
int16 index = startIndex, colorCount = count;
@@ -76,18 +74,17 @@ void Palette::setDeltaPalette(byte *palette, byte mask, char deltaValue, int16 c
while (count--) {
rgb = *palPtr++;
- if (mask & 1) colors[index * 4 + 0] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ if (mask & 1) colors[index * 3 + 0] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
rgb = *palPtr++;
- if (mask & 2) colors[index * 4 + 1] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ if (mask & 2) colors[index * 3 + 1] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
rgb = *palPtr++;
- if (mask & 4) colors[index * 4 + 2] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
- index++;
+ if (mask & 4) colors[index * 3 + 2] = CLIP<int>(rgb + deltaValue, 0, 63) << 2;
+ index++;
}
debug(0, "startIndex = %d; colorCount = %d", startIndex, colorCount);
_vm->_system->getPaletteManager()->setPalette((const byte *)colors, 0, 256);
-
}
void Palette::loadAddPalette(uint resIndex, byte startIndex) {
Commit: acd4d4098f880aa639895f3cfecbac0764999112
https://github.com/scummvm/scummvm/commit/acd4d4098f880aa639895f3cfecbac0764999112
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Fix bugs
- Save scene parameters before playing a movie and restore them afterwards (fixes crash)
- Fix text disappearing too fast
- Implement script function sfGetCameraChanged
- Replace nop script functions with stubs which print debug info when called
- Some cleanup, remove obsolete TODOs
Changed paths:
engines/toltecs/animation.cpp
engines/toltecs/menu.h
engines/toltecs/movie.cpp
engines/toltecs/render.cpp
engines/toltecs/resource.cpp
engines/toltecs/saveload.cpp
engines/toltecs/screen.cpp
engines/toltecs/script.cpp
engines/toltecs/script.h
engines/toltecs/segmap.cpp
engines/toltecs/sound.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/animation.cpp b/engines/toltecs/animation.cpp
index 8c0337d..eef9cef 100644
--- a/engines/toltecs/animation.cpp
+++ b/engines/toltecs/animation.cpp
@@ -147,7 +147,6 @@ void AnimationPlayer::saveState(Common::WriteStream *out) {
}
void AnimationPlayer::loadState(Common::ReadStream *in) {
-
_resIndex = in->readUint16LE();
_width = in->readUint16LE();
_height = in->readUint16LE();
@@ -160,7 +159,6 @@ void AnimationPlayer::loadState(Common::ReadStream *in) {
_firstCurFrameSize = in->readUint32LE();
_firstNextFrameSize = in->readUint32LE();
_firstNextFrameOffset = in->readUint32LE();
-
}
} // End of namespace Toltecs
diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h
index d4cbddc..3e2c2da 100644
--- a/engines/toltecs/menu.h
+++ b/engines/toltecs/menu.h
@@ -94,7 +94,6 @@ protected:
struct Item {
Common::Rect rect;
ItemID id;
- //const byte *caption;
Common::String caption;
byte defaultColor, activeColor;
int x, y, w;
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index 36ba5c7..c396d6d 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -41,7 +41,12 @@ MoviePlayer::~MoviePlayer() {
void MoviePlayer::playMovie(uint resIndex) {
- uint32 subtitleSlot;
+ const uint32 subtitleSlot = kMaxScriptSlots - 1;
+ int16 savedSceneWidth = _vm->_sceneWidth;
+ int16 savedSceneHeight = _vm->_sceneHeight;
+ int16 savedCameraHeight = _vm->_cameraHeight;
+ int16 savedCameraX = _vm->_cameraX;
+ int16 savedCameraY = _vm->_cameraY;
byte moviePalette[768];
_vm->_isSaveAllowed = false;
@@ -53,8 +58,6 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_arc->openResource(resIndex);
- subtitleSlot = kMaxScriptSlots - 1;
-
_frameCount = _vm->_arc->readUint32LE();
_chunkCount = _vm->_arc->readUint32LE();
@@ -170,6 +173,12 @@ void MoviePlayer::playMovie(uint resIndex) {
debug(0, "playMovie() done");
+ _vm->_sceneWidth = savedSceneWidth;
+ _vm->_sceneHeight = savedSceneHeight;
+ _vm->_cameraHeight = savedCameraHeight;
+ _vm->_cameraX = savedCameraX;
+ _vm->_cameraY = savedCameraY;
+
_vm->_isSaveAllowed = true;
}
@@ -187,7 +196,7 @@ void MoviePlayer::fetchAudioChunks() {
byte chunkType = _vm->_arc->readByte();
uint32 chunkSize = _vm->_arc->readUint32LE();
if (chunkType == 4) {
- byte *chunkBuffer = new byte[chunkSize];
+ byte *chunkBuffer = (byte*)malloc(chunkSize);
_vm->_arc->read(chunkBuffer, chunkSize);
_audioStream->queueBuffer(chunkBuffer, chunkSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
chunkBuffer = NULL;
diff --git a/engines/toltecs/render.cpp b/engines/toltecs/render.cpp
index b7e859a..c6dbe93 100644
--- a/engines/toltecs/render.cpp
+++ b/engines/toltecs/render.cpp
@@ -73,7 +73,6 @@ void RenderQueue::addSprite(SpriteDrawItem &sprite) {
void RenderQueue::addText(int16 x, int16 y, byte color, uint fontResIndex, byte *text, int len) {
- // TODO: Font caching?
Font font(_vm->_res->load(fontResIndex)->data);
RenderQueueItem item;
@@ -248,8 +247,6 @@ RenderQueueItem *RenderQueue::findItemInQueue(RenderQueueArray *queue, const Ren
bool RenderQueue::hasItemChanged(const RenderQueueItem &item1, const RenderQueueItem &item2) {
- // TODO: Clean up.
-
if (item1.type != item1.type)
return true;
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index cbd0bcb..ddc1a6e 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -57,7 +57,6 @@ uint32 ArchiveReader::openResource(uint resIndex) {
void ArchiveReader::closeResource() {
}
-
uint32 ArchiveReader::getResourceSize(uint resIndex) {
return _offsets[resIndex + 1] - _offsets[resIndex];
}
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index f2bcc1a..aa04537 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -34,7 +34,6 @@
namespace Toltecs {
/* TODO:
- - Saveload is working so far but only one slot is supported until the game menu is implemented
- Save with F7; Load with F9
- Saving during an animation (AnimationPlayer) is not working correctly yet
- Maybe switch to SCUMM/Tinsel serialization approach?
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index b2979b7..4eda8f6 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -125,7 +125,7 @@ void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
int16 height = imageData[3];
int16 workWidth = width, workHeight = height;
imageData += headerSize;
-
+
byte *dest = _frontScreen + x + (y + _vm->_cameraHeight) * 640;
//debug(0, "Screen::drawGuiImage() x = %d; y = %d; w = %d; h = %d; resIndex = %d", x, y, width, height, resIndex);
@@ -444,9 +444,8 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
}
int16 textDurationMultiplier = item->duration + 8;
- // TODO: Check sound/text flags
- if (*textData == 0xFE) {
- //textDurationMultiplier += 100;
+ if (_vm->_doSpeech && *textData == 0xFE) {
+ textDurationMultiplier += 100;
}
item->duration = 4 * textDurationMultiplier * durationModifier;
@@ -478,7 +477,8 @@ void Screen::addTalkTextItemsToRenderQueue() {
if (item->fontNum == -1 || item->duration == 0)
continue;
- item->duration -= _vm->_counter01;
+ //item->duration -= _vm->_counter01;
+ item->duration--;
if (item->duration < 0)
item->duration = 0;
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index fa5eb4d..c128d5a 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -66,71 +66,85 @@ typedef Common::Functor0Mem<void, ScriptInterpreter> ScriptFunctionF;
_scriptFuncNames.push_back(#x);
void ScriptInterpreter::setupScriptFunctions() {
+ // 0
RegisterScriptFunction(sfNop);
RegisterScriptFunction(sfNop);
RegisterScriptFunction(sfGetGameVar);
RegisterScriptFunction(sfSetGameVar);
RegisterScriptFunction(sfUpdateScreen);
+ // 5
RegisterScriptFunction(sfGetRandomNumber);
RegisterScriptFunction(sfDrawGuiTextMulti);
RegisterScriptFunction(sfUpdateVerbLine);
RegisterScriptFunction(sfSetFontColor);
RegisterScriptFunction(sfGetTalkTextDuration);
+ // 10
RegisterScriptFunction(sfTalk);
RegisterScriptFunction(sfFindPaletteFragment);
RegisterScriptFunction(sfClearPaletteFragments);
RegisterScriptFunction(sfAddPaletteFragment);
RegisterScriptFunction(sfSetDeltaAnimPalette);
- RegisterScriptFunction(sfNop); // TODO
+ // 15
+ RegisterScriptFunction(sfSetUnkPaletteEffect);
RegisterScriptFunction(sfBuildColorTransTable);
RegisterScriptFunction(sfSetDeltaMainPalette);
RegisterScriptFunction(sfLoadScript);
RegisterScriptFunction(sfRegisterFont);
+ // 20
RegisterScriptFunction(sfLoadAddPalette);
RegisterScriptFunction(sfLoadScene);
RegisterScriptFunction(sfSetGuiHeight);
RegisterScriptFunction(sfFindMouseInRectIndex1);
RegisterScriptFunction(sfFindMouseInRectIndex2);
+ // 25
RegisterScriptFunction(sfDrawGuiImage);
RegisterScriptFunction(sfAddAnimatedSpriteNoLoop);
RegisterScriptFunction(sfAddAnimatedSprite);
RegisterScriptFunction(sfAddStaticSprite);
RegisterScriptFunction(sfAddAnimatedSpriteScaled);
+ // 30
RegisterScriptFunction(sfFindPath);
RegisterScriptFunction(sfWalk);
RegisterScriptFunction(sfScrollCameraUp);
RegisterScriptFunction(sfScrollCameraDown);
RegisterScriptFunction(sfScrollCameraLeft);
+ // 35
RegisterScriptFunction(sfScrollCameraRight);
RegisterScriptFunction(sfScrollCameraUpEx);
RegisterScriptFunction(sfScrollCameraDownEx);
RegisterScriptFunction(sfScrollCameraLeftEx);
RegisterScriptFunction(sfScrollCameraRightEx);
+ // 40
RegisterScriptFunction(sfSetCamera);
- RegisterScriptFunction(sfNop); // TODO
+ RegisterScriptFunction(sfGetCameraChanged);
RegisterScriptFunction(sfGetRgbModifiertAtPoint);
RegisterScriptFunction(sfStartAnim);
RegisterScriptFunction(sfAnimNextFrame);
+ // 45
RegisterScriptFunction(sfNop);
RegisterScriptFunction(sfGetAnimFrameNumber);
RegisterScriptFunction(sfGetAnimStatus);
RegisterScriptFunction(sfStartShakeScreen);
RegisterScriptFunction(sfStopShakeScreen);
+ // 50
RegisterScriptFunction(sfStartSequence);
RegisterScriptFunction(sfEndSequence);
RegisterScriptFunction(sfSetSequenceVolume);
RegisterScriptFunction(sfPlayPositionalSound);
RegisterScriptFunction(sfPlaySound2);
+ // 55
RegisterScriptFunction(sfClearScreen);
RegisterScriptFunction(sfNop);
RegisterScriptFunction(sfHandleInput);
RegisterScriptFunction(sfRunOptionsScreen);
RegisterScriptFunction(sfPrecacheSprites);
+ // 60
RegisterScriptFunction(sfPrecacheSounds1);
RegisterScriptFunction(sfDeletePrecachedFiles);
RegisterScriptFunction(sfPrecacheSounds2);
RegisterScriptFunction(sfRestoreStackPtr);
RegisterScriptFunction(sfSaveStackPtr);
+ // 65
RegisterScriptFunction(sfPlayMovie);
RegisterScriptFunction(sfNop);
@@ -849,6 +863,11 @@ void ScriptInterpreter::sfSetDeltaAnimPalette() {
_vm->_palette->setDeltaPalette(_vm->_palette->getAnimPalette(), arg8(6), (char)arg8(5), arg8(4), arg8(3));
}
+void ScriptInterpreter::sfSetUnkPaletteEffect() {
+ // TODO
+ debug("ScriptInterpreter::sfSetUnkPaletteEffect");
+}
+
void ScriptInterpreter::sfBuildColorTransTable() {
_vm->_palette->buildColorTransTable(arg8(4), (char)arg8(3), arg8(5));
}
@@ -977,6 +996,10 @@ void ScriptInterpreter::sfSetCamera() {
_vm->setCamera(arg16(5), arg16(3));
}
+void ScriptInterpreter::sfGetCameraChanged() {
+ localWrite16(arg16(3), _vm->getCameraChanged() ? 1 : 0);
+}
+
void ScriptInterpreter::sfGetRgbModifiertAtPoint() {
byte *rgb = getSlotData(arg16(11)) + arg16(9);
_vm->_segmap->getRgbModifiertAtPoint(arg16(5), arg16(3), arg16(7), rgb[0], rgb[1], rgb[2]);
@@ -1012,15 +1035,21 @@ void ScriptInterpreter::sfStopShakeScreen() {
void ScriptInterpreter::sfStartSequence() {
// TODO
- //_vm->_arc->dump(arg16(3));
+ // DEBUG: Dump music so we know what's in there
+ int16 sequenceResIndex = arg16(3);
+ debug("ScriptInterpreter::sfStartSequence(%d)", sequenceResIndex);
+ if (sequenceResIndex >= 0)
+ _vm->_arc->dump(sequenceResIndex, "music");
}
void ScriptInterpreter::sfEndSequence() {
// TODO
+ debug("ScriptInterpreter::sfEndSequence");
}
void ScriptInterpreter::sfSetSequenceVolume() {
// TODO
+ //debug("ScriptInterpreter::sfSetSequenceVolume");
}
void ScriptInterpreter::sfPlayPositionalSound() {
@@ -1033,6 +1062,7 @@ void ScriptInterpreter::sfPlaySound2() {
void ScriptInterpreter::sfClearScreen() {
// TODO
+ debug("ScriptInterpreter::sfClearScreen");
}
void ScriptInterpreter::sfHandleInput() {
diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h
index 04bebdd..1a5a9c9 100644
--- a/engines/toltecs/script.h
+++ b/engines/toltecs/script.h
@@ -126,6 +126,7 @@ protected:
void sfClearPaletteFragments();
void sfAddPaletteFragment();
void sfSetDeltaAnimPalette();
+ void sfSetUnkPaletteEffect();
void sfBuildColorTransTable();
void sfSetDeltaMainPalette();
void sfLoadScript();
@@ -151,6 +152,7 @@ protected:
void sfScrollCameraLeftEx();
void sfScrollCameraRightEx();
void sfSetCamera();
+ void sfGetCameraChanged();
void sfGetRgbModifiertAtPoint();
void sfStartAnim();
void sfAnimNextFrame();
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 40471fe..6fbc04a 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -36,8 +36,6 @@ SegmentMap::~SegmentMap() {
void SegmentMap::load(byte *source) {
- // TODO: Use MemoryReadStream
-
freeSegmapMaskRectSurfaces();
_maskRects.clear();
_pathRects.clear();
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 00b4a45..3bebd81 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -51,7 +51,7 @@ void Sound::playSound(int16 resIndex, int16 type, int16 volume) {
// TODO: Use the right volumes
- debug("playSound(%d, %d, %d)", resIndex, type, volume);
+ debug(0, "playSound(%d, %d, %d)", resIndex, type, volume);
if (volume == -1 || type == -2) {
if (type == kChannelTypeBackground) {
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index f1d6040..3fa7f00 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -214,7 +214,6 @@ void ToltecsEngine::requestLoadgame(int slotNum) {
}
void ToltecsEngine::loadScene(uint resIndex) {
- // TODO
Resource *sceneResource = _res->load(resIndex);
byte *scene = sceneResource->data;
@@ -431,6 +430,10 @@ void ToltecsEngine::setCamera(int16 x, int16 y) {
}
+bool ToltecsEngine::getCameraChanged() {
+ return _cameraX != _newCameraX || _cameraY != _newCameraY;
+}
+
void ToltecsEngine::scrollCameraUp(int16 delta) {
if (_newCameraY > 0) {
if (_newCameraY < delta)
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 38a8952..2aa3585 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -112,6 +112,7 @@ public:
void setGuiHeight(int16 guiHeight);
void setCamera(int16 x, int16 y);
+ bool getCameraChanged();
void scrollCameraUp(int16 delta);
void scrollCameraDown(int16 delta);
void scrollCameraLeft(int16 delta);
Commit: a3007d6e2a5ec810b26e091349cf6aaac197f7a7
https://github.com/scummvm/scummvm/commit/a3007d6e2a5ec810b26e091349cf6aaac197f7a7
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Fix Compilation After Base Code Header Changes.
Changed paths:
engines/toltecs/palette.cpp
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp
index 6155858..8857abc 100644
--- a/engines/toltecs/palette.cpp
+++ b/engines/toltecs/palette.cpp
@@ -21,6 +21,8 @@
*
*/
+#include "graphics/palette.h"
+
#include "toltecs/toltecs.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index c128d5a..53af5f9 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -23,6 +23,8 @@
// TODO: Clean up game variable handling and move it to ToltecsEngine
+#include "common/error.h"
+
#include "graphics/cursorman.h"
#include "toltecs/toltecs.h"
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 3fa7f00..1e8a8ec 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -24,6 +24,8 @@
#include "common/EventRecorder.h"
#include "common/config-manager.h"
#include "common/str.h"
+#include "common/error.h"
+#include "common/textconsole.h"
#include "base/plugins.h"
#include "base/version.h"
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 2aa3585..ce87d19 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -30,6 +30,7 @@
#include "common/file.h"
#include "common/keyboard.h"
#include "common/random.h"
+#include "common/textconsole.h"
#include "engines/engine.h"
Commit: 9f3cc261c2e833097d7dca196502c004593a38ab
https://github.com/scummvm/scummvm/commit/9f3cc261c2e833097d7dca196502c004593a38ab
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Fix Compilation After Graphics::Surface PixelFormat changes.
Changed paths:
engines/toltecs/menu.cpp
engines/toltecs/segmap.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index e8ae49d..074e27c 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -42,7 +42,7 @@ int MenuSystem::run() {
debug("MenuSystem::run()");
_background = new Graphics::Surface();
- _background->create(640, 400, 1);
+ _background->create(640, 400, Graphics::PixelFormat::createFormatCLUT8());
_currMenuID = kMenuIdNone;
_newMenuID = kMenuIdMain;
diff --git a/engines/toltecs/segmap.cpp b/engines/toltecs/segmap.cpp
index 6fbc04a..75b0c63 100644
--- a/engines/toltecs/segmap.cpp
+++ b/engines/toltecs/segmap.cpp
@@ -370,7 +370,7 @@ void SegmentMap::getRgbModifiertAtPoint(int16 x, int16 y, int16 id, byte &r, byt
void SegmentMap::loadSegmapMaskRectSurface(byte *maskData, SegmapMaskRect &maskRect) {
maskRect.surface = new Graphics::Surface();
- maskRect.surface->create(maskRect.width, maskRect.height, 1);
+ maskRect.surface->create(maskRect.width, maskRect.height, Graphics::PixelFormat::createFormatCLUT8());
byte *backScreen = _vm->_screen->_backScreen + maskRect.x + (maskRect.y * _vm->_sceneWidth);
byte *dest = (byte*)maskRect.surface->getBasePtr(0, 0);
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 1e8a8ec..4f9fbae 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -303,7 +303,7 @@ void ToltecsEngine::drawScreen() {
_screen->_renderQueue->update();
- //printf("_guiHeight = %d\n", _guiHeight); fflush(stdout);
+ //debug("_guiHeight = %d\n", _guiHeight);
if (_screen->_guiRefresh && _guiHeight > 0 && _cameraHeight > 0) {
// Update the GUI when needed and it's visible
Commit: ae4437aea4901ea983cd4350fd9fe244c9460e4a
https://github.com/scummvm/scummvm/commit/ae4437aea4901ea983cd4350fd9fe244c9460e4a
Author: Benjamin Haisch (john_doe at techie.com)
Date: 2011-11-20T13:43:10-08:00
Commit Message:
TOLTECS: Fix compilation
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 4f9fbae..41d626a 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -65,8 +65,7 @@ ToltecsEngine::ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDe
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
- _rnd = new Common::RandomSource();
- g_eventRec.registerRandomSource(*_rnd, "toltecs");
+ _rnd = new Common::RandomSource("toltecs");
}
ToltecsEngine::~ToltecsEngine() {
Commit: ddaf38bdcda6ece923c920d5cc052064b0b0cff6
https://github.com/scummvm/scummvm/commit/ddaf38bdcda6ece923c920d5cc052064b0b0cff6
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Fix Compilation After Common::RandomSource Changes in Latest master.
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 41d626a..180da78 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -21,8 +21,9 @@
*
*/
-#include "common/EventRecorder.h"
#include "common/config-manager.h"
+#include "common/events.h"
+#include "common/random.h"
#include "common/str.h"
#include "common/error.h"
#include "common/textconsole.h"
Commit: 8a34de2c45f6ecf0fbca4c8cb34556ee303aa4fb
https://github.com/scummvm/scummvm/commit/8a34de2c45f6ecf0fbca4c8cb34556ee303aa4fb
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Replace snprintf() usage with Common::String::format()
Safer and less portability issues.
Changed paths:
engines/toltecs/resource.cpp
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index ddc1a6e..62dbca3 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -65,12 +65,12 @@ void ArchiveReader::dump(uint resIndex, const char *prefix) {
int32 resourceSize = getResourceSize(resIndex);
byte *data = new byte[resourceSize];
- char fn[256];
+ Common::String fn;
if (prefix)
- snprintf(fn, 256, "%s_%04X.0", prefix, resIndex);
+ fn = Common::String::format("%s_%04X.0", prefix, resIndex);
else
- snprintf(fn, 256, "%04X.0", resIndex);
+ fn = Common::String::format("%04X.0", resIndex);
openResource(resIndex);
read(data, resourceSize);
Commit: 3967da03efe714abe1940c8a0c74b20918fa0fd5
https://github.com/scummvm/scummvm/commit/3967da03efe714abe1940c8a0c74b20918fa0fd5
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Fix Compilation With Latest Git Master.
Changed paths:
engines/toltecs/microtiles.cpp
diff --git a/engines/toltecs/microtiles.cpp b/engines/toltecs/microtiles.cpp
index 7414eba..38e4f65 100644
--- a/engines/toltecs/microtiles.cpp
+++ b/engines/toltecs/microtiles.cpp
@@ -176,7 +176,6 @@ Common::Rect * MicroTileArray::getRectangles(int *num_rects, int min_x, int min_
rects[n_rects].right = x1 + 1;
rects[n_rects].bottom = y1 + 1;
n_rects++;
- fflush(stdout);
#else
Commit: eb0b7c957fc811e8d43ad2a38711c5bb3d6ba5b6
https://github.com/scummvm/scummvm/commit/eb0b7c957fc811e8d43ad2a38711c5bb3d6ba5b6
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Update AdvancedMetaEngine For Removal of ADParams.
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 50d605d..2e6e052 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -140,34 +140,11 @@ static const ToltecsGameDescription gameDescriptions[] = {
} // End of namespace Toltecs
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)Toltecs::gameDescriptions,
- // Size of that superset structure
- sizeof(Toltecs::ToltecsGameDescription),
- // Number of bytes to compute MD5 sum for
- 5000,
- // List of all engine targets
- toltecsGames,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- "toltecs",
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 1,
- // List of directory globs
- 0
-};
-
class ToltecsMetaEngine : public AdvancedMetaEngine {
public:
- ToltecsMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+ ToltecsMetaEngine() : AdvancedMetaEngine(Toltecs::gameDescriptions, sizeof(Toltecs::ToltecsGameDescription), toltecsGames) {
+ params.singleid = "toltecs";
+ }
virtual const char *getName() const {
return "Toltecs Engine";
Commit: 4ba1f78dc5ac45ba0de6716b098f80e6af289ed6
https://github.com/scummvm/scummvm/commit/4ba1f78dc5ac45ba0de6716b098f80e6af289ed6
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Fix Detection For ADParams Removal From AdvancedMetaEngine.
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 2e6e052..e168aab 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -143,7 +143,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
class ToltecsMetaEngine : public AdvancedMetaEngine {
public:
ToltecsMetaEngine() : AdvancedMetaEngine(Toltecs::gameDescriptions, sizeof(Toltecs::ToltecsGameDescription), toltecsGames) {
- params.singleid = "toltecs";
+ _singleid = "toltecs";
}
virtual const char *getName() const {
Commit: c545a8b1763df661e46047bcedb052385d62a507
https://github.com/scummvm/scummvm/commit/c545a8b1763df661e46047bcedb052385d62a507
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Fix saveGameState signature to match Engine's virtual method.
Changed paths:
engines/toltecs/saveload.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index aa04537..9d88b9d 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -184,9 +184,9 @@ Common::Error ToltecsEngine::loadGameState(int slot) {
return Common::kNoError;
}
-Common::Error ToltecsEngine::saveGameState(int slot, const char *description) {
+Common::Error ToltecsEngine::saveGameState(int slot, const Common::String &description) {
const char *fileName = getSavegameFilename(slot);
- savegame(fileName, description);
+ savegame(fileName, description.c_str());
return Common::kNoError;
}
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index ce87d19..377ef1c 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -195,7 +195,7 @@ public:
bool canLoadGameStateCurrently() { return _isSaveAllowed; }
bool canSaveGameStateCurrently() { return _isSaveAllowed; }
Common::Error loadGameState(int slot);
- Common::Error saveGameState(int slot, const char *description);
+ Common::Error saveGameState(int slot, const Common::String &description);
void savegame(const char *filename, const char *description);
void loadgame(const char *filename);
Commit: 9b885d0c5018c841fc616d182eb059eb9fd1b7f7
https://github.com/scummvm/scummvm/commit/9b885d0c5018c841fc616d182eb059eb9fd1b7f7
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Removed now uneeded c_str() call.
Changed paths:
engines/toltecs/script.cpp
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 53af5f9..8f534ef 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -192,7 +192,7 @@ void ScriptInterpreter::runScript() {
if (_vm->_saveLoadRequested == 1)
_vm->loadGameState(_vm->_saveLoadSlot);
else if (_vm->_saveLoadRequested == 2)
- _vm->saveGameState(_vm->_saveLoadSlot, _vm->_saveLoadDescription.c_str());
+ _vm->saveGameState(_vm->_saveLoadSlot, _vm->_saveLoadDescription);
_vm->_saveLoadRequested = 0;
}
Commit: 86e6ec89efe2a13c6502e215c496535a7f40e678
https://github.com/scummvm/scummvm/commit/86e6ec89efe2a13c6502e215c496535a7f40e678
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Fix Compilation due to Graphics::loadThumbnail() API change.
Changed paths:
engines/toltecs/saveload.cpp
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 9d88b9d..b895c7c 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -53,12 +53,7 @@ ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::Seekab
header.description += (char)in->readByte();
if (loadThumbnail) {
- header.thumbnail = new Graphics::Surface();
- assert(header.thumbnail);
- if (!Graphics::loadThumbnail(*in, *header.thumbnail)) {
- delete header.thumbnail;
- header.thumbnail = 0;
- }
+ header.thumbnail = Graphics::loadThumbnail(*in);
} else {
Graphics::skipThumbnail(*in);
}
Commit: 9b487e917d729a59d68b99db609206e8e20eaaca
https://github.com/scummvm/scummvm/commit/9b487e917d729a59d68b99db609206e8e20eaaca
Author: David Turner (digitall at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Switch to initGraphics() call, rather than separate calls.
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 180da78..42a1b20 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -84,11 +84,7 @@ void ToltecsEngine::syncSoundSettings() {
}
Common::Error ToltecsEngine::run() {
- // Initialize backend
- _system->beginGFXTransaction();
- initCommonGFX(true);
- _system->initSize(640, 400);
- _system->endGFXTransaction();
+ initGraphics(640, 400, true);
_isSaveAllowed = true;
Commit: 522c1ca32b844633a647c1529d9ff015d0c07836
https://github.com/scummvm/scummvm/commit/522c1ca32b844633a647c1529d9ff015d0c07836
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Bugfixes for the game menu
- The game's background is now restored when the menu closes
- Fixed a memory leak
- Removed dead code
Changed paths:
engines/toltecs/menu.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 074e27c..720767b 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -44,6 +44,11 @@ int MenuSystem::run() {
_background = new Graphics::Surface();
_background->create(640, 400, Graphics::PixelFormat::createFormatCLUT8());
+ // Save original background
+ Graphics::Surface backgroundOrig;
+ backgroundOrig.create(640, 400, Graphics::PixelFormat::createFormatCLUT8());
+ memcpy(backgroundOrig.getBasePtr(0,0), _vm->_screen->_frontScreen, 640 * 400);
+
_currMenuID = kMenuIdNone;
_newMenuID = kMenuIdMain;
_currItemID = kItemIdNone;
@@ -64,17 +69,25 @@ int MenuSystem::run() {
_vm->_palette->buildColorTransTable(0, 16, 7);
_vm->_screen->_renderQueue->clear();
+ // Draw the menu background and frame
_vm->_screen->blastSprite(0x140 + _vm->_cameraX, 0x175 + _vm->_cameraY, 0, 1, 0x4000);
+ shadeRect(60, 39, 520, 246, 30, 94);
memcpy(_background->pixels, _vm->_screen->_frontScreen, 640 * 400);
- shadeRect(60, 39, 520, 246, 30, 94);
-
while (_running) {
update();
_vm->_system->updateScreen();
}
+ // Restore original background
+ memcpy(_vm->_screen->_frontScreen, backgroundOrig.getBasePtr(0,0), 640 * 400);
+ _vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, 400);
+ _vm->_system->updateScreen();
+
+ // Cleanup
+ backgroundOrig.free();
+ _background->free();
delete _background;
return 0;
@@ -93,7 +106,7 @@ void MenuSystem::update() {
if (_needRedraw) {
//_vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen + 39 * 640 + 60, 640, 60, 39, 520, 247);
_vm->_system->copyRectToScreen((const byte *)_vm->_screen->_frontScreen, 640, 0, 0, 640, 400);
- debug("redraw");
+ //debug("redraw");
_needRedraw = false;
}
@@ -410,25 +423,6 @@ void MenuSystem::restoreRect(int x, int y, int w, int h) {
}
void MenuSystem::shadeRect(int x, int y, int w, int h, byte color1, byte color2) {
- // FIXME: Why is the following block disabled?
-#if 0
- byte *src = (byte*)_background->getBasePtr(x, y);
- for (int xc = 0; xc < w; xc++) {
- src[xc] = color1;
- src[xc + h * 640] = 46;
- }
- src += 640;
- w -= 1;
- h -= 1;
- while (h--) {
- src[0] = color2;
- src[w] = color2;
- for (int xc = 1; xc < w; xc++) {
- src[xc] = _vm->_palette->getColorTransPixel(src[xc]);
- }
- src += 640;
- }
-#endif
byte *src = (byte*)_background->getBasePtr(x, y);
for (int xc = 0; xc < w; xc++) {
src[xc] = color2;
Commit: 1eed5caff5aace0fb4d423a64a3e00665815a2f3
https://github.com/scummvm/scummvm/commit/1eed5caff5aace0fb4d423a64a3e00665815a2f3
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Some cleanup of the menu code
Changed paths:
engines/toltecs/menu.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 720767b..ad97448 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -39,7 +39,7 @@ MenuSystem::~MenuSystem() {
int MenuSystem::run() {
- debug("MenuSystem::run()");
+ //debug("MenuSystem::run()");
_background = new Graphics::Surface();
_background->create(640, 400, Graphics::PixelFormat::createFormatCLUT8());
@@ -97,7 +97,7 @@ void MenuSystem::update() {
if (_currMenuID != _newMenuID) {
_currMenuID = _newMenuID;
- debug("_currMenuID = %d", _currMenuID);
+ //debug("_currMenuID = %d", _currMenuID);
initMenu(_currMenuID);
}
@@ -344,11 +344,11 @@ void MenuSystem::clickItem(ItemID id) {
setCfgText(true, false);
break;
case kItemIdVolumesMenu:
- debug("kItemIdVolumesMenu");
+ //debug("kItemIdVolumesMenu");
_newMenuID = kMenuIdVolumes;
break;
case kItemIdPlay:
- debug("kItemIdPlay");
+ //debug("kItemIdPlay");
_running = false;
break;
case kItemIdQuit:
@@ -488,19 +488,13 @@ int MenuSystem::loadSavegamesList() {
MenuSystem::SavegameItem *MenuSystem::getSavegameItemByID(ItemID id) {
switch (id) {
case kItemIdSavegame1:
- return &_savegames[_savegameListTopIndex + 0];
case kItemIdSavegame2:
- return &_savegames[_savegameListTopIndex + 1];
case kItemIdSavegame3:
- return &_savegames[_savegameListTopIndex + 2];
case kItemIdSavegame4:
- return &_savegames[_savegameListTopIndex + 3];
case kItemIdSavegame5:
- return &_savegames[_savegameListTopIndex + 4];
case kItemIdSavegame6:
- return &_savegames[_savegameListTopIndex + 5];
case kItemIdSavegame7:
- return &_savegames[_savegameListTopIndex + 6];
+ return &_savegames[_savegameListTopIndex + id - kItemIdSavegame1];
default:
return NULL;
}
@@ -534,7 +528,7 @@ void MenuSystem::scrollSavegames(int delta) {
void MenuSystem::clickSavegameItem(ItemID id) {
if (_currMenuID == kMenuIdLoad) {
SavegameItem *savegameItem = getSavegameItemByID(id);
- debug("slotNum = [%d]; description = [%s]", savegameItem->_slotNum, savegameItem->_description.c_str());
+ //debug("slotNum = [%d]; description = [%s]", savegameItem->_slotNum, savegameItem->_description.c_str());
//_vm->loadgame(savegameItem->_filename.c_str());
_vm->requestLoadgame(savegameItem->_slotNum);
_running = false;
Commit: 84e6ceafbf70260a27a3d3f9eacf98580a04fcd6
https://github.com/scummvm/scummvm/commit/84e6ceafbf70260a27a3d3f9eacf98580a04fcd6
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Initialize mouse cursor when loading a saved game from the launcher
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 42a1b20..6b2704c 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -169,6 +169,7 @@ Common::Error ToltecsEngine::run() {
if (ConfMan.hasKey("save_slot")) {
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot >= 0 && saveSlot <= 99) {
+ _screen->loadMouseCursor(12);
loadGameState(saveSlot);
}
}
Commit: 4a03bb3e435fca0ec155242fe8739db1a022d9c8
https://github.com/scummvm/scummvm/commit/4a03bb3e435fca0ec155242fe8739db1a022d9c8
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Disabled some leftover unnecessary debug output
Changed paths:
engines/toltecs/menu.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index ad97448..54527c6 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -475,7 +475,7 @@ int MenuSystem::loadSavegamesList() {
if (in) {
if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
_savegames.push_back(SavegameItem(slotNum, header.description));
- debug("%s -> %s", file->c_str(), header.description.c_str());
+ //debug("%s -> %s", file->c_str(), header.description.c_str());
}
delete in;
}
Commit: 48e0238ed0b7caae871393ff916007986f5a591d
https://github.com/scummvm/scummvm/commit/48e0238ed0b7caae871393ff916007986f5a591d
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Updated the TODO, after talking with johndoe
Changed paths:
engines/toltecs/TODO.txt
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 248fe41..449ffcb 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -1,26 +1,20 @@
NOTES
-------
-
- The game is completable with revision 20 with some minor glitches (see BUGS).
TODO
------
-
-- Rewrite the resource system to something similar as used by M4
- - each resource type gets its own class, the resource cache manages the resource instances
- - generic resource class which has a method that creates a MemoryReadStream
- - rewrite parts of the engine to use the new resource system
- Add music support (game seems to use XMIDI, MIDI and headerless music...figure out more)
-- Add game menu
- - Rewrite from scratch with only minor stuff from the disasm since the original menu is one huge
- messy function
-- Extend savegame format (savegame version, description, more data)
- When saving a game, save the whole screen when an animation is playing
+ e.g. when playing animations (the script controlled ones, not the movies) it should save
+ the whole screen when the game is saved when such an animation is running since it uses
+ delta-frames so currently, once restored, the screen is wrong. This is only observed in
+ a few places.
+- Add "Quit game" functionality to the menu
BUGS
------
-
- Crashes sometimes on scene changes
(I guess because some talktext is still running although the slot used by it has changed)
- Crashes sometimes (e.g. when inside the barn and going up the ladder)
@@ -32,3 +26,11 @@ DONE
- Add movie playback functionality (movie format is known, needs implementing)
- Add sound support (after rewrite of the resource system)
- Still some clipping issues (walking upstairs in the saloon, when on top of the tower in the hideout)
+- Add game menu
+ - Rewrite from scratch with only minor stuff from the disasm since the original menu is one huge
+ messy function
+- Rewrite the resource system to something similar as used by M4
+ - each resource type gets its own class, the resource cache manages the resource instances
+ - generic resource class which has a method that creates a MemoryReadStream
+ - rewrite parts of the engine to use the new resource system
+- Extend savegame format (savegame version, description, more data)
Commit: 6fc40c7c24ee33ba2c7f92108b30130987001e8a
https://github.com/scummvm/scummvm/commit/6fc40c7c24ee33ba2c7f92108b30130987001e8a
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Updated TODO
Changed paths:
engines/toltecs/TODO.txt
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 449ffcb..ae913ef 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -12,6 +12,7 @@ TODO
delta-frames so currently, once restored, the screen is wrong. This is only observed in
a few places.
- Add "Quit game" functionality to the menu
+- Flush the resource cache when changing rooms, otherwise the game will keep eating up memory
BUGS
------
Commit: 2b29dfe0c796a5077fea4e5b0a6dff9a3feeb1b6
https://github.com/scummvm/scummvm/commit/2b29dfe0c796a5077fea4e5b0a6dff9a3feeb1b6
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Added the ability to skip the current dialog line with the escape key
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 6b2704c..37834e8 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -334,6 +334,14 @@ void ToltecsEngine::updateInput() {
case Common::KEYCODE_F9:
loadgame("toltecs.001");
break;
+ case Common::KEYCODE_ESCAPE:
+ // Skip current dialog line, if a dialog is active
+ if (_screen->getTalkTextDuration() > 0) {
+ _sound->stopSpeech();
+ _screen->finishTalkTextItems();
+ _keyState.reset(); // event consumed
+ }
+ break;
default:
break;
}
Commit: 5298859cbaa97b1fab98e6687fee8357a8bec199
https://github.com/scummvm/scummvm/commit/5298859cbaa97b1fab98e6687fee8357a8bec199
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: The resource cache is now purged when changing rooms
Changed paths:
engines/toltecs/TODO.txt
engines/toltecs/resource.cpp
engines/toltecs/resource.h
engines/toltecs/script.cpp
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index ae913ef..449ffcb 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -12,7 +12,6 @@ TODO
delta-frames so currently, once restored, the screen is wrong. This is only observed in
a few places.
- Add "Quit game" functionality to the menu
-- Flush the resource cache when changing rooms, otherwise the game will keep eating up memory
BUGS
------
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index 62dbca3..e1e3cb9 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -90,7 +90,17 @@ ResourceCache::ResourceCache(ToltecsEngine *vm) : _vm(vm) {
}
ResourceCache::~ResourceCache() {
- // TODO: Delete resources
+ purgeCache();
+}
+
+void ResourceCache::purgeCache() {
+ for (ResourceMap::iterator iter = _cache.begin(); iter != _cache.end(); ++iter) {
+ delete[] iter->_value->data;
+ delete iter->_value;
+ iter->_value = 0;
+ }
+
+ _cache.clear();
}
Resource *ResourceCache::load(uint resIndex) {
diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h
index 0201bd5..7f4694f 100644
--- a/engines/toltecs/resource.h
+++ b/engines/toltecs/resource.h
@@ -68,6 +68,7 @@ public:
~ResourceCache();
Resource *load(uint resIndex);
+ void purgeCache();
protected:
typedef Common::HashMap<uint, Resource*> ResourceMap;
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 8f534ef..780e9ef 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -896,6 +896,7 @@ void ScriptInterpreter::sfLoadAddPalette() {
void ScriptInterpreter::sfLoadScene() {
if (arg8(3) == 0) {
_vm->_sound->stopSpeech();
+ _vm->_res->purgeCache();
_vm->loadScene(arg16(4));
} else {
_vm->_screen->loadMouseCursor(arg16(4));
Commit: 9f8ceaace26d56d7d57a39b1f955eb518ff93624
https://github.com/scummvm/scummvm/commit/9f8ceaace26d56d7d57a39b1f955eb518ff93624
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:11-08:00
Commit Message:
TOLTECS: Implemented Quit game functionality in the menu
Changed paths:
engines/toltecs/TODO.txt
engines/toltecs/menu.cpp
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 449ffcb..0b9970d 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -11,7 +11,6 @@ TODO
the whole screen when the game is saved when such an animation is running since it uses
delta-frames so currently, once restored, the screen is wrong. This is only observed in
a few places.
-- Add "Quit game" functionality to the menu
BUGS
------
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 54527c6..7629bf4 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -352,7 +352,8 @@ void MenuSystem::clickItem(ItemID id) {
_running = false;
break;
case kItemIdQuit:
- debug("kItemIdQuit");
+ _running = false;
+ _vm->quitGame();
break;
// Volumes menu
case kItemIdMasterUp:
Commit: 8940d7348aa966b8cf91706cea3b8f648e79d746
https://github.com/scummvm/scummvm/commit/8940d7348aa966b8cf91706cea3b8f648e79d746
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Add finalize() calls to file output code
Changed paths:
engines/toltecs/resource.cpp
engines/toltecs/saveload.cpp
diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp
index e1e3cb9..b95e044 100644
--- a/engines/toltecs/resource.cpp
+++ b/engines/toltecs/resource.cpp
@@ -79,6 +79,7 @@ void ArchiveReader::dump(uint resIndex, const char *prefix) {
Common::DumpFile o;
o.open(fn);
o.write(data, resourceSize);
+ o.finalize();
o.close();
delete[] data;
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index b895c7c..c421be4 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -112,6 +112,7 @@ void ToltecsEngine::savegame(const char *filename, const char *description) {
_anim->saveState(out);
_screen->saveState(out);
+ out->finalize();
delete out;
}
Commit: 360bd6edd316e0111bd61cd65accbc9c91ac8728
https://github.com/scummvm/scummvm/commit/360bd6edd316e0111bd61cd65accbc9c91ac8728
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Initial implementation for music
Changed paths:
A engines/toltecs/music.cpp
A engines/toltecs/music.h
engines/toltecs/TODO.txt
engines/toltecs/module.mk
engines/toltecs/script.cpp
engines/toltecs/toltecs.cpp
engines/toltecs/toltecs.h
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 0b9970d..45b7b6d 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -5,7 +5,7 @@ NOTES
TODO
------
-- Add music support (game seems to use XMIDI, MIDI and headerless music...figure out more)
+- Finish music support (game seems to use XMIDI, MIDI and headerless music...figure out more)
- When saving a game, save the whole screen when an animation is playing
e.g. when playing animations (the script controlled ones, not the movies) it should save
the whole screen when the game is saved when such an animation is running since it uses
diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk
index 1d9d50c..aa4a6f3 100644
--- a/engines/toltecs/module.mk
+++ b/engines/toltecs/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS = \
menu.o \
microtiles.o \
movie.o \
+ music.o \
palette.o \
toltecs.o \
render.o \
diff --git a/engines/toltecs/music.cpp b/engines/toltecs/music.cpp
new file mode 100644
index 0000000..8c88c6d
--- /dev/null
+++ b/engines/toltecs/music.cpp
@@ -0,0 +1,138 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// FIXME: This code is taken from SAGA and needs more work (e.g. setVolume).
+
+#include "toltecs/music.h"
+
+#include "audio/midiparser.h"
+
+namespace Toltecs {
+
+MusicPlayer::MusicPlayer() : _isGM(false), _buffer(NULL) {
+ MidiPlayer::createDriver();
+
+ int ret = _driver->open();
+ if (ret == 0) {
+ if (_nativeMT32)
+ _driver->sendMT32Reset();
+ else
+ _driver->sendGMReset();
+
+ _driver->setTimerCallback(this, &timerCallback);
+ }
+}
+
+void MusicPlayer::send(uint32 b) {
+ if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
+ b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
+ }
+
+ Audio::MidiPlayer::send(b);
+}
+
+void MusicPlayer::playXMIDI(const byte *data, uint32 size, MusicFlags flags) {
+ Common::StackLock lock(_mutex);
+
+ if (_isPlaying)
+ return;
+
+ stopAndClear();
+
+ _buffer = new byte[size];
+ memcpy(_buffer, data, size);
+
+ // Load XMID resource data
+
+ _isGM = true;
+
+ MidiParser *parser = MidiParser::createParser_XMIDI(NULL);
+ if (parser->loadMusic(_buffer, size)) {
+ parser->setTrack(0);
+ parser->setMidiDriver(this);
+ parser->setTimerRate(_driver->getBaseTempo());
+ parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+ parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
+
+ _parser = parser;
+
+ setVolume(127);
+
+ _isLooping = flags & MUSIC_LOOP;
+ _isPlaying = true;
+ } else {
+ delete parser;
+ }
+}
+
+void MusicPlayer::playSMF(const byte *data, uint32 size, MusicFlags flags) {
+ Common::StackLock lock(_mutex);
+
+ if (_isPlaying)
+ return;
+
+ stopAndClear();
+
+ _buffer = new byte[size];
+ memcpy(_buffer, data, size);
+
+ // Load MIDI resource data
+
+ _isGM = true;
+
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(_buffer, size)) {
+ parser->setTrack(0);
+ parser->setMidiDriver(this);
+ parser->setTimerRate(_driver->getBaseTempo());
+ parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+
+ _parser = parser;
+
+ setVolume(127);
+
+ _isLooping = flags & MUSIC_LOOP;
+ _isPlaying = true;
+ } else {
+ delete parser;
+ }
+}
+
+void MusicPlayer::pause() {
+ setVolume(-1);
+ _isPlaying = false;
+}
+
+void MusicPlayer::resume() {
+ setVolume(127);
+ _isPlaying = true;
+}
+
+void MusicPlayer::stopAndClear() {
+ Common::StackLock lock(_mutex);
+ stop();
+
+ delete[] _buffer;
+ _buffer = NULL;
+}
+
+} // End of namespace Made
diff --git a/engines/toltecs/music.h b/engines/toltecs/music.h
new file mode 100644
index 0000000..9658633
--- /dev/null
+++ b/engines/toltecs/music.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Music class
+
+#ifndef MADE_MUSIC_H
+#define MADE_MUSIC_H
+
+#include "audio/midiplayer.h"
+
+namespace Toltecs {
+
+enum MusicFlags {
+ MUSIC_NORMAL = 0,
+ MUSIC_LOOP = 1
+};
+
+class MusicPlayer : public Audio::MidiPlayer {
+public:
+ MusicPlayer();
+
+ void playXMIDI(const byte *data, uint32 size, MusicFlags flags = MUSIC_NORMAL);
+ void playSMF(const byte *data, uint32 size, MusicFlags flags = MUSIC_NORMAL);
+ void pause();
+ void resume();
+ void stopAndClear();
+
+ // MidiDriver_BASE interface implementation
+ virtual void send(uint32 b);
+
+protected:
+ bool _isGM;
+
+private:
+ byte *_buffer;
+};
+
+} // End of namespace Made
+
+#endif
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 780e9ef..1104c96 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -31,6 +31,7 @@
#include "toltecs/animation.h"
#include "toltecs/menu.h"
#include "toltecs/movie.h"
+#include "toltecs/music.h"
#include "toltecs/palette.h"
#include "toltecs/resource.h"
#include "toltecs/script.h"
@@ -1037,17 +1038,32 @@ void ScriptInterpreter::sfStopShakeScreen() {
}
void ScriptInterpreter::sfStartSequence() {
- // TODO
- // DEBUG: Dump music so we know what's in there
int16 sequenceResIndex = arg16(3);
- debug("ScriptInterpreter::sfStartSequence(%d)", sequenceResIndex);
- if (sequenceResIndex >= 0)
- _vm->_arc->dump(sequenceResIndex, "music");
+ //debug("ScriptInterpreter::sfStartSequence(%d)", sequenceResIndex);
+ if (sequenceResIndex >= 0) {
+ //_vm->_arc->dump(sequenceResIndex, "music"); // DEBUG: Dump music so we know what's in there
+
+ int32 resourceSize = _vm->_arc->getResourceSize(sequenceResIndex);
+ byte *data = new byte[resourceSize];
+ _vm->_arc->openResource(sequenceResIndex);
+ _vm->_arc->read(data, resourceSize);
+ _vm->_arc->closeResource();
+
+ if (!memcmp(data, "FORM", 4)) {
+ // TODO: Looping flag
+ _vm->_musicPlayer->playXMIDI(data, resourceSize);
+ } else {
+ // TODO: Where does this occur? Are these SMF MIDI files?
+ warning("sfStartSequence: resource %d isn't XMIDI", sequenceResIndex);
+ }
+
+ delete[] data;
+ }
}
void ScriptInterpreter::sfEndSequence() {
- // TODO
- debug("ScriptInterpreter::sfEndSequence");
+ //debug("ScriptInterpreter::sfEndSequence");
+ _vm->_musicPlayer->stopAndClear();
}
void ScriptInterpreter::sfSetSequenceVolume() {
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 37834e8..7e3a294 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -41,6 +41,7 @@
#include "toltecs/animation.h"
#include "toltecs/menu.h"
#include "toltecs/movie.h"
+#include "toltecs/music.h"
#include "toltecs/palette.h"
#include "toltecs/render.h"
#include "toltecs/resource.h"
@@ -133,6 +134,7 @@ Common::Error ToltecsEngine::run() {
_palette = new Palette(this);
_segmap = new SegmentMap(this);
_moviePlayer = new MoviePlayer(this);
+ _musicPlayer = new MusicPlayer();
_menuSystem = new MenuSystem(this);
_sound = new Sound(this);
@@ -182,6 +184,7 @@ Common::Error ToltecsEngine::run() {
delete _anim;
delete _palette;
delete _segmap;
+ delete _musicPlayer;
delete _moviePlayer;
delete _menuSystem;
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index 377ef1c..279016c 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -45,6 +45,7 @@ class ArchiveReader;
class Input;
class MenuSystem;
class MoviePlayer;
+class MusicPlayer;
class Palette;
class ResourceCache;
class ScriptInterpreter;
@@ -134,6 +135,7 @@ public:
Input *_input;
MenuSystem *_menuSystem;
MoviePlayer *_moviePlayer;
+ MusicPlayer *_musicPlayer;
Palette *_palette;
ResourceCache *_res;
ScriptInterpreter *_script;
Commit: 9841ce6b9f3b00f387a6f149221db05815f64801
https://github.com/scummvm/scummvm/commit/9841ce6b9f3b00f387a6f149221db05815f64801
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Code cleanup
Changed paths:
engines/toltecs/music.cpp
engines/toltecs/music.h
engines/toltecs/script.cpp
diff --git a/engines/toltecs/music.cpp b/engines/toltecs/music.cpp
index 8c88c6d..84cb2f7 100644
--- a/engines/toltecs/music.cpp
+++ b/engines/toltecs/music.cpp
@@ -28,7 +28,7 @@
namespace Toltecs {
-MusicPlayer::MusicPlayer() : _isGM(false), _buffer(NULL) {
+MusicPlayer::MusicPlayer(bool isGM) : _isGM(isGM), _buffer(NULL) {
MidiPlayer::createDriver();
int ret = _driver->open();
@@ -50,22 +50,21 @@ void MusicPlayer::send(uint32 b) {
Audio::MidiPlayer::send(b);
}
-void MusicPlayer::playXMIDI(const byte *data, uint32 size, MusicFlags flags) {
+void MusicPlayer::playMIDI(const byte *data, uint32 size, MusicFlags flags) {
Common::StackLock lock(_mutex);
- if (_isPlaying)
- return;
-
stopAndClear();
_buffer = new byte[size];
memcpy(_buffer, data, size);
- // Load XMID resource data
-
- _isGM = true;
+ MidiParser *parser;
+
+ if (!memcmp(data, "FORM", 4))
+ parser = MidiParser::createParser_XMIDI(NULL);
+ else
+ parser = MidiParser::createParser_SMF();
- MidiParser *parser = MidiParser::createParser_XMIDI(NULL);
if (parser->loadMusic(_buffer, size)) {
parser->setTrack(0);
parser->setMidiDriver(this);
@@ -84,39 +83,6 @@ void MusicPlayer::playXMIDI(const byte *data, uint32 size, MusicFlags flags) {
}
}
-void MusicPlayer::playSMF(const byte *data, uint32 size, MusicFlags flags) {
- Common::StackLock lock(_mutex);
-
- if (_isPlaying)
- return;
-
- stopAndClear();
-
- _buffer = new byte[size];
- memcpy(_buffer, data, size);
-
- // Load MIDI resource data
-
- _isGM = true;
-
- MidiParser *parser = MidiParser::createParser_SMF();
- if (parser->loadMusic(_buffer, size)) {
- parser->setTrack(0);
- parser->setMidiDriver(this);
- parser->setTimerRate(_driver->getBaseTempo());
- parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
-
- _parser = parser;
-
- setVolume(127);
-
- _isLooping = flags & MUSIC_LOOP;
- _isPlaying = true;
- } else {
- delete parser;
- }
-}
-
void MusicPlayer::pause() {
setVolume(-1);
_isPlaying = false;
diff --git a/engines/toltecs/music.h b/engines/toltecs/music.h
index 9658633..4523821 100644
--- a/engines/toltecs/music.h
+++ b/engines/toltecs/music.h
@@ -36,10 +36,9 @@ enum MusicFlags {
class MusicPlayer : public Audio::MidiPlayer {
public:
- MusicPlayer();
+ MusicPlayer(bool isGM = true);
- void playXMIDI(const byte *data, uint32 size, MusicFlags flags = MUSIC_NORMAL);
- void playSMF(const byte *data, uint32 size, MusicFlags flags = MUSIC_NORMAL);
+ void playMIDI(const byte *data, uint32 size, MusicFlags flags = MUSIC_NORMAL);
void pause();
void resume();
void stopAndClear();
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 1104c96..91a3f36 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -1051,7 +1051,7 @@ void ScriptInterpreter::sfStartSequence() {
if (!memcmp(data, "FORM", 4)) {
// TODO: Looping flag
- _vm->_musicPlayer->playXMIDI(data, resourceSize);
+ _vm->_musicPlayer->playMIDI(data, resourceSize);
} else {
// TODO: Where does this occur? Are these SMF MIDI files?
warning("sfStartSequence: resource %d isn't XMIDI", sequenceResIndex);
Commit: 5c3c9f4e6cbc65648635050ce6ab794603767a0f
https://github.com/scummvm/scummvm/commit/5c3c9f4e6cbc65648635050ce6ab794603767a0f
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Added a hack to fix a crash when smoking the peace pipe
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 7e3a294..7414ab0 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -307,6 +307,15 @@ void ToltecsEngine::drawScreen() {
if (_screen->_guiRefresh && _guiHeight > 0 && _cameraHeight > 0) {
// Update the GUI when needed and it's visible
+ if (_cameraHeight + _guiHeight > 400)
+ // HACK: Sanity check - happens when smoking the peace pipe in the
+ // Indian village.
+ // FIXME: why does this happen? Fix the actual cause.
+ warning("Scene height (%d) and GUI height (%d) exceed the screen "
+ "height, cutting off the screen", _cameraHeight, _guiHeight);
+ _cameraHeight = 400 - _guiHeight;
+ }
+
_system->copyRectToScreen((const byte *)_screen->_frontScreen + _cameraHeight * 640,
640, 0, _cameraHeight, 640, _guiHeight);
_screen->_guiRefresh = false;
Commit: 14cbfd4607f0fa30dff8a7d5eb7a5caad060bc13
https://github.com/scummvm/scummvm/commit/14cbfd4607f0fa30dff8a7d5eb7a5caad060bc13
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Fixed typo
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 7414ab0..c3bb69c 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -307,7 +307,7 @@ void ToltecsEngine::drawScreen() {
if (_screen->_guiRefresh && _guiHeight > 0 && _cameraHeight > 0) {
// Update the GUI when needed and it's visible
- if (_cameraHeight + _guiHeight > 400)
+ if (_cameraHeight + _guiHeight > 400) {
// HACK: Sanity check - happens when smoking the peace pipe in the
// Indian village.
// FIXME: why does this happen? Fix the actual cause.
Commit: 1bddee1e7382ca28e55082b61a0e0a698a815eca
https://github.com/scummvm/scummvm/commit/1bddee1e7382ca28e55082b61a0e0a698a815eca
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Fixed music looping
Changed paths:
engines/toltecs/music.cpp
engines/toltecs/music.h
engines/toltecs/script.cpp
diff --git a/engines/toltecs/music.cpp b/engines/toltecs/music.cpp
index 84cb2f7..ef44421 100644
--- a/engines/toltecs/music.cpp
+++ b/engines/toltecs/music.cpp
@@ -50,7 +50,7 @@ void MusicPlayer::send(uint32 b) {
Audio::MidiPlayer::send(b);
}
-void MusicPlayer::playMIDI(const byte *data, uint32 size, MusicFlags flags) {
+void MusicPlayer::playMIDI(const byte *data, uint32 size, bool loop) {
Common::StackLock lock(_mutex);
stopAndClear();
@@ -76,7 +76,7 @@ void MusicPlayer::playMIDI(const byte *data, uint32 size, MusicFlags flags) {
setVolume(127);
- _isLooping = flags & MUSIC_LOOP;
+ _isLooping = loop;
_isPlaying = true;
} else {
delete parser;
diff --git a/engines/toltecs/music.h b/engines/toltecs/music.h
index 4523821..c7189e8 100644
--- a/engines/toltecs/music.h
+++ b/engines/toltecs/music.h
@@ -29,16 +29,11 @@
namespace Toltecs {
-enum MusicFlags {
- MUSIC_NORMAL = 0,
- MUSIC_LOOP = 1
-};
-
class MusicPlayer : public Audio::MidiPlayer {
public:
MusicPlayer(bool isGM = true);
- void playMIDI(const byte *data, uint32 size, MusicFlags flags = MUSIC_NORMAL);
+ void playMIDI(const byte *data, uint32 size, bool loop = false);
void pause();
void resume();
void stopAndClear();
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index 91a3f36..d95ac0e 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -1050,8 +1050,8 @@ void ScriptInterpreter::sfStartSequence() {
_vm->_arc->closeResource();
if (!memcmp(data, "FORM", 4)) {
- // TODO: Looping flag
- _vm->_musicPlayer->playMIDI(data, resourceSize);
+ // TODO: It seems that music is always looping?
+ _vm->_musicPlayer->playMIDI(data, resourceSize, true);
} else {
// TODO: Where does this occur? Are these SMF MIDI files?
warning("sfStartSequence: resource %d isn't XMIDI", sequenceResIndex);
Commit: b6c3232ea3b72b261b360febb9c6543452394066
https://github.com/scummvm/scummvm/commit/b6c3232ea3b72b261b360febb9c6543452394066
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Updated TODO
- Updated locations where the animation hack is necessary
- Fixed crashes on scene changes (with a TODO)
- MIDI Music is always XMIDI
- sfClearScreen() doesn't seem to be necessary
Changed paths:
engines/toltecs/TODO.txt
engines/toltecs/script.cpp
engines/toltecs/sound.cpp
engines/toltecs/sound.h
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 45b7b6d..6317f4a 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -5,21 +5,36 @@ NOTES
TODO
------
-- Finish music support (game seems to use XMIDI, MIDI and headerless music...figure out more)
+- Finish music support (volume, looping perhaps?)
+- Check if background resources are used before purging them when changing scenes - check
+ the comments inside sfLoadScene.
+- Sometimes, some stray lines are drawn below fonts - probably because the text doesn't
+ fit inside the screen and the surface is cut off incorrectly.
+- Load/start sound and music of the saved scene when loading.
+- The animation changes in commit 105 (probably) seem to be insufficient - some animations
+ exceed the screen height (together with the interface) - perhaps the interface height
+ should not be saved?
+- Some sounds are cut off prematurely (e.g. when an animation finishes before the sound
+ sample, when changing scenes and a dialog is immediately started afterwards).
- When saving a game, save the whole screen when an animation is playing
e.g. when playing animations (the script controlled ones, not the movies) it should save
the whole screen when the game is saved when such an animation is running since it uses
delta-frames so currently, once restored, the screen is wrong. This is only observed in
a few places.
+
BUGS
------
-- Crashes sometimes on scene changes
- (I guess because some talktext is still running although the slot used by it has changed)
-- Crashes sometimes (e.g. when inside the barn and going up the ladder)
+None known (see TODO).
DONE
------
+- Crashes sometimes on scene changes
+ (I guess because some talktext is still running although the slot used by it has changed)
+ Crashes sometimes (e.g. when inside the barn and going up the ladder)
+ These crashes are caused by non-stopping background sounds, see TODO above.
+- The game music is in XMIDI. I'm assuming that the rest of the formats were because of badly
+ dumped resources - finalize() Calls were missing and the resulting music could contain anything.
- Implement dirty rectangles (low priority)
- Optimize segment mask redrawing (only redraw what's neccessary)
- Add movie playback functionality (movie format is known, needs implementing)
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index d95ac0e..d0bf39b 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -896,7 +896,17 @@ void ScriptInterpreter::sfLoadAddPalette() {
void ScriptInterpreter::sfLoadScene() {
if (arg8(3) == 0) {
- _vm->_sound->stopSpeech();
+ // FIXME: Originally, this was stopSpeech(). However, we need to stop
+ // ALL sounds here (including sound effects and background sounds)
+ // before purgeCache() is called, otherwise the sound buffers will be
+ // invalidated. This is apparent when moving from a scene that has
+ // background sounds (such as the canyon at the beginning), to another
+ // one that doesn't (such as the map), and does not stop the sounds
+ // already playing. In this case, the engine will either crash or
+ // garbage will be heard through the speakers.
+ // TODO: We should either move purgeCache() elsewhere, or monitor
+ // which resources are still used before purging the cache.
+ _vm->_sound->stopAll();
_vm->_res->purgeCache();
_vm->loadScene(arg16(4));
} else {
@@ -1053,8 +1063,8 @@ void ScriptInterpreter::sfStartSequence() {
// TODO: It seems that music is always looping?
_vm->_musicPlayer->playMIDI(data, resourceSize, true);
} else {
- // TODO: Where does this occur? Are these SMF MIDI files?
- warning("sfStartSequence: resource %d isn't XMIDI", sequenceResIndex);
+ // Sanity check: this should never occur
+ error("sfStartSequence: resource %d isn't XMIDI", sequenceResIndex);
}
delete[] data;
@@ -1080,8 +1090,8 @@ void ScriptInterpreter::sfPlaySound2() {
}
void ScriptInterpreter::sfClearScreen() {
- // TODO
- debug("ScriptInterpreter::sfClearScreen");
+ // TODO: Occurs on every scene change, but seems unneeded
+ //debug("ScriptInterpreter::sfClearScreen");
}
void ScriptInterpreter::sfHandleInput() {
diff --git a/engines/toltecs/sound.cpp b/engines/toltecs/sound.cpp
index 3bebd81..47d5263 100644
--- a/engines/toltecs/sound.cpp
+++ b/engines/toltecs/sound.cpp
@@ -176,4 +176,13 @@ void Sound::stopSpeech() {
}
}
+void Sound::stopAll() {
+ for (int i = 0; i < kMaxChannels; i++) {
+ _vm->_mixer->stopHandle(channels[i].handle);
+ _vm->_screen->keepTalkTextItemsAlive();
+ channels[i].type = kChannelTypeEmpty;
+ channels[i].resIndex = -1;
+ }
+}
+
} // End of namespace Toltecs
diff --git a/engines/toltecs/sound.h b/engines/toltecs/sound.h
index 1414631..e4580ef 100644
--- a/engines/toltecs/sound.h
+++ b/engines/toltecs/sound.h
@@ -57,6 +57,7 @@ public:
void playSoundAtPos(int16 resIndex, int16 x, int16 y);
void updateSpeech();
void stopSpeech();
+ void stopAll();
protected:
ToltecsEngine *_vm;
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index c3bb69c..c268b13 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -309,7 +309,8 @@ void ToltecsEngine::drawScreen() {
// Update the GUI when needed and it's visible
if (_cameraHeight + _guiHeight > 400) {
// HACK: Sanity check - happens when smoking the peace pipe in the
- // Indian village.
+ // Indian village, when cheating at the game of cards and when
+ // the ladies find out that the sergeant is drinking again.
// FIXME: why does this happen? Fix the actual cause.
warning("Scene height (%d) and GUI height (%d) exceed the screen "
"height, cutting off the screen", _cameraHeight, _guiHeight);
Commit: fee561c0397d2e331306837544acb86d2b23c840
https://github.com/scummvm/scummvm/commit/fee561c0397d2e331306837544acb86d2b23c840
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Updated TODO
Changed paths:
engines/toltecs/TODO.txt
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 6317f4a..7aefbd8 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -10,6 +10,8 @@ TODO
the comments inside sfLoadScene.
- Sometimes, some stray lines are drawn below fonts - probably because the text doesn't
fit inside the screen and the surface is cut off incorrectly.
+- Fix some occasional artifacts on screen (e.g. when text is shown over an animation)
+ sometimes.
- Load/start sound and music of the saved scene when loading.
- The animation changes in commit 105 (probably) seem to be insufficient - some animations
exceed the screen height (together with the interface) - perhaps the interface height
Commit: f3fdcad214f694275a65adba90a4de84c857296a
https://github.com/scummvm/scummvm/commit/f3fdcad214f694275a65adba90a4de84c857296a
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Updated TODO
Changed paths:
engines/toltecs/TODO.txt
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index 7aefbd8..cac88e4 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -12,6 +12,11 @@ TODO
fit inside the screen and the surface is cut off incorrectly.
- Fix some occasional artifacts on screen (e.g. when text is shown over an animation)
sometimes.
+- Pathfinding bugs in Fort Apache and the Indian village - e.g. when moving to the door
+ on the right, the hero walks around a big path. Same when moving to the tent on the top
+ in the indian village.
+- When getting the piano player off the well, he walks up facing to the left (his side
+ animation is shown).
- Load/start sound and music of the saved scene when loading.
- The animation changes in commit 105 (probably) seem to be insufficient - some animations
exceed the screen height (together with the interface) - perhaps the interface height
Commit: a8112121b261ebb971512f07061992e264226d1b
https://github.com/scummvm/scummvm/commit/a8112121b261ebb971512f07061992e264226d1b
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Cleanup
Changed paths:
engines/toltecs/script.cpp
diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp
index d0bf39b..708afb7 100644
--- a/engines/toltecs/script.cpp
+++ b/engines/toltecs/script.cpp
@@ -543,82 +543,33 @@ const char *getVarName(uint variable) {
int16 ScriptInterpreter::getGameVar(uint variable) {
debug(0, "ScriptInterpreter::getGameVar(%d{%s})", variable, getVarName(variable));
- int16 value = 0;
-
switch (variable) {
- case 0:
- value = _vm->_mouseDisabled;
- break;
- case 1:
- value = _vm->_mouseY;
- break;
- case 2:
- value = _vm->_mouseX;
- break;
- case 3:
- value = _vm->_mouseButton;
- break;
- case 4:
- value = _vm->_screen->_verbLineY;
- break;
- case 5:
- value = _vm->_screen->_verbLineX;
- break;
- case 6:
- value = _vm->_screen->_verbLineWidth;
- break;
- case 7:
- value = _vm->_screen->_verbLineCount;
- break;
- case 8:
- value = _vm->_screen->_verbLineNum;
- break;
- case 9:
- value = _vm->_screen->_talkTextItemNum;
- break;
- case 10:
- value = _vm->_screen->_talkTextY;
- break;
- case 11:
- value = _vm->_screen->_talkTextX;
- break;
- case 12:
- value = _vm->_screen->_talkTextFontColor;
- break;
- case 13:
- value = _vm->_cameraY;
- break;
- case 14:
- value = _vm->_cameraX;
- break;
- case 15:
- value = _vm->_walkSpeedY;
- break;
- case 16:
- value = _vm->_walkSpeedX;
- break;
- case 17:
- value = _vm->_flag01;
- break;
- case 18:
- value = _vm->_sceneResIndex;
- break;
- case 19:
- value = _vm->_guiHeight;
- break;
- case 20:
- value = _vm->_sceneHeight;
- break;
- case 21:
- value = _vm->_sceneWidth;
- break;
+ case 0: return _vm->_mouseDisabled;
+ case 1: return _vm->_mouseY;
+ case 2: return _vm->_mouseX;
+ case 3: return _vm->_mouseButton;
+ case 4: return _vm->_screen->_verbLineY;
+ case 5: return _vm->_screen->_verbLineX;
+ case 6: return _vm->_screen->_verbLineWidth;
+ case 7: return _vm->_screen->_verbLineCount;
+ case 8: return _vm->_screen->_verbLineNum;
+ case 9: return _vm->_screen->_talkTextItemNum;
+ case 10: return _vm->_screen->_talkTextY;
+ case 11: return _vm->_screen->_talkTextX;
+ case 12: return _vm->_screen->_talkTextFontColor;
+ case 13: return _vm->_cameraY;
+ case 14: return _vm->_cameraX;
+ case 15: return _vm->_walkSpeedY;
+ case 16: return _vm->_walkSpeedX;
+ case 17: return _vm->_flag01;
+ case 18: return _vm->_sceneResIndex;
+ case 19: return _vm->_guiHeight;
+ case 20: return _vm->_sceneHeight;
+ case 21: return _vm->_sceneWidth;
default:
warning("Getting unimplemented game variable %s (%d)", getVarName(variable), variable);
- break;
+ return 0;
}
-
- return value;
-
}
void ScriptInterpreter::setGameVar(uint variable, int16 value) {
Commit: 8b4c082f6d833d33f2a5299ae9a402eeb05cae04
https://github.com/scummvm/scummvm/commit/8b4c082f6d833d33f2a5299ae9a402eeb05cae04
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Stop all sounds when exiting
Changed paths:
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index c268b13..47cabe0 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -177,6 +177,9 @@ Common::Error ToltecsEngine::run() {
}
_script->runScript();
+ _musicPlayer->stopAndClear();
+ _sound->stopAll();
+
delete _arc;
delete _res;
delete _screen;
Commit: 94f5b8b190590f4a28a27a5088987a05534705f9
https://github.com/scummvm/scummvm/commit/94f5b8b190590f4a28a27a5088987a05534705f9
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Always hide the game interface when showing a movie
Changed paths:
engines/toltecs/TODO.txt
engines/toltecs/movie.cpp
engines/toltecs/toltecs.cpp
diff --git a/engines/toltecs/TODO.txt b/engines/toltecs/TODO.txt
index cac88e4..31215f7 100644
--- a/engines/toltecs/TODO.txt
+++ b/engines/toltecs/TODO.txt
@@ -18,9 +18,6 @@ TODO
- When getting the piano player off the well, he walks up facing to the left (his side
animation is shown).
- Load/start sound and music of the saved scene when loading.
-- The animation changes in commit 105 (probably) seem to be insufficient - some animations
- exceed the screen height (together with the interface) - perhaps the interface height
- should not be saved?
- Some sounds are cut off prematurely (e.g. when an animation finishes before the sound
sample, when changing scenes and a dialog is immediately started afterwards).
- When saving a game, save the whole screen when an animation is playing
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index c396d6d..b90015f 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -47,6 +47,7 @@ void MoviePlayer::playMovie(uint resIndex) {
int16 savedCameraHeight = _vm->_cameraHeight;
int16 savedCameraX = _vm->_cameraX;
int16 savedCameraY = _vm->_cameraY;
+ int16 savedGuiHeight = _vm->_guiHeight;
byte moviePalette[768];
_vm->_isSaveAllowed = false;
@@ -72,6 +73,7 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_cameraHeight = 400;
_vm->_cameraX = 0;
_vm->_cameraY = 0;
+ _vm->_guiHeight = 0;
_audioStream = Audio::makeQueuingAudioStream(22050, false);
@@ -178,6 +180,7 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_cameraHeight = savedCameraHeight;
_vm->_cameraX = savedCameraX;
_vm->_cameraY = savedCameraY;
+ _vm->_guiHeight = savedGuiHeight;
_vm->_isSaveAllowed = true;
diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp
index 47cabe0..046578c 100644
--- a/engines/toltecs/toltecs.cpp
+++ b/engines/toltecs/toltecs.cpp
@@ -310,16 +310,6 @@ void ToltecsEngine::drawScreen() {
if (_screen->_guiRefresh && _guiHeight > 0 && _cameraHeight > 0) {
// Update the GUI when needed and it's visible
- if (_cameraHeight + _guiHeight > 400) {
- // HACK: Sanity check - happens when smoking the peace pipe in the
- // Indian village, when cheating at the game of cards and when
- // the ladies find out that the sergeant is drinking again.
- // FIXME: why does this happen? Fix the actual cause.
- warning("Scene height (%d) and GUI height (%d) exceed the screen "
- "height, cutting off the screen", _cameraHeight, _guiHeight);
- _cameraHeight = 400 - _guiHeight;
- }
-
_system->copyRectToScreen((const byte *)_screen->_frontScreen + _cameraHeight * 640,
640, 0, _cameraHeight, 640, _guiHeight);
_screen->_guiRefresh = false;
Commit: c119cbda906781cc05876ec48037c50321f60966
https://github.com/scummvm/scummvm/commit/c119cbda906781cc05876ec48037c50321f60966
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Slight cleanup of the audio code
Changed paths:
engines/toltecs/movie.cpp
diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp
index b90015f..054683b 100644
--- a/engines/toltecs/movie.cpp
+++ b/engines/toltecs/movie.cpp
@@ -33,6 +33,18 @@
namespace Toltecs {
+enum ChunkTypes {
+ kChunkFirstImage = 0,
+ kChunkSubsequentImages = 1,
+ kChunkPalette = 2,
+ kChunkUnused = 3,
+ kChunkAudio = 4,
+ kChunkShowSubtitle = 5,
+ kChunkShakeScreen = 6,
+ kChunkSetupSubtitles = 7,
+ kChunkStopSubtitles = 8
+};
+
MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm) {
}
@@ -81,31 +93,34 @@ void MoviePlayer::playMovie(uint resIndex) {
_soundChunkFramesLeft = 0;
_lastPrefetchOfs = 0;
+
fetchAudioChunks();
uint32 lastTime = _vm->_mixer->getSoundElapsedTime(_audioStreamHandle);
while (_chunkCount--) {
- byte chunkType;
- uint32 chunkSize;
- byte *chunkBuffer;
+ byte chunkType = _vm->_arc->readByte();
+ uint32 chunkSize = _vm->_arc->readUint32LE();
+ byte *chunkBuffer = NULL;
uint32 movieOffset;
- chunkType = _vm->_arc->readByte();
- chunkSize = _vm->_arc->readUint32LE();
-
debug(0, "chunkType = %d; chunkSize = %d", chunkType, chunkSize);
-
- chunkBuffer = new byte[chunkSize];
- _vm->_arc->read(chunkBuffer, chunkSize);
+
+ // Skip audio chunks - we've already queued them in
+ // fetchAudioChunks() above
+ if (chunkType == kChunkAudio) {
+ _vm->_arc->skip(chunkSize);
+ } else {
+ chunkBuffer = new byte[chunkSize];
+ _vm->_arc->read(chunkBuffer, chunkSize);
+ }
movieOffset = _vm->_arc->pos();
switch (chunkType) {
- case 0: // image data
- case 1:
-
+ case kChunkFirstImage:
+ case kChunkSubsequentImages:
unpackRle(chunkBuffer, _vm->_screen->_backScreen);
// TODO: Rework this
_vm->_screen->updateShakeScreen();
@@ -119,39 +134,41 @@ void MoviePlayer::playMovie(uint resIndex) {
}
while (_vm->_mixer->getSoundElapsedTime(_audioStreamHandle) < lastTime + 111) {
- g_system->delayMillis(0);
+ g_system->delayMillis(10);
}
lastTime = _vm->_mixer->getSoundElapsedTime(_audioStreamHandle);
break;
- case 2: // palette data
+ case kChunkPalette:
unpackPalette(chunkBuffer, moviePalette, 256, 3);
_vm->_palette->setFullPalette(moviePalette);
break;
- //case 3: -- what is this type
- case 4: // audio data
+ case kChunkUnused:
+ error("Chunk considered to be unused has been encountered");
+ case kChunkAudio:
+ // Already processed
break;
- case 5:
+ case kChunkShowSubtitle:
// TODO: Check if the text is a subtitle (last character == 0xFE).
// If so, don't show it if text display is disabled.
memcpy(_vm->_script->getSlotData(subtitleSlot), chunkBuffer, chunkSize);
_vm->_screen->updateTalkText(subtitleSlot, 0);
break;
- case 6: // start/stop shakescreen effect
+ case kChunkShakeScreen: // start/stop shakescreen effect
if (chunkBuffer[0] == 0xFF)
_vm->_screen->stopShakeScreen();
else
_vm->_screen->startShakeScreen(chunkBuffer[0]);
break;
- case 7: // setup subtitle parameters
+ case kChunkSetupSubtitles: // setup subtitle parameters
_vm->_screen->_talkTextY = READ_LE_UINT16(chunkBuffer + 0);
_vm->_screen->_talkTextX = READ_LE_UINT16(chunkBuffer + 2);
_vm->_screen->_talkTextFontColor = ((chunkBuffer[4] << 4) & 0xF0) | ((chunkBuffer[4] >> 4) & 0x0F);
debug(0, "_talkTextX = %d; _talkTextY = %d; _talkTextFontColor = %d",
_vm->_screen->_talkTextX, _vm->_screen->_talkTextY, _vm->_screen->_talkTextFontColor);
break;
- case 8: // stop subtitles
+ case kChunkStopSubtitles:
_vm->_script->getSlotData(subtitleSlot)[0] = 0xFF;
_vm->_screen->finishTalkTextItems();
break;
@@ -183,7 +200,6 @@ void MoviePlayer::playMovie(uint resIndex) {
_vm->_guiHeight = savedGuiHeight;
_vm->_isSaveAllowed = true;
-
}
void MoviePlayer::fetchAudioChunks() {
Commit: 8b503f558ed380514b4a070f1875383206952b85
https://github.com/scummvm/scummvm/commit/8b503f558ed380514b4a070f1875383206952b85
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Fixed compilation after the latest changes to GUI options
Changed paths:
engines/toltecs/detection.cpp
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index e168aab..3717d33 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -66,7 +66,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ GUIO1(GUIO_NONE)
},
},
@@ -79,7 +79,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ GUIO1(GUIO_NONE)
},
},
@@ -92,7 +92,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ GUIO1(GUIO_NONE)
},
},
@@ -105,7 +105,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ GUIO1(GUIO_NONE)
},
},
@@ -118,7 +118,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ GUIO1(GUIO_NONE)
},
},
@@ -131,7 +131,7 @@ static const ToltecsGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- Common::GUIO_NONE
+ GUIO1(GUIO_NONE)
},
},
Commit: e4d5320e7fbb183e68cb7c7b2221a6494fb18c38
https://github.com/scummvm/scummvm/commit/e4d5320e7fbb183e68cb7c7b2221a6494fb18c38
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Fixed typo in logic
Changed paths:
engines/toltecs/render.cpp
diff --git a/engines/toltecs/render.cpp b/engines/toltecs/render.cpp
index c6dbe93..de5e77f 100644
--- a/engines/toltecs/render.cpp
+++ b/engines/toltecs/render.cpp
@@ -247,7 +247,7 @@ RenderQueueItem *RenderQueue::findItemInQueue(RenderQueueArray *queue, const Ren
bool RenderQueue::hasItemChanged(const RenderQueueItem &item1, const RenderQueueItem &item2) {
- if (item1.type != item1.type)
+ if (item1.type != item2.type)
return true;
if (item1.rect.left != item2.rect.left ||
Commit: 579c47b717fba7aa39a1adae23984060bdb771d3
https://github.com/scummvm/scummvm/commit/579c47b717fba7aa39a1adae23984060bdb771d3
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: Removed duplicate assignment
Changed paths:
engines/toltecs/menu.cpp
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 7629bf4..25c240f 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -53,7 +53,6 @@ int MenuSystem::run() {
_newMenuID = kMenuIdMain;
_currItemID = kItemIdNone;
_editingDescription = false;
- _needRedraw = false;
_cfgText = true;
_cfgVoices = true;
_cfgMasterVolume = 10;
Commit: 4c6038260484d7f7b63f435a3124bb99e9a44733
https://github.com/scummvm/scummvm/commit/4c6038260484d7f7b63f435a3124bb99e9a44733
Author: Alex Bevilacqua (alexbevi at gmail.com)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: integrate engine
Changed paths:
base/plugins.cpp
configure
engines/engines.mk
diff --git a/base/plugins.cpp b/base/plugins.cpp
index e587b96..df12d0d 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -172,6 +172,9 @@ public:
#if PLUGIN_ENABLED_STATIC(TINSEL)
LINK_PLUGIN(TINSEL)
#endif
+ #if PLUGIN_ENABLED_STATIC(TOLTECS)
+ LINK_PLUGIN(TOLTECS)
+ #endif
#if PLUGIN_ENABLED_STATIC(TOON)
LINK_PLUGIN(TOON)
#endif
diff --git a/configure b/configure
index 96667e6..9675e48 100755
--- a/configure
+++ b/configure
@@ -117,6 +117,7 @@ add_engine sword25 "Broken Sword 2.5" no
add_engine teenagent "Teen Agent" yes
add_engine testbed "TestBed: the Testing framework" no
add_engine tinsel "Tinsel" yes
+add_engine toltecs "3 Skulls of the Toltecs" no
add_engine toon "Toonstruck" yes
add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
add_engine tsage "TsAGE" yes
diff --git a/engines/engines.mk b/engines/engines.mk
index b327ba6..5280bf9 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -188,6 +188,11 @@ DEFINES += -DENABLE_TINSEL=$(ENABLE_TINSEL)
MODULES += engines/tinsel
endif
+ifdef ENABLE_TOLTECS
+DEFINES += -DENABLE_TOLTECS=$(ENABLE_TOLTECS)
+MODULES += engines/toltecs
+endif
+
ifdef ENABLE_TOON
DEFINES += -DENABLE_TOON=$(ENABLE_TOON)
MODULES += engines/toon
Commit: b592d73e6226c5c5375d4b40123b15e37b064b9e
https://github.com/scummvm/scummvm/commit/b592d73e6226c5c5375d4b40123b15e37b064b9e
Author: Alex Bevilacqua (alexbevi at gmail.com)
Date: 2011-11-20T13:43:12-08:00
Commit Message:
TOLTECS: silence a couple gcc warnings
Changed paths:
engines/toltecs/screen.h
engines/toltecs/sprite.cpp
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
index bf49569..988f59c 100644
--- a/engines/toltecs/screen.h
+++ b/engines/toltecs/screen.h
@@ -117,6 +117,7 @@ class SpriteFilter {
public:
SpriteFilter(const SpriteDrawItem &sprite) : _sprite(&sprite) {
}
+ virtual ~SpriteFilter() {}
virtual SpriteReaderStatus readPacket(PixelPacket &packet) = 0;
protected:
const SpriteDrawItem *_sprite;
diff --git a/engines/toltecs/sprite.cpp b/engines/toltecs/sprite.cpp
index 08c7ef4..7a02663 100644
--- a/engines/toltecs/sprite.cpp
+++ b/engines/toltecs/sprite.cpp
@@ -467,7 +467,7 @@ void Screen::drawSpriteCore(byte *dest, SpriteFilter &reader, const SpriteDrawIt
if (((sprite.flags & 0x40) && (packet.pixel != 0)) ||
((sprite.flags & 0x10) && (packet.pixel != 0xFF)) ||
- !(sprite.flags & 0x10) && (packet.pixel != 0))
+ (!(sprite.flags & 0x10) && (packet.pixel != 0)))
{
if (sprite.flags & 0x40) {
while (packet.count--) {
Commit: 2613e7f5879c8c3ca7663dfcea8d5b91c499c107
https://github.com/scummvm/scummvm/commit/2613e7f5879c8c3ca7663dfcea8d5b91c499c107
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2011-11-20T13:49:18-08:00
Commit Message:
TOLTECS: Merge toltecs engine
This is an engine for the game "3 Skulls of the Toltecs".
It is a renamed, tweaked and manual merge of the pull request at
https://github.com/scummvm/scummvm/pull/119
Changed paths:
A engines/toltecs/TODO.txt
A engines/toltecs/animation.cpp
A engines/toltecs/animation.h
A engines/toltecs/detection.cpp
A engines/toltecs/menu.cpp
A engines/toltecs/menu.h
A engines/toltecs/microtiles.cpp
A engines/toltecs/microtiles.h
A engines/toltecs/module.mk
A engines/toltecs/movie.cpp
A engines/toltecs/movie.h
A engines/toltecs/music.cpp
A engines/toltecs/music.h
A engines/toltecs/palette.cpp
A engines/toltecs/palette.h
A engines/toltecs/render.cpp
A engines/toltecs/render.h
A engines/toltecs/resource.cpp
A engines/toltecs/resource.h
A engines/toltecs/saveload.cpp
A engines/toltecs/screen.cpp
A engines/toltecs/screen.h
A engines/toltecs/script.cpp
A engines/toltecs/script.h
A engines/toltecs/segmap.cpp
A engines/toltecs/segmap.h
A engines/toltecs/sound.cpp
A engines/toltecs/sound.h
A engines/toltecs/sprite.cpp
A engines/toltecs/toltecs.cpp
A engines/toltecs/toltecs.h
base/plugins.cpp
configure
engines/engines.mk
More information about the Scummvm-git-logs
mailing list