aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--README4
-rw-r--r--audio/decoders/voc.cpp14
-rw-r--r--backends/graphics/graphics.h2
-rw-r--r--backends/graphics/null/null-graphics.h2
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp54
-rw-r--r--backends/graphics/opengl/opengl-graphics.h4
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp94
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h4
-rw-r--r--backends/graphics/wincesdl/wincesdl-graphics.cpp2
-rw-r--r--backends/graphics/wincesdl/wincesdl-graphics.h2
-rw-r--r--backends/modular-backend.cpp4
-rw-r--r--backends/modular-backend.h2
-rw-r--r--backends/platform/android/android.h2
-rw-r--r--backends/platform/android/gfx.cpp7
-rw-r--r--backends/platform/dc/dc.h2
-rw-r--r--backends/platform/dc/display.cpp2
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.cpp6
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.h2
-rw-r--r--backends/platform/iphone/osys_main.h2
-rw-r--r--backends/platform/iphone/osys_video.mm4
-rw-r--r--backends/platform/n64/osys_n64.h2
-rw-r--r--backends/platform/n64/osys_n64_base.cpp2
-rw-r--r--backends/platform/ps2/systemps2.cpp2
-rw-r--r--backends/platform/ps2/systemps2.h2
-rw-r--r--backends/platform/psp/osys_psp.cpp6
-rw-r--r--backends/platform/psp/osys_psp.h2
-rw-r--r--backends/platform/wii/osystem.h2
-rw-r--r--backends/platform/wii/osystem_gfx.cpp5
-rw-r--r--common/coroutines.cpp173
-rw-r--r--common/coroutines.h308
-rw-r--r--common/system.h42
-rw-r--r--engines/agi/saveload.cpp22
-rw-r--r--engines/cge/events.cpp16
-rw-r--r--engines/cruise/menu.cpp9
-rw-r--r--engines/dialogs.cpp30
-rw-r--r--engines/dreamweb/saveload.cpp16
-rw-r--r--engines/gob/detection_tables.h4
-rw-r--r--engines/gob/draw_v1.cpp2
-rw-r--r--engines/gob/draw_v2.cpp2
-rw-r--r--engines/gob/global.cpp1
-rw-r--r--engines/gob/global.h1
-rw-r--r--engines/gob/gob.h4
-rw-r--r--engines/gob/init.h1
-rw-r--r--engines/gob/init_fascin.cpp6
-rw-r--r--engines/gob/init_geisha.cpp7
-rw-r--r--engines/gob/init_v1.cpp2
-rw-r--r--engines/gob/init_v2.cpp2
-rw-r--r--engines/gob/inter_fascin.cpp3
-rw-r--r--engines/gob/inter_geisha.cpp5
-rw-r--r--engines/gob/inter_v1.cpp34
-rw-r--r--engines/gob/minigames/geisha/meter.cpp4
-rw-r--r--engines/gob/minigames/geisha/penetration.cpp581
-rw-r--r--engines/gob/minigames/geisha/penetration.h95
-rw-r--r--engines/gob/minigames/geisha/submarine.cpp9
-rw-r--r--engines/gob/minigames/geisha/submarine.h2
-rw-r--r--engines/gob/module.mk2
-rw-r--r--engines/gob/mult.cpp3
-rw-r--r--engines/gob/palanim.cpp93
-rw-r--r--engines/gob/sound/adlib.cpp1044
-rw-r--r--engines/gob/sound/adlib.h312
-rw-r--r--engines/gob/sound/adlplayer.cpp257
-rw-r--r--engines/gob/sound/adlplayer.h85
-rw-r--r--engines/gob/sound/musplayer.cpp391
-rw-r--r--engines/gob/sound/musplayer.h109
-rw-r--r--engines/gob/sound/sound.cpp90
-rw-r--r--engines/gob/sound/sound.h21
-rw-r--r--engines/groovie/cursor.cpp2
-rw-r--r--engines/hugo/console.cpp10
-rw-r--r--engines/hugo/dialogs.cpp82
-rw-r--r--engines/hugo/dialogs.h4
-rw-r--r--engines/hugo/display.cpp152
-rw-r--r--engines/hugo/display.h60
-rw-r--r--engines/hugo/file.cpp282
-rw-r--r--engines/hugo/file.h72
-rw-r--r--engines/hugo/file_v1d.cpp10
-rw-r--r--engines/hugo/file_v1w.cpp36
-rw-r--r--engines/hugo/file_v2d.cpp60
-rw-r--r--engines/hugo/file_v3d.cpp78
-rw-r--r--engines/hugo/game.h126
-rw-r--r--engines/hugo/hugo.cpp108
-rw-r--r--engines/hugo/hugo.h100
-rw-r--r--engines/hugo/intro.cpp142
-rw-r--r--engines/hugo/intro.h6
-rw-r--r--engines/hugo/inventory.cpp12
-rw-r--r--engines/hugo/inventory.h10
-rw-r--r--engines/hugo/mouse.cpp100
-rw-r--r--engines/hugo/mouse.h6
-rw-r--r--engines/hugo/object.cpp436
-rw-r--r--engines/hugo/object.h46
-rw-r--r--engines/hugo/object_v1d.cpp284
-rw-r--r--engines/hugo/object_v1w.cpp270
-rw-r--r--engines/hugo/object_v2d.cpp274
-rw-r--r--engines/hugo/object_v3d.cpp174
-rw-r--r--engines/hugo/parser.cpp98
-rw-r--r--engines/hugo/parser.h70
-rw-r--r--engines/hugo/parser_v1d.cpp164
-rw-r--r--engines/hugo/parser_v1w.cpp46
-rw-r--r--engines/hugo/parser_v2d.cpp28
-rw-r--r--engines/hugo/parser_v3d.cpp200
-rw-r--r--engines/hugo/route.cpp150
-rw-r--r--engines/hugo/route.h29
-rw-r--r--engines/hugo/schedule.cpp1252
-rw-r--r--engines/hugo/schedule.h583
-rw-r--r--engines/hugo/sound.cpp32
-rw-r--r--engines/hugo/sound.h2
-rw-r--r--engines/kyra/animator_hof.cpp2
-rw-r--r--engines/kyra/animator_mr.cpp4
-rw-r--r--engines/kyra/detection_tables.h2
-rw-r--r--engines/kyra/gui_hof.cpp35
-rw-r--r--engines/kyra/gui_lok.cpp6
-rw-r--r--engines/kyra/gui_mr.cpp25
-rw-r--r--engines/kyra/gui_v1.cpp9
-rw-r--r--engines/kyra/gui_v2.cpp10
-rw-r--r--engines/kyra/items_hof.cpp5
-rw-r--r--engines/kyra/items_lok.cpp16
-rw-r--r--engines/kyra/items_mr.cpp10
-rw-r--r--engines/kyra/items_v2.cpp7
-rw-r--r--engines/kyra/kyra_hof.cpp10
-rw-r--r--engines/kyra/kyra_lok.cpp8
-rw-r--r--engines/kyra/kyra_mr.cpp2
-rw-r--r--engines/kyra/kyra_v2.cpp3
-rw-r--r--engines/kyra/screen.cpp4
-rw-r--r--engines/kyra/screen_lok.cpp2
-rw-r--r--engines/kyra/script_hof.cpp4
-rw-r--r--engines/kyra/script_lok.cpp4
-rw-r--r--engines/kyra/script_mr.cpp4
-rw-r--r--engines/kyra/sequences_lok.cpp2
-rw-r--r--engines/kyra/text_hof.cpp9
-rw-r--r--engines/kyra/text_lok.cpp6
-rw-r--r--engines/kyra/text_mr.cpp6
-rw-r--r--engines/lastexpress/data/cursor.cpp2
-rw-r--r--engines/mohawk/cursors.cpp2
-rw-r--r--engines/mohawk/myst.cpp3
-rw-r--r--engines/mohawk/riven.cpp12
-rw-r--r--engines/mohawk/video.cpp20
-rw-r--r--engines/parallaction/saveload.cpp11
-rw-r--r--engines/sci/console.cpp22
-rw-r--r--engines/sci/detection_tables.h38
-rw-r--r--engines/sci/engine/file.cpp451
-rw-r--r--engines/sci/engine/file.h140
-rw-r--r--engines/sci/engine/kernel.h11
-rw-r--r--engines/sci/engine/kernel_tables.h32
-rw-r--r--engines/sci/engine/kfile.cpp1209
-rw-r--r--engines/sci/engine/kgraphics32.cpp160
-rw-r--r--engines/sci/engine/klists.cpp19
-rw-r--r--engines/sci/engine/kmisc.cpp28
-rw-r--r--engines/sci/engine/ksound.cpp8
-rw-r--r--engines/sci/engine/kstring.cpp14
-rw-r--r--engines/sci/engine/kvideo.cpp1
-rw-r--r--engines/sci/engine/savegame.cpp4
-rw-r--r--engines/sci/engine/script.cpp7
-rw-r--r--engines/sci/engine/script.h2
-rw-r--r--engines/sci/engine/state.cpp12
-rw-r--r--engines/sci/engine/state.h48
-rw-r--r--engines/sci/engine/workarounds.cpp1
-rw-r--r--engines/sci/event.cpp4
-rw-r--r--engines/sci/graphics/frameout.cpp131
-rw-r--r--engines/sci/graphics/frameout.h40
-rw-r--r--engines/sci/graphics/palette.cpp2
-rw-r--r--engines/sci/graphics/text32.cpp48
-rw-r--r--engines/sci/graphics/text32.h6
-rw-r--r--engines/sci/module.mk1
-rw-r--r--engines/scumm/cursor.cpp4
-rw-r--r--engines/scumm/detection.cpp1
-rw-r--r--engines/scumm/detection_tables.h9
-rw-r--r--engines/scumm/he/intern_he.h8
-rw-r--r--engines/scumm/he/logic/football.cpp173
-rw-r--r--engines/scumm/he/logic_he.cpp3
-rw-r--r--engines/scumm/he/logic_he.h1
-rw-r--r--engines/scumm/he/script_v100he.cpp5
-rw-r--r--engines/scumm/he/script_v60he.cpp2
-rw-r--r--engines/scumm/he/sound_he.cpp2
-rw-r--r--engines/scumm/scumm.h1
-rw-r--r--engines/sword25/gfx/image/art.cpp28
-rw-r--r--engines/sword25/gfx/image/art.h2
-rw-r--r--engines/tinsel/tinsel.h2
-rw-r--r--engines/toon/toon.cpp14
-rw-r--r--engines/tsage/scenes.cpp10
-rw-r--r--graphics/cursorman.cpp20
-rw-r--r--graphics/cursorman.h14
-rw-r--r--graphics/scaler.cpp9
-rw-r--r--graphics/scaler/aspect.cpp10
-rw-r--r--gui/ThemeEngine.cpp7
-rw-r--r--gui/ThemeEngine.h11
-rw-r--r--gui/ThemeParser.cpp7
-rw-r--r--gui/ThemeParser.h1
-rw-r--r--gui/launcher.cpp2
-rw-r--r--gui/saveload.cpp26
-rw-r--r--gui/saveload.h27
-rw-r--r--gui/themes/default.inc784
-rw-r--r--gui/themes/scummclassic.zipbin93390 -> 93390 bytes
-rw-r--r--gui/themes/scummclassic/THEMERC2
-rw-r--r--gui/themes/scummmodern.zipbin1449894 -> 1449870 bytes
-rw-r--r--gui/themes/scummmodern/THEMERC2
-rw-r--r--gui/themes/scummmodern/scummmodern_gfx.stx4
-rw-r--r--gui/widget.cpp86
-rw-r--r--gui/widget.h4
-rw-r--r--video/codecs/qtrle.cpp135
-rw-r--r--video/codecs/qtrle.h3
-rw-r--r--video/codecs/rpza.cpp22
-rw-r--r--video/codecs/rpza.h3
202 files changed, 7790 insertions, 5968 deletions
diff --git a/NEWS b/NEWS
index ed98cdc83f..acff8b8473 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ For a more comprehensive changelog of the latest experimental code, see:
- Added support for Blue Force.
- Added support for Darby the Dragon.
- Added support for Dreamweb.
+ - Added support for Geisha.
- Added support for Gregory and the Hot Air Balloon.
- Added support for Magic Tales: Baba Yaga and the Magic Geese.
- Added support for Magic Tales: Imo and the King.
@@ -28,7 +29,7 @@ For a more comprehensive changelog of the latest experimental code, see:
Engine tab when adding or editing a configuration for a game. In most
cases, you will have to run each game once or readd them all in ScummVM's
launcher in order to get the custom options tab.
- - Improved predicitve dialog look.
+ - Improved predictive dialog look.
- Various GUI improvements.
SDL ports:
@@ -44,6 +45,11 @@ For a more comprehensive changelog of the latest experimental code, see:
Cine:
- Implemented Roland MT-32 output driver.
+ Gob:
+ - Fixed a crash in Lost in Time
+ - Rewrote the AdLib player. Enabled the now working MDY player in
+ Fascination and Geisha.
+
SCUMM:
- Added support for the Macintosh version of SPY Fox in Hold the Mustard.
- Added a difficulty selection dialog for Loom FM-TOWNS.
diff --git a/README b/README
index 81b28830c2..1024c6764b 100644
--- a/README
+++ b/README
@@ -235,13 +235,17 @@ AGOS Games by Adventuresoft/Horrorsoft:
The Feeble Files [feeble]
GOB Games by Coktel Vision:
+ Bambou le sauveur de la jungle [bambou]
Bargon Attack [bargon]
+ Fascination [fascination]
+ Geisha [geisha]
Gobliiins [gob1]
Gobliins 2 [gob2]
Goblins 3 [gob3]
Lost in Time [lostintime]
The Bizarre Adventures of Woodruff
and the Schnibble [woodruff]
+ Urban Runner [urban]
Ween: The Prophecy [ween]
MADE Games by Activision:
diff --git a/audio/decoders/voc.cpp b/audio/decoders/voc.cpp
index f0b5b2777d..fa330c6f2c 100644
--- a/audio/decoders/voc.cpp
+++ b/audio/decoders/voc.cpp
@@ -321,9 +321,14 @@ void VocStream::preProcess() {
// In case we hit a "Terminator" block we also break here.
if (_stream->eos() || block.code == 0)
break;
- // We also allow 128 as terminator, since Simon 1 Amiga CD32 uses it.
- if (block.code == 128) {
- debug(3, "VocStream::preProcess: Caught 128 as terminator");
+ // We will allow invalid block numbers as terminators. This is needed,
+ // since some games ship broken VOC files. The following occasions are
+ // known:
+ // - 128 is used as terminator in Simon 1 Amiga CD32
+ // - Full Throttle contains a VOC file with an incorrect block length
+ // resulting in a sample (127) to be read as block code.
+ if (block.code > 9) {
+ warning("VocStream::preProcess: Caught %d as terminator", block.code);
break;
}
@@ -482,7 +487,8 @@ void VocStream::preProcess() {
default:
warning("Unhandled code %d in VOC file (len %d)", block.code, block.length);
- return;
+ // Skip the whole block and try to use the next one.
+ skip = block.length;
}
// Premature end of stream => error!
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index 3f282df587..0d6fa30418 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -80,7 +80,7 @@ public:
virtual bool showMouse(bool visible) = 0;
virtual void warpMouse(int x, int y) = 0;
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0;
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) = 0;
virtual void setCursorPalette(const byte *colors, uint start, uint num) = 0;
virtual void displayMessageOnOSD(const char *msg) {}
diff --git a/backends/graphics/null/null-graphics.h b/backends/graphics/null/null-graphics.h
index 2e6b24d147..2f8baae3e8 100644
--- a/backends/graphics/null/null-graphics.h
+++ b/backends/graphics/null/null-graphics.h
@@ -78,7 +78,7 @@ public:
bool showMouse(bool visible) { return !visible; }
void warpMouse(int x, int y) {}
- void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) {}
+ void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) {}
void setCursorPalette(const byte *colors, uint start, uint num) {}
};
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index cd820ae3b2..8449048997 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -49,7 +49,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
_transactionMode(kTransactionNone),
_cursorNeedsRedraw(false), _cursorPaletteDisabled(true),
_cursorVisible(false), _cursorKeyColor(0),
- _cursorTargetScale(1),
+ _cursorDontScale(false),
_formatBGR(false),
_displayX(0), _displayY(0), _displayWidth(0), _displayHeight(0) {
@@ -591,7 +591,7 @@ void OpenGLGraphicsManager::warpMouse(int x, int y) {
setInternalMousePosition(scaledX, scaledY);
}
-void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
#ifdef USE_RGB_COLOR
if (format)
_cursorFormat = *format;
@@ -616,7 +616,7 @@ void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int
_cursorState.hotX = hotspotX;
_cursorState.hotY = hotspotY;
_cursorKeyColor = keycolor;
- _cursorTargetScale = cursorTargetScale;
+ _cursorDontScale = dontScale;
_cursorNeedsRedraw = true;
refreshCursorScale();
@@ -829,28 +829,19 @@ void OpenGLGraphicsManager::refreshCursor() {
}
void OpenGLGraphicsManager::refreshCursorScale() {
- // Calculate the scale factors of the screen. We limit ourselves to 3 at
- // most here to avoid really big (and ugly) cursors for big resolutions.
- // It might be noteworthy that 3 is the (current) target scale for the
- // modern theme and thus assures the cursor is *never* scaled.
+ // Calculate the scale factors of the screen.
// We also totally ignore the aspect of the overlay cursor, since aspect
// ratio correction only applies to the game screen.
- uint screenScaleFactorX = MIN(30000, _videoMode.hardwareWidth * 10000 / _videoMode.screenWidth);
- uint screenScaleFactorY = MIN(30000, _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight);
-
- // Apply the target scale factor to the cursor.
- // It might be noteworthy we only apply any scaling to the cursor in case
- // the current scale factor is bigger than the target scale to match
- // SurfaceSdlGraphicsManager's behavior. Otherwise we would downscale the
- // GUI cursor of the modern theme for example.
- if (screenScaleFactorX > uint(_cursorTargetScale * 10000))
- screenScaleFactorX /= _cursorTargetScale;
- else
+ // TODO: It might make sense to always ignore scaling of the mouse cursor
+ // when the overlay is visible.
+ uint screenScaleFactorX = _videoMode.hardwareWidth * 10000 / _videoMode.screenWidth;
+ uint screenScaleFactorY = _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight;
+
+ // Ignore scaling when the cursor should not be scaled.
+ if (_cursorDontScale) {
screenScaleFactorX = 10000;
- if (screenScaleFactorY > uint(_cursorTargetScale * 10000))
- screenScaleFactorY /= _cursorTargetScale;
- else
screenScaleFactorY = 10000;
+ }
// Apply them (without any possible) aspect ratio correction to the
// overlay.
@@ -859,16 +850,19 @@ void OpenGLGraphicsManager::refreshCursorScale() {
_cursorState.rHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
_cursorState.rHotY = (int16)(_cursorState.hotY * screenScaleFactorY / 10000);
- // Make sure we properly scale the cursor according to the desired aspect.
- // It might be noteworthy that, unlike with the overlay, we do not limit
- // the scale factor here to avoid odd looks if the game uses items as
- // mouse cursor, which would otherwise suddenly be smaller.
- int width, height;
- calculateDisplaySize(width, height);
- screenScaleFactorX = (width * 10000 / _videoMode.screenWidth) / _cursorTargetScale;
- screenScaleFactorY = (height * 10000 / _videoMode.screenHeight) / _cursorTargetScale;
+ // Only apply scaling when it's desired.
+ if (_cursorDontScale) {
+ screenScaleFactorX = 10000;
+ screenScaleFactorY = 10000;
+ } else {
+ // Make sure we properly scale the cursor according to the desired aspect.
+ int width, height;
+ calculateDisplaySize(width, height);
+ screenScaleFactorX = (width * 10000 / _videoMode.screenWidth);
+ screenScaleFactorY = (height * 10000 / _videoMode.screenHeight);
+ }
- // Always scale the cursor for the game.
+ // Apply the scale cursor scaling for the game screen.
_cursorState.vW = (int16)(_cursorState.w * screenScaleFactorX / 10000);
_cursorState.vH = (int16)(_cursorState.h * screenScaleFactorY / 10000);
_cursorState.vHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000);
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index ad8765bab1..956722c08f 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -104,7 +104,7 @@ public:
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
virtual void displayMessageOnOSD(const char *msg);
@@ -283,7 +283,7 @@ protected:
MousePos _cursorState;
bool _cursorVisible;
uint32 _cursorKeyColor;
- int _cursorTargetScale;
+ bool _cursorDontScale;
bool _cursorNeedsRedraw;
/**
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index e841ecb834..652c08dc45 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -63,17 +63,12 @@ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Normal (no scaling)", "lowres")
-// Table of relative scalers magnitudes
-// [definedScale - 1][scaleFactor - 1]
-static ScalerProc *scalersMagn[3][3] = {
+// Table of the cursor scalers [scaleFactor - 1]
+static ScalerProc *scalersMagn[3] = {
#ifdef USE_SCALERS
- { Normal1x, AdvMame2x, AdvMame3x },
- { Normal1x, Normal1x, Normal1o5x },
- { Normal1x, Normal1x, Normal1x }
+ Normal1x, AdvMame2x, AdvMame3x
#else // remove dependencies on other scalers
- { Normal1x, Normal1x, Normal1x },
- { Normal1x, Normal1x, Normal1x },
- { Normal1x, Normal1x, Normal1x }
+ Normal1x, Normal1x, Normal1x
#endif
};
@@ -135,7 +130,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
_overlayscreen(0), _tmpscreen2(0),
_scalerProc(0), _screenChangeCount(0),
_mouseVisible(false), _mouseNeedsRedraw(false), _mouseData(0), _mouseSurface(0),
- _mouseOrigSurface(0), _cursorTargetScale(1), _cursorPaletteDisabled(true),
+ _mouseOrigSurface(0), _cursorDontScale(false), _cursorPaletteDisabled(true),
_currentShakePos(0), _newShakePos(0),
_paletteDirtyStart(0), _paletteDirtyEnd(0),
_screenIsLocked(false),
@@ -1718,7 +1713,7 @@ void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
}
}
-void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
#ifdef USE_RGB_COLOR
if (!format)
_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
@@ -1739,7 +1734,7 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h,
_mouseKeyColor = keycolor;
- _cursorTargetScale = cursorTargetScale;
+ _cursorDontScale = dontScale;
if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) {
_mouseCurState.w = w;
@@ -1847,51 +1842,34 @@ void SurfaceSdlGraphicsManager::blitCursor() {
}
int rW, rH;
+ int cursorScale;
- if (_cursorTargetScale >= _videoMode.scaleFactor) {
- // The cursor target scale is greater or equal to the scale at
- // which the rest of the screen is drawn. We do not downscale
- // the cursor image, we draw it at its original size. It will
- // appear too large on screen.
-
- rW = w;
- rH = h;
- _mouseCurState.rHotX = _mouseCurState.hotX;
- _mouseCurState.rHotY = _mouseCurState.hotY;
-
- // The virtual dimensions may be larger than the original.
-
- _mouseCurState.vW = w * _cursorTargetScale / _videoMode.scaleFactor;
- _mouseCurState.vH = h * _cursorTargetScale / _videoMode.scaleFactor;
- _mouseCurState.vHotX = _mouseCurState.hotX * _cursorTargetScale /
- _videoMode.scaleFactor;
- _mouseCurState.vHotY = _mouseCurState.hotY * _cursorTargetScale /
- _videoMode.scaleFactor;
+ if (_cursorDontScale) {
+ // Don't scale the cursor at all if the user requests this behavior.
+ cursorScale = 1;
} else {
- // The cursor target scale is smaller than the scale at which
- // the rest of the screen is drawn. We scale up the cursor
- // image to make it appear correct.
+ // Scale the cursor with the game screen scale factor.
+ cursorScale = _videoMode.scaleFactor;
+ }
- rW = w * _videoMode.scaleFactor / _cursorTargetScale;
- rH = h * _videoMode.scaleFactor / _cursorTargetScale;
- _mouseCurState.rHotX = _mouseCurState.hotX * _videoMode.scaleFactor /
- _cursorTargetScale;
- _mouseCurState.rHotY = _mouseCurState.hotY * _videoMode.scaleFactor /
- _cursorTargetScale;
+ // Adapt the real hotspot according to the scale factor.
+ rW = w * cursorScale;
+ rH = h * cursorScale;
+ _mouseCurState.rHotX = _mouseCurState.hotX * cursorScale;
+ _mouseCurState.rHotY = _mouseCurState.hotY * cursorScale;
- // The virtual dimensions will be the same as the original.
+ // The virtual dimensions will be the same as the original.
- _mouseCurState.vW = w;
- _mouseCurState.vH = h;
- _mouseCurState.vHotX = _mouseCurState.hotX;
- _mouseCurState.vHotY = _mouseCurState.hotY;
- }
+ _mouseCurState.vW = w;
+ _mouseCurState.vH = h;
+ _mouseCurState.vHotX = _mouseCurState.hotX;
+ _mouseCurState.vHotY = _mouseCurState.hotY;
#ifdef USE_SCALERS
int rH1 = rH; // store original to pass to aspect-correction function later
#endif
- if (_videoMode.aspectRatioCorrection && _cursorTargetScale == 1) {
+ if (!_cursorDontScale && _videoMode.aspectRatioCorrection) {
rH = real2Aspect(rH - 1) + 1;
_mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
}
@@ -1922,21 +1900,25 @@ void SurfaceSdlGraphicsManager::blitCursor() {
ScalerProc *scalerProc;
- // If possible, use the same scaler for the cursor as for the rest of
- // the game. This only works well with the non-blurring scalers so we
- // actually only use the 1x, 1.5x, 2x and AdvMame scalers.
-
- if (_cursorTargetScale == 1 && (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE))
- scalerProc = _scalerProc;
- else
- scalerProc = scalersMagn[_cursorTargetScale - 1][_videoMode.scaleFactor - 1];
+ // Only apply scaling, when the user allows it.
+ if (!_cursorDontScale) {
+ // If possible, use the same scaler for the cursor as for the rest of
+ // the game. This only works well with the non-blurring scalers so we
+ // actually only use the 1x, 2x and AdvMame scalers.
+ if (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE)
+ scalerProc = _scalerProc;
+ else
+ scalerProc = scalersMagn[_videoMode.scaleFactor - 1];
+ } else {
+ scalerProc = Normal1x;
+ }
scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2,
_mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch,
_mouseCurState.w, _mouseCurState.h);
#ifdef USE_SCALERS
- if (_videoMode.aspectRatioCorrection && _cursorTargetScale == 1)
+ if (!_cursorDontScale && _videoMode.aspectRatioCorrection)
cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0);
#endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index f71096d43e..32fb219bcd 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -131,7 +131,7 @@ public:
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
#ifdef USE_OSD
@@ -281,7 +281,7 @@ protected:
#else
byte _mouseKeyColor;
#endif
- int _cursorTargetScale;
+ bool _cursorDontScale;
bool _cursorPaletteDisabled;
SDL_Surface *_mouseOrigSurface;
SDL_Surface *_mouseSurface;
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.cpp b/backends/graphics/wincesdl/wincesdl-graphics.cpp
index 58b735ef8b..bb79813f3b 100644
--- a/backends/graphics/wincesdl/wincesdl-graphics.cpp
+++ b/backends/graphics/wincesdl/wincesdl-graphics.cpp
@@ -1128,7 +1128,7 @@ void WINCESdlGraphicsManager::copyRectToScreen(const byte *src, int pitch, int x
SDL_UnlockSurface(_screen);
}
-void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
undrawMouse();
if (w == 0 || h == 0)
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.h b/backends/graphics/wincesdl/wincesdl-graphics.h
index 2e8c3313b3..7cff8a16d9 100644
--- a/backends/graphics/wincesdl/wincesdl-graphics.h
+++ b/backends/graphics/wincesdl/wincesdl-graphics.h
@@ -73,7 +73,7 @@ public:
void internDrawMouse();
void undrawMouse();
bool showMouse(bool visible);
- void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend
+ void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format); // overloaded by CE backend
void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME)
Graphics::Surface *lockScreen();
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index 525170d685..f133c65ed5 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -195,8 +195,8 @@ void ModularBackend::warpMouse(int x, int y) {
_graphicsManager->warpMouse(x, y);
}
-void ModularBackend::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
- _graphicsManager->setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, format);
+void ModularBackend::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
+ _graphicsManager->setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
}
void ModularBackend::setCursorPalette(const byte *colors, uint start, uint num) {
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index 072ee805b6..150c12c3c8 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -100,7 +100,7 @@ public:
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
//@}
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index 47a6515a2a..4dad1ee7ed 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -269,7 +269,7 @@ public:
virtual void warpMouse(int x, int y);
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
int hotspotY, uint32 keycolor,
- int cursorTargetScale,
+ bool dontScale,
const Graphics::PixelFormat *format);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp
index 8bc914f567..304031b4ba 100644
--- a/backends/platform/android/gfx.cpp
+++ b/backends/platform/android/gfx.cpp
@@ -687,10 +687,10 @@ bool OSystem_Android::showMouse(bool visible) {
void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
int hotspotX, int hotspotY,
- uint32 keycolor, int cursorTargetScale,
+ uint32 keycolor, bool dontScale,
const Graphics::PixelFormat *format) {
ENTER("%p, %u, %u, %d, %d, %u, %d, %p", buf, w, h, hotspotX, hotspotY,
- keycolor, cursorTargetScale, format);
+ keycolor, dontScale, format);
GLTHREADCHECK;
@@ -766,7 +766,8 @@ void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h,
}
_mouse_hotspot = Common::Point(hotspotX, hotspotY);
- _mouse_targetscale = cursorTargetScale;
+ // TODO: Adapt to the new "do not scale" cursor logic.
+ _mouse_targetscale = 1;
}
void OSystem_Android::setCursorPaletteInternal(const byte *colors,
diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h
index 8ca48bf19e..ffe003ea1d 100644
--- a/backends/platform/dc/dc.h
+++ b/backends/platform/dc/dc.h
@@ -142,7 +142,7 @@ public:
void warpMouse(int x, int y);
// Set the bitmap that's used when drawing the cursor.
- void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
+ void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
// Replace the specified range of cursor the palette with new colors.
void setCursorPalette(const byte *colors, uint start, uint num);
diff --git a/backends/platform/dc/display.cpp b/backends/platform/dc/display.cpp
index e886b55869..e4e9a94ec8 100644
--- a/backends/platform/dc/display.cpp
+++ b/backends/platform/dc/display.cpp
@@ -293,7 +293,7 @@ void OSystem_Dreamcast::warpMouse(int x, int y)
void OSystem_Dreamcast::setMouseCursor(const byte *buf, uint w, uint h,
int hotspot_x, int hotspot_y,
- uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format)
+ uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format)
{
_ms_cur_w = w;
_ms_cur_h = h;
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 73340ed18a..a6b85f207f 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -580,7 +580,7 @@ bool OSystem_DS::showMouse(bool visible) {
void OSystem_DS::warpMouse(int x, int y) {
}
-void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, int targetCursorScale, const Graphics::PixelFormat *format) {
+void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
if ((w > 0) && (w < 64) && (h > 0) && (h < 64)) {
memcpy(_cursorImage, buf, w * h);
_cursorW = w;
@@ -588,7 +588,9 @@ void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, i
_cursorHotX = hotspotX;
_cursorHotY = hotspotY;
_cursorKey = keycolor;
- _cursorScale = targetCursorScale;
+ // TODO: The old target scales was saved, but never used. Should the
+ // new "do not scale" logic be implemented?
+ //_cursorScale = targetCursorScale;
refreshCursor();
}
}
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index 6aa3731916..11b0988666 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -114,7 +114,7 @@ public:
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, int targetCursorScale, const Graphics::PixelFormat *format);
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
virtual bool pollEvent(Common::Event &event);
virtual uint32 getMillis();
diff --git a/backends/platform/iphone/osys_main.h b/backends/platform/iphone/osys_main.h
index b443e22f56..e06c7973ab 100644
--- a/backends/platform/iphone/osys_main.h
+++ b/backends/platform/iphone/osys_main.h
@@ -161,7 +161,7 @@ public:
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL);
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
virtual bool pollEvent(Common::Event &event);
diff --git a/backends/platform/iphone/osys_video.mm b/backends/platform/iphone/osys_video.mm
index c6b6e6d757..ddfa8f5030 100644
--- a/backends/platform/iphone/osys_video.mm
+++ b/backends/platform/iphone/osys_video.mm
@@ -398,8 +398,8 @@ void OSystem_IPHONE::dirtyFullOverlayScreen() {
}
}
-void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
- //printf("setMouseCursor(%p, %u, %u, %i, %i, %u, %d, %p)\n", (const void *)buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, (const void *)format);
+void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
+ //printf("setMouseCursor(%p, %u, %u, %i, %i, %u, %d, %p)\n", (const void *)buf, w, h, hotspotX, hotspotY, keycolor, dontScale, (const void *)format);
const Graphics::PixelFormat pixelFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();
#if 0
diff --git a/backends/platform/n64/osys_n64.h b/backends/platform/n64/osys_n64.h
index 4788beb1ca..b8519eeea6 100644
--- a/backends/platform/n64/osys_n64.h
+++ b/backends/platform/n64/osys_n64.h
@@ -182,7 +182,7 @@ public:
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
virtual void setCursorPalette(const byte *colors, uint start, uint num);
virtual bool pollEvent(Common::Event &event);
diff --git a/backends/platform/n64/osys_n64_base.cpp b/backends/platform/n64/osys_n64_base.cpp
index c3adb9691c..f36f7399e1 100644
--- a/backends/platform/n64/osys_n64_base.cpp
+++ b/backends/platform/n64/osys_n64_base.cpp
@@ -773,7 +773,7 @@ void OSystem_N64::warpMouse(int x, int y) {
_dirtyOffscreen = true;
}
-void OSystem_N64::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+void OSystem_N64::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
if (!w || !h) return;
_mouseHotspotX = hotspotX;
diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp
index d4e993da63..668ac93a07 100644
--- a/backends/platform/ps2/systemps2.cpp
+++ b/backends/platform/ps2/systemps2.cpp
@@ -618,7 +618,7 @@ void OSystem_PS2::warpMouse(int x, int y) {
_screen->setMouseXy(x, y);
}
-void OSystem_PS2::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+void OSystem_PS2::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
_screen->setMouseOverlay(buf, w, h, hotspot_x, hotspot_y, keycolor);
}
diff --git a/backends/platform/ps2/systemps2.h b/backends/platform/ps2/systemps2.h
index 3a0e247737..7bbe061e42 100644
--- a/backends/platform/ps2/systemps2.h
+++ b/backends/platform/ps2/systemps2.h
@@ -80,7 +80,7 @@ public:
virtual bool showMouse(bool visible);
virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = 0);
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = 0);
virtual uint32 getMillis();
virtual void delayMillis(uint msecs);
diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp
index 5fa5110684..958a3a22c6 100644
--- a/backends/platform/psp/osys_psp.cpp
+++ b/backends/platform/psp/osys_psp.cpp
@@ -303,7 +303,7 @@ void OSystem_PSP::warpMouse(int x, int y) {
_cursor.setXY(x, y);
}
-void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
+void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
DEBUG_ENTER_FUNC();
_displayManager.waitUntilRenderFinished();
_pendingUpdate = false;
@@ -314,7 +314,9 @@ void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
}
_cursor.setKeyColor(keycolor);
- _cursor.setCursorTargetScale(cursorTargetScale);
+ // TODO: The old target scale was saved but never used. Should the new
+ // "do not scale" logic be implemented?
+ //_cursor.setCursorTargetScale(cursorTargetScale);
_cursor.setSizeAndScummvmPixelFormat(w, h, format);
_cursor.setHotspot(hotspotX, hotspotY);
_cursor.clearKeyColor();
diff --git a/backends/platform/psp/osys_psp.h b/backends/platform/psp/osys_psp.h
index e6b445e232..c72053f52c 100644
--- a/backends/platform/psp/osys_psp.h
+++ b/backends/platform/psp/osys_psp.h
@@ -118,7 +118,7 @@ public:
// Mouse related
bool showMouse(bool visible);
void warpMouse(int x, int y);
- void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
+ void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
// Events and input
bool pollEvent(Common::Event &event);
diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h
index 64197f913a..b6784d59e4 100644
--- a/backends/platform/wii/osystem.h
+++ b/backends/platform/wii/osystem.h
@@ -189,7 +189,7 @@ public:
virtual void warpMouse(int x, int y);
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
int hotspotY, uint32 keycolor,
- int cursorTargetScale,
+ bool dontScale,
const Graphics::PixelFormat *format);
virtual bool pollEvent(Common::Event &event);
diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp
index 83607984cc..a00cea8252 100644
--- a/backends/platform/wii/osystem_gfx.cpp
+++ b/backends/platform/wii/osystem_gfx.cpp
@@ -644,7 +644,7 @@ void OSystem_Wii::warpMouse(int x, int y) {
void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
int hotspotY, uint32 keycolor,
- int cursorTargetScale,
+ bool dontScale,
const Graphics::PixelFormat *format) {
gfx_tex_format_t tex_format = GFX_TF_PALETTE_RGB5A3;
uint tw, th;
@@ -742,7 +742,8 @@ void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX,
_mouseHotspotX = hotspotX;
_mouseHotspotY = hotspotY;
- _cursorScale = cursorTargetScale;
+ // TODO: Adapt to new dontScale logic!
+ _cursorScale = 1;
if ((_texMouse.palette) && (oldKeycolor != _mouseKeyColor))
_cursorPaletteDirty = true;
diff --git a/common/coroutines.cpp b/common/coroutines.cpp
index 6159bdc0f3..241d31e0d7 100644
--- a/common/coroutines.cpp
+++ b/common/coroutines.cpp
@@ -34,7 +34,6 @@ CoroContext nullContext = NULL;
DECLARE_SINGLETON(CoroutineScheduler);
-
#ifdef COROUTINE_DEBUG
namespace {
/** Count of active coroutines */
@@ -63,18 +62,15 @@ static void displayCoroStats() {
if (!s_coroFuncs)
return;
for (CoroHashMap::const_iterator it = s_coroFuncs->begin();
- it != s_coroFuncs->end(); ++it) {
+ it != s_coroFuncs->end(); ++it) {
if (it->_value != 0)
debug(" %3d x %s", it->_value, it->_key.c_str());
}
}
-}
+} // End of anonymous namespace
#endif
-/**
- * Creates a coroutine context
- */
CoroBaseContext::CoroBaseContext(const char *func)
: _line(0), _sleep(0), _subctx(0) {
#ifdef COROUTINE_DEBUG
@@ -84,15 +80,12 @@ CoroBaseContext::CoroBaseContext(const char *func)
#endif
}
-/**
- * Destructor for coroutine context
- */
CoroBaseContext::~CoroBaseContext() {
#ifdef COROUTINE_DEBUG
s_coroCount--;
changeCoroStats(_funcName, -1);
debug("Deleting coro in %s at %p (subctx %p)",
- _funcName, (void *)this, (void *)_subctx);
+ _funcName, (void *)this, (void *)_subctx);
displayCoroStats();
#endif
delete _subctx;
@@ -100,9 +93,6 @@ CoroBaseContext::~CoroBaseContext() {
//--------------------- Scheduler Class ------------------------
-/**
- * Constructor
- */
CoroutineScheduler::CoroutineScheduler() {
processList = NULL;
pFreeProcesses = NULL;
@@ -124,9 +114,6 @@ CoroutineScheduler::CoroutineScheduler() {
reset();
}
-/**
- * Destructor
- */
CoroutineScheduler::~CoroutineScheduler() {
// Kill all running processes (i.e. free memory allocated for their state).
PROCESS *pProc = active->pNext;
@@ -145,14 +132,10 @@ CoroutineScheduler::~CoroutineScheduler() {
// Clear the event list
Common::List<EVENT *>::iterator i;
for (i = _events.begin(); i != _events.end(); ++i)
- delete (*i);
+ delete *i;
}
-/**
- * Kills all processes and places them on the free list.
- */
void CoroutineScheduler::reset() {
-
#ifdef DEBUG
// clear number of process in use
numProcs = 0;
@@ -194,21 +177,14 @@ void CoroutineScheduler::reset() {
}
-#ifdef DEBUG
-/**
- * Shows the maximum number of process used at once.
- */
+#ifdef DEBUG
void CoroutineScheduler::printStats() {
debug("%i process of %i used", maxProcs, CORO_NUM_PROCESS);
}
#endif
#ifdef DEBUG
-/**
- * Checks both the active and free process list to insure all the links are valid,
- * and that no processes have been lost
- */
-void CoroutineScheduler::CheckStack() {
+void CoroutineScheduler::checkStack() {
Common::List<PROCESS *> pList;
// Check both the active and free process lists
@@ -242,9 +218,6 @@ void CoroutineScheduler::CheckStack() {
}
#endif
-/**
- * Give all active processes a chance to run
- */
void CoroutineScheduler::schedule() {
// start dispatching active process list
PROCESS *pNext;
@@ -274,9 +247,6 @@ void CoroutineScheduler::schedule() {
}
}
-/**
- * Reschedules all the processes to run again this query
- */
void CoroutineScheduler::rescheduleAll() {
assert(pCurrent);
@@ -292,10 +262,6 @@ void CoroutineScheduler::rescheduleAll() {
pCurrent->pPrevious = active;
}
-/**
- * If the specified process has already run on this tick, make it run
- * again on the current tick.
- */
void CoroutineScheduler::reschedule(PPROCESS pReSchedProc) {
// If not currently processing the schedule list, then no action is needed
if (!pCurrent)
@@ -333,11 +299,6 @@ void CoroutineScheduler::reschedule(PPROCESS pReSchedProc) {
pReSchedProc->pNext = NULL;
}
-/**
- * Moves the specified process to the end of the dispatch queue
- * allowing it to run again within the current game cycle.
- * @param pGiveProc Which process
- */
void CoroutineScheduler::giveWay(PPROCESS pReSchedProc) {
// If not currently processing the schedule list, then no action is needed
if (!pCurrent)
@@ -371,13 +332,6 @@ void CoroutineScheduler::giveWay(PPROCESS pReSchedProc) {
pReSchedProc->pNext = NULL;
}
-/**
- * Continously makes a given process wait for another process to finish or event to signal.
- *
- * @param pid Process/Event identifier
- * @param duration Duration in milliseconds
- * @param expired If specified, set to true if delay period expired
- */
void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired) {
if (!pCurrent)
error("Called CoroutineScheduler::waitForSingleObject from the main process");
@@ -398,7 +352,7 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio
// Presume it will expire
*expired = true;
- // Outer loop for doing checks until expiry
+ // Outer loop for doing checks until expiry
while (g_system->getMillis() <= _ctx->endTime) {
// Check to see if a process or event with the given Id exists
_ctx->pProcess = getProcess(pid);
@@ -412,7 +366,7 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio
break;
}
- // If a process was found, don't go into the if statement, and keep waiting.
+ // If a process was found, don't go into the if statement, and keep waiting.
// Likewise if it's an event that's not yet signalled
if ((_ctx->pEvent != NULL) && _ctx->pEvent->signalled) {
// Unless the event is flagged for manual reset, reset it now
@@ -434,17 +388,8 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio
CORO_END_CODE;
}
-/**
- * Continously makes a given process wait for given prcesses to finished or events to be set
- *
- * @param nCount Number of Id's being passed
- * @param evtList List of pids to wait for
- * @param bWaitAll Specifies whether all or any of the processes/events
- * @param duration Duration in milliseconds
- * @param expired Set to true if delay period expired
- */
-void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll,
- uint32 duration, bool *expired) {
+void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll,
+ uint32 duration, bool *expired) {
if (!pCurrent)
error("Called CoroutineScheduler::waitForMultipleObjects from the main process");
@@ -468,7 +413,7 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *
// Presume that delay will expire
*expired = true;
- // Outer loop for doing checks until expiry
+ // Outer loop for doing checks until expiry
while (g_system->getMillis() <= _ctx->endTime) {
_ctx->signalled = bWaitAll;
@@ -510,12 +455,6 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *
CORO_END_CODE;
}
-/**
- * Make the active process sleep for the given duration in milliseconds
- * @param duration Duration in milliseconds
- * @remarks This duration won't be precise, since it relies on the frequency the
- * scheduler is called.
- */
void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) {
if (!pCurrent)
error("Called CoroutineScheduler::sleep from the main process");
@@ -530,7 +469,7 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) {
_ctx->endTime = g_system->getMillis() + duration;
- // Outer loop for doing checks until expiry
+ // Outer loop for doing checks until expiry
while (g_system->getMillis() < _ctx->endTime) {
// Sleep until the next cycle
CORO_SLEEP(1);
@@ -539,14 +478,6 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) {
CORO_END_CODE;
}
-/**
- * Creates a new process.
- *
- * @param pid process identifier
- * @param coroAddr Coroutine start address
- * @param pParam Process specific info
- * @param sizeParam Size of process specific info
- */
PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam) {
PROCESS *pProc;
@@ -577,7 +508,7 @@ PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const
pCurrent->pNext = pProc;
pProc->pPrevious = pCurrent;
- } else { // no active processes, place process at head of list
+ } else { // no active processes, place process at head of list
pProc->pNext = active->pNext;
pProc->pPrevious = active;
@@ -611,35 +542,15 @@ PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const
return pProc;
}
-/**
- * Creates a new process with an auto-incrementing Process Id.
- *
- * @param coroAddr Coroutine start address
- * @param pParam Process specific info
- * @param sizeParam Size of process specific info
- */
uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam) {
PROCESS *pProc = createProcess(++pidCounter, coroAddr, pParam, sizeParam);
return pProc->pid;
}
-/**
- * Creates a new process with an auto-incrementing Process Id, and a single pointer parameter.
- *
- * @param coroAddr Coroutine start address
- * @param pParam Process specific info
- * @param sizeParam Size of process specific info
- */
uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam) {
return createProcess(coroAddr, &pParam, sizeof(void *));
}
-
-/**
- * Kills the specified process.
- *
- * @param pKillProc Which process to kill
- */
void CoroutineScheduler::killProcess(PROCESS *pKillProc) {
// make sure a valid process pointer
assert(pKillProc >= processList && pKillProc <= processList + CORO_NUM_PROCESS - 1);
@@ -675,20 +586,10 @@ void CoroutineScheduler::killProcess(PROCESS *pKillProc) {
pFreeProcesses = pKillProc;
}
-
-
-/**
- * Returns a pointer to the currently running process.
- */
PROCESS *CoroutineScheduler::getCurrentProcess() {
return pCurrent;
}
-/**
- * Returns the process identifier of the specified process.
- *
- * @param pProc Which process
- */
int CoroutineScheduler::getCurrentPID() const {
PROCESS *pProc = pCurrent;
@@ -699,17 +600,9 @@ int CoroutineScheduler::getCurrentPID() const {
return pProc->pid;
}
-/**
- * Kills any process matching the specified PID. The current
- * process cannot be killed.
- *
- * @param pidKill Process identifier of process to kill
- * @param pidMask Mask to apply to process identifiers before comparison
- * @return The number of processes killed is returned.
- */
int CoroutineScheduler::killMatchingProcess(uint32 pidKill, int pidMask) {
int numKilled = 0;
- PROCESS *pProc, *pPrev; // process list pointers
+ PROCESS *pProc, *pPrev; // process list pointers
for (pProc = active->pNext, pPrev = active; pProc != NULL; pPrev = pProc, pProc = pProc->pNext) {
if ((pProc->pid & (uint32)pidMask) == pidKill) {
@@ -756,15 +649,6 @@ int CoroutineScheduler::killMatchingProcess(uint32 pidKill, int pidMask) {
return numKilled;
}
-/**
- * Set pointer to a function to be called by killProcess().
- *
- * May be called by a resource allocator, the function supplied is
- * called by killProcess() to allow the resource allocator to free
- * resources allocated to the dying process.
- *
- * @param pFunc Function to be called by killProcess()
- */
void CoroutineScheduler::setResourceCallback(VFPTRPP pFunc) {
pRCfunction = pFunc;
}
@@ -789,12 +673,6 @@ EVENT *CoroutineScheduler::getEvent(uint32 pid) {
}
-/**
- * Creates a new event object
- * @param bManualReset Events needs to be manually reset. Otherwise, events
- * will be automatically reset after a process waits on the event finishes
- * @param bInitialState Specifies whether the event is signalled or not initially
- */
uint32 CoroutineScheduler::createEvent(bool bManualReset, bool bInitialState) {
EVENT *evt = new EVENT();
evt->pid = ++pidCounter;
@@ -805,10 +683,6 @@ uint32 CoroutineScheduler::createEvent(bool bManualReset, bool bInitialState) {
return evt->pid;
}
-/**
- * Destroys the given event
- * @param pidEvent Event Process Id
- */
void CoroutineScheduler::closeEvent(uint32 pidEvent) {
EVENT *evt = getEvent(pidEvent);
if (evt) {
@@ -817,41 +691,26 @@ void CoroutineScheduler::closeEvent(uint32 pidEvent) {
}
}
-/**
- * Sets the event
- * @param pidEvent Event Process Id
- */
void CoroutineScheduler::setEvent(uint32 pidEvent) {
EVENT *evt = getEvent(pidEvent);
if (evt)
evt->signalled = true;
}
-/**
- * Resets the event
- * @param pidEvent Event Process Id
- */
void CoroutineScheduler::resetEvent(uint32 pidEvent) {
EVENT *evt = getEvent(pidEvent);
if (evt)
evt->signalled = false;
}
-/**
- * Temporarily sets a given event to true, and then runs all waiting processes, allowing any
- * processes waiting on the event to be fired. It then immediately resets the event again.
- * @param pidEvent Event Process Id
- *
- * @remarks Should not be run inside of another process
- */
void CoroutineScheduler::pulseEvent(uint32 pidEvent) {
EVENT *evt = getEvent(pidEvent);
if (!evt)
return;
-
+
// Set the event as true
evt->signalled = true;
-
+
// start dispatching active process list for any processes that are currently waiting
PROCESS *pOriginal = pCurrent;
PROCESS *pNext;
diff --git a/common/coroutines.h b/common/coroutines.h
index abc114e0cf..64eabbf8f4 100644
--- a/common/coroutines.h
+++ b/common/coroutines.h
@@ -23,7 +23,7 @@
#define COMMON_COROUTINES_H
#include "common/scummsys.h"
-#include "common/util.h" // for SCUMMVM_CURRENT_FUNCTION
+#include "common/util.h" // for SCUMMVM_CURRENT_FUNCTION
#include "common/list.h"
#include "common/singleton.h"
@@ -56,7 +56,14 @@ struct CoroBaseContext {
#ifdef COROUTINE_DEBUG
const char *_funcName;
#endif
+ /**
+ * Creates a coroutine context
+ */
CoroBaseContext(const char *func);
+
+ /**
+ * Destructor for coroutine context
+ */
virtual ~CoroBaseContext();
};
@@ -126,42 +133,43 @@ public:
/**
* End the declaration of a coroutine context.
- * @param x name of the coroutine context
+ * @param x name of the coroutine context
* @see CORO_BEGIN_CONTEXT
*/
#define CORO_END_CONTEXT(x) } *x = (CoroContextTag *)coroParam
/**
* Begin the code section of a coroutine.
- * @param x name of the coroutine context
+ * @param x name of the coroutine context
* @see CORO_BEGIN_CODE
*/
#define CORO_BEGIN_CODE(x) \
- if (&coroParam == &Common::nullContext) assert(!Common::nullContext);\
- if (!x) {coroParam = x = new CoroContextTag();}\
- Common::CoroContextHolder tmpHolder(coroParam);\
- switch (coroParam->_line) { case 0:;
+ if (&coroParam == &Common::nullContext) assert(!Common::nullContext); \
+ if (!x) { coroParam = x = new CoroContextTag(); } \
+ Common::CoroContextHolder tmpHolder(coroParam); \
+ switch (coroParam->_line) { case 0:;
/**
* End the code section of a coroutine.
* @see CORO_END_CODE
*/
#define CORO_END_CODE \
- if (&coroParam == &Common::nullContext) { \
- delete Common::nullContext; \
- Common::nullContext = NULL; \
- } \
- }
+ if (&coroParam == &Common::nullContext) { \
+ delete Common::nullContext; \
+ Common::nullContext = NULL; \
+ } \
+ }
/**
* Sleep for the specified number of scheduler cycles.
*/
-#define CORO_SLEEP(delay) do {\
- coroParam->_line = __LINE__;\
- coroParam->_sleep = delay;\
- assert(&coroParam != &Common::nullContext);\
- return; case __LINE__:;\
- } while (0)
+#define CORO_SLEEP(delay) \
+ do { \
+ coroParam->_line = __LINE__; \
+ coroParam->_sleep = delay; \
+ assert(&coroParam != &Common::nullContext); \
+ return; case __LINE__:; \
+ } while (0)
#define CORO_GIVE_WAY do { CoroScheduler.giveWay(); CORO_SLEEP(1); } while (0)
#define CORO_RESCHEDULE do { CoroScheduler.reschedule(); CORO_SLEEP(1); } while (0)
@@ -175,7 +183,7 @@ public:
* then delete the entire coroutine's state, including all subcontexts).
*/
#define CORO_KILL_SELF() \
- do { if (&coroParam != &Common::nullContext) { coroParam->_sleep = -1; } return; } while (0)
+ do { if (&coroParam != &Common::nullContext) { coroParam->_sleep = -1; } return; } while (0)
/**
@@ -194,8 +202,8 @@ public:
* If the subcontext is null, the coroutine ended normally, and we can
* simply break out of the loop and continue execution.
*
- * @param subCoro name of the coroutine-enabled function to invoke
- * @param ARGS list of arguments to pass to subCoro
+ * @param subCoro name of the coroutine-enabled function to invoke
+ * @param ARGS list of arguments to pass to subCoro
*
* @note ARGS must be surrounded by parentheses, and the first argument
* in this list must always be CORO_SUBCTX. For example, the
@@ -204,18 +212,18 @@ public:
* becomes the following:
* CORO_INVOKE_ARGS(myFunc, (CORO_SUBCTX, a, b));
*/
-#define CORO_INVOKE_ARGS(subCoro, ARGS) \
- do {\
- coroParam->_line = __LINE__;\
- coroParam->_subctx = 0;\
- do {\
- subCoro ARGS;\
- if (!coroParam->_subctx) break;\
- coroParam->_sleep = coroParam->_subctx->_sleep;\
- assert(&coroParam != &Common::nullContext);\
- return; case __LINE__:;\
- } while (1);\
- } while (0)
+#define CORO_INVOKE_ARGS(subCoro, ARGS) \
+ do { \
+ coroParam->_line = __LINE__; \
+ coroParam->_subctx = 0; \
+ do { \
+ subCoro ARGS; \
+ if (!coroParam->_subctx) break; \
+ coroParam->_sleep = coroParam->_subctx->_sleep; \
+ assert(&coroParam != &Common::nullContext); \
+ return; case __LINE__:; \
+ } while (1); \
+ } while (0)
/**
* Invoke another coroutine. Similar to CORO_INVOKE_ARGS,
@@ -223,62 +231,62 @@ public:
* if invoked coroutine yields (thus causing the current
* coroutine to yield, too).
*/
-#define CORO_INVOKE_ARGS_V(subCoro, RESULT, ARGS) \
- do {\
- coroParam->_line = __LINE__;\
- coroParam->_subctx = 0;\
- do {\
- subCoro ARGS;\
- if (!coroParam->_subctx) break;\
- coroParam->_sleep = coroParam->_subctx->_sleep;\
- assert(&coroParam != &Common::nullContext);\
- return RESULT; case __LINE__:;\
- } while (1);\
- } while (0)
+#define CORO_INVOKE_ARGS_V(subCoro, RESULT, ARGS) \
+ do { \
+ coroParam->_line = __LINE__; \
+ coroParam->_subctx = 0; \
+ do { \
+ subCoro ARGS; \
+ if (!coroParam->_subctx) break; \
+ coroParam->_sleep = coroParam->_subctx->_sleep; \
+ assert(&coroParam != &Common::nullContext); \
+ return RESULT; case __LINE__:; \
+ } while (1); \
+ } while (0)
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with no parameters.
*/
#define CORO_INVOKE_0(subCoroutine) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX))
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with one parameter.
*/
#define CORO_INVOKE_1(subCoroutine, a0) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0))
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with two parameters.
*/
#define CORO_INVOKE_2(subCoroutine, a0,a1) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1))
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with three parameters.
*/
#define CORO_INVOKE_3(subCoroutine, a0,a1,a2) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1,a2))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1, a2))
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with four parameters.
*/
#define CORO_INVOKE_4(subCoroutine, a0,a1,a2,a3) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1,a2,a3))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1, a2, a3))
// the size of process specific info
-#define CORO_PARAM_SIZE 32
+#define CORO_PARAM_SIZE 32
// the maximum number of processes
-#define CORO_NUM_PROCESS 100
-#define CORO_MAX_PROCESSES 100
+#define CORO_NUM_PROCESS 100
+#define CORO_MAX_PROCESSES 100
#define CORO_MAX_PID_WAITING 5
#define CORO_INFINITE 0xffffffff
@@ -289,16 +297,16 @@ typedef void (*CORO_ADDR)(CoroContext &, const void *);
/** process structure */
struct PROCESS {
- PROCESS *pNext; ///< pointer to next process in active or free list
- PROCESS *pPrevious; ///< pointer to previous process in active or free list
+ PROCESS *pNext; ///< pointer to next process in active or free list
+ PROCESS *pPrevious; ///< pointer to previous process in active or free list
- CoroContext state; ///< the state of the coroutine
- CORO_ADDR coroAddr; ///< the entry point of the coroutine
+ CoroContext state; ///< the state of the coroutine
+ CORO_ADDR coroAddr; ///< the entry point of the coroutine
- int sleepTime; ///< number of scheduler cycles to sleep
- uint32 pid; ///< process ID
- uint32 pidWaiting[CORO_MAX_PID_WAITING]; ///< Process ID(s) process is currently waiting on
- char param[CORO_PARAM_SIZE]; ///< process specific info
+ int sleepTime; ///< number of scheduler cycles to sleep
+ uint32 pid; ///< process ID
+ uint32 pidWaiting[CORO_MAX_PID_WAITING]; ///< Process ID(s) process is currently waiting on
+ char param[CORO_PARAM_SIZE]; ///< process specific info
};
typedef PROCESS *PPROCESS;
@@ -314,12 +322,24 @@ struct EVENT {
/**
* Creates and manages "processes" (really coroutines).
*/
-class CoroutineScheduler: public Singleton<CoroutineScheduler> {
+class CoroutineScheduler : public Singleton<CoroutineScheduler> {
public:
/** Pointer to a function of the form "void function(PPROCESS)" */
typedef void (*VFPTRPP)(PROCESS *);
private:
+ friend class Singleton<CoroutineScheduler>;
+
+ /**
+ * Constructor
+ */
+ CoroutineScheduler();
+
+ /**
+ * Destructor
+ */
+ ~CoroutineScheduler();
+
/** list of all processes */
PROCESS *processList;
@@ -344,7 +364,11 @@ private:
int numProcs;
int maxProcs;
- void CheckStack();
+ /**
+ * Checks both the active and free process list to insure all the links are valid,
+ * and that no processes have been lost
+ */
+ void checkStack();
#endif
/**
@@ -356,71 +380,175 @@ private:
PROCESS *getProcess(uint32 pid);
EVENT *getEvent(uint32 pid);
public:
- CoroutineScheduler();
- ~CoroutineScheduler();
-
+ /**
+ * Kills all processes and places them on the free list.
+ */
void reset();
- #ifdef DEBUG
+#ifdef DEBUG
+ /**
+ * Shows the maximum number of process used at once.
+ */
void printStats();
- #endif
+#endif
- /** Give all active processes a chance to run */
+ /**
+ * Give all active processes a chance to run
+ */
void schedule();
- /** Reschedules all the processes to run again this tick */
+ /**
+ * Reschedules all the processes to run again this tick
+ */
void rescheduleAll();
- /** If the specified process has already run on this tick, make it run again on the current tick. */
+ /**
+ * If the specified process has already run on this tick, make it run
+ * again on the current tick.
+ */
void reschedule(PPROCESS pReSchedProc = NULL);
- /** Moves the specified process to the end of the dispatch queue, so it can again in the current tick */
+ /**
+ * Moves the specified process to the end of the dispatch queue
+ * allowing it to run again within the current game cycle.
+ * @param pGiveProc Which process
+ */
void giveWay(PPROCESS pReSchedProc = NULL);
- /** Continously makes a given process wait for another process to finish or event to signal. */
+ /**
+ * Continously makes a given process wait for another process to finish or event to signal.
+ *
+ * @param pid Process/Event identifier
+ * @param duration Duration in milliseconds
+ * @param expired If specified, set to true if delay period expired
+ */
void waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired = NULL);
- /** Continously makes a given process wait for given prcesses to finished or events to be set */
- void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll,
- uint32 duration, bool *expired = NULL);
+ /**
+ * Continously makes a given process wait for given prcesses to finished or events to be set
+ *
+ * @param nCount Number of Id's being passed
+ * @param evtList List of pids to wait for
+ * @param bWaitAll Specifies whether all or any of the processes/events
+ * @param duration Duration in milliseconds
+ * @param expired Set to true if delay period expired
+ */
+ void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll,
+ uint32 duration, bool *expired = NULL);
- /** Make the active process sleep for the given duration in milliseconds */
+ /**
+ * Make the active process sleep for the given duration in milliseconds
+ *
+ * @param duration Duration in milliseconds
+ * @remarks This duration won't be precise, since it relies on the frequency the
+ * scheduler is called.
+ */
void sleep(CORO_PARAM, uint32 duration);
-
- /** Creates a new process. */
+
+ /**
+ * Creates a new process.
+ *
+ * @param pid process identifier
+ * @param coroAddr Coroutine start address
+ * @param pParam Process specific info
+ * @param sizeParam Size of process specific info
+ */
PROCESS *createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam);
+
+ /**
+ * Creates a new process with an auto-incrementing Process Id.
+ *
+ * @param coroAddr Coroutine start address
+ * @param pParam Process specific info
+ * @param sizeParam Size of process specific info
+ */
uint32 createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam);
+
+ /**
+ * Creates a new process with an auto-incrementing Process Id, and a single pointer parameter.
+ *
+ * @param coroAddr Coroutine start address
+ * @param pParam Process specific info
+ */
uint32 createProcess(CORO_ADDR coroAddr, const void *pParam);
- /** Kills the specified process. */
+ /**
+ * Kills the specified process.
+ *
+ * @param pKillProc Which process to kill
+ */
void killProcess(PROCESS *pKillProc);
- /** Returns a pointer to the currently running process. */
+ /**
+ * Returns a pointer to the currently running process.
+ */
PROCESS *getCurrentProcess();
- /** Returns the process identifier of the specified process. */
+ /**
+ * Returns the process identifier of the currently running process.
+ */
int getCurrentPID() const;
- /** Kills any process matching the specified PID. The current process cannot be killed. */
+ /**
+ * Kills any process matching the specified PID. The current
+ * process cannot be killed.
+ *
+ * @param pidKill Process identifier of process to kill
+ * @param pidMask Mask to apply to process identifiers before comparison
+ * @return The number of processes killed is returned.
+ */
int killMatchingProcess(uint32 pidKill, int pidMask = -1);
- /** Set pointer to a function to be called by killProcess() */
+ /**
+ * Set pointer to a function to be called by killProcess().
+ *
+ * May be called by a resource allocator, the function supplied is
+ * called by killProcess() to allow the resource allocator to free
+ * resources allocated to the dying process.
+ *
+ * @param pFunc Function to be called by killProcess()
+ */
void setResourceCallback(VFPTRPP pFunc);
/* Event methods */
- /** Creates a new event (semaphore) object */
+ /**
+ * Creates a new event (semaphore) object
+ *
+ * @param bManualReset Events needs to be manually reset. Otherwise,
+ * events will be automatically reset after a
+ * process waits on the event finishes
+ * @param bInitialState Specifies whether the event is signalled or not
+ * initially
+ */
uint32 createEvent(bool bManualReset, bool bInitialState);
- /** Destroys the given event */
+ /**
+ * Destroys the given event
+ * @param pidEvent Event Process Id
+ */
void closeEvent(uint32 pidEvent);
- /** Sets the event */
+ /**
+ * Sets the event
+ * @param pidEvent Event Process Id
+ */
void setEvent(uint32 pidEvent);
- /** Resets the event */
+ /**
+ * Resets the event
+ * @param pidEvent Event Process Id
+ */
void resetEvent(uint32 pidEvent);
- /** Temporarily sets a given event to true, allowing other waiting processes to fire */
+ /**
+ * Temporarily sets a given event to true, and then runs all waiting
+ * processes,allowing any processes waiting on the event to be fired. It
+ * then immediately resets the event again.
+ *
+ * @param pidEvent Event Process Id
+ *
+ * @remarks Should not be run inside of another process
+ */
void pulseEvent(uint32 pidEvent);
};
@@ -428,4 +556,4 @@ public:
} // end of namespace Common
-#endif // COMMON_COROUTINES_H
+#endif // COMMON_COROUTINES_H
diff --git a/common/system.h b/common/system.h
index dc74533861..94bf7f01eb 100644
--- a/common/system.h
+++ b/common/system.h
@@ -380,33 +380,22 @@ public:
*
*
* The next layer is the overlay. It is composed over the game
- * graphics. By default, it has exactly the same size and
- * resolution as the game graphics. However, client code can
- * specify an overlay scale (as an additional parameter to
- * initSize()). This is meant to increase the resolution of the
- * overlay while keeping its size the same as that of the game
- * graphics. For example, if the overlay scale is 2, and the game
- * graphics have a resolution of 320x200; then the overlay shall
- * have a resolution of 640x400, but it still has the same
- * physical size as the game graphics.
- * The overlay usually uses 16bpp, but on some ports, only 8bpp
- * are availble, so that is supported, too, via a compile time
- * switch (see also the OverlayColor typedef in scummsys.h).
- *
+ * graphics. Historically the overlay size had always been a
+ * multiple of the game resolution, for example when the game
+ * resolution was 320x200 and the user selected a 2x scaler and did
+ * not enable aspect ratio correction it had a size of 640x400.
+ * An exception was the aspect ratio correction, which did allow
+ * for non multiples of the vertical resolution of the game screen.
+ * Nowadays the overlay size does not need to have any relation to
+ * the game resolution though, for example the overlay resolution
+ * might be the same as the physical screen resolution.
+ * The overlay is forced to a 16bpp mode right now.
*
* Finally, there is the mouse layer. This layer doesn't have to
* actually exist within the backend -- it all depends on how a
* backend chooses to implement mouse cursors, but in the default
* SDL backend, it really is a separate layer. The mouse can
* have a palette of its own, if the backend supports it.
- * The scale of the mouse cursor is called 'cursorTargetScale'.
- * This is meant as a hint to the backend. For example, let us
- * assume the overlay is not visible, and the game graphics are
- * displayed using a 2x scaler. If a mouse cursor with a
- * cursorTargetScale of 1 is set, then it should be scaled by
- * factor 2x, too, just like the game graphics. But if it has a
- * cursorTargetScale of 2, then it shouldn't be scaled again by
- * the game graphics scaler.
*
* On a note for OSystem users here. We do not require our graphics
* to be thread safe and in fact most/all backends using OpenGL are
@@ -758,13 +747,11 @@ public:
* In order to be able to display dialogs atop the game graphics, backends
* must provide an overlay mode.
*
- * The overlay can be 8 or 16 bpp. Depending on which it is, OverlayColor
- * is 8 or 16 bit.
+ * The overlay is currently forced at 16 bpp.
*
* For 'coolness' we usually want to have an overlay which is blended over
* the game graphics. On backends which support alpha blending, this is
- * no issue; but on other systems (in particular those which only support
- * 8bpp), this needs some trickery.
+ * no issue; but on other systems this needs some trickery.
*
* Essentially, we fake (alpha) blending on these systems by copying the
* current game graphics into the overlay buffer when activating the overlay,
@@ -883,10 +870,11 @@ public:
* @param keycolor transparency color value. This should not exceed the maximum color value of the specified format.
* In case it does the behavior is undefined. The backend might just error out or simply ignore the
* value. (The SDL backend will just assert to prevent abuse of this).
- * @param cursorTargetScale scale factor which cursor is designed for
+ * @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor
+ * would be too small to notice otherwise, these are allowed to scale the cursor anyway.
* @param format pointer to the pixel format which cursor graphic uses (0 means CLUT8)
*/
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0;
+ virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) = 0;
/**
* Replace the specified range of cursor the palette with new colors.
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index d58e55a6b9..3e63da756d 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -795,38 +795,26 @@ int AgiEngine::selectSlot() {
}
int AgiEngine::scummVMSaveLoadDialog(bool isSave) {
- const EnginePlugin *plugin = NULL;
- EngineMan.findGame(ConfMan.get("gameid"), &plugin);
GUI::SaveLoadChooser *dialog;
Common::String desc;
int slot;
if (isSave) {
- dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"));
- dialog->setSaveMode(true);
+ dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
- slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ slot = dialog->runModalWithCurrentTarget();
desc = dialog->getResultString();
if (desc.empty()) {
// create our own description for the saved game, the user didnt enter it
-#if defined(USE_SAVEGAME_TIMESTAMP)
- TimeDate curTime;
- g_system->getTimeAndDate(curTime);
- curTime.tm_year += 1900; // fixup year
- curTime.tm_mon++; // fixup month
- desc = Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec);
-#else
- desc = Common::String::format("Save %d", slot + 1);
-#endif
+ desc = dialog->createDefaultSaveDescription(slot);
}
if (desc.size() > 28)
desc = Common::String(desc.c_str(), 28);
} else {
- dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"));
- dialog->setSaveMode(false);
- slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
+ slot = dialog->runModalWithCurrentTarget();
}
delete dialog;
diff --git a/engines/cge/events.cpp b/engines/cge/events.cpp
index 3c561c5659..095aac2412 100644
--- a/engines/cge/events.cpp
+++ b/engines/cge/events.cpp
@@ -70,12 +70,8 @@ bool Keyboard::getKey(Common::Event &event) {
return false;
case Common::KEYCODE_F5:
if (_vm->canSaveGameStateCurrently()) {
- const EnginePlugin *plugin = NULL;
- EngineMan.findGame(_vm->_gameDescription->gameid, &plugin);
-
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save");
- dialog->setSaveMode(true);
- int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true);
+ int16 savegameId = dialog->runModalWithCurrentTarget();
Common::String savegameDescription = dialog->getResultString();
delete dialog;
@@ -85,12 +81,8 @@ bool Keyboard::getKey(Common::Event &event) {
return false;
case Common::KEYCODE_F7:
if (_vm->canLoadGameStateCurrently()) {
- const EnginePlugin *plugin = NULL;
- EngineMan.findGame(_vm->_gameDescription->gameid, &plugin);
-
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore");
- dialog->setSaveMode(false);
- int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false);
+ int16 savegameId = dialog->runModalWithCurrentTarget();
delete dialog;
if (savegameId != -1)
diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp
index e763e2b8a1..512259f7d7 100644
--- a/engines/cruise/menu.cpp
+++ b/engines/cruise/menu.cpp
@@ -207,16 +207,13 @@ int processMenu(menuStruct *pMenu) {
}
static void handleSaveLoad(bool saveFlag) {
- const EnginePlugin *plugin = 0;
- EngineMan.findGame(_vm->getGameId(), &plugin);
GUI::SaveLoadChooser *dialog;
if (saveFlag)
- dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"));
+ dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
else
- dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"));
+ dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false);
- dialog->setSaveMode(saveFlag);
- int slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ int slot = dialog->runModalWithCurrentTarget();
if (slot >= 0) {
if (!saveFlag)
diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp
index 1b54c7e26a..cf3dfaa44b 100644
--- a/engines/dialogs.cpp
+++ b/engines/dialogs.cpp
@@ -111,10 +111,8 @@ MainMenuDialog::MainMenuDialog(Engine *engine)
_aboutDialog = new GUI::AboutDialog();
_optionsDialog = new ConfigDialog(_engine->hasFeature(Engine::kSupportsSubtitleOptions));
- _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"));
- _loadDialog->setSaveMode(false);
- _saveDialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"));
- _saveDialog->setSaveMode(true);
+ _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false);
+ _saveDialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
}
MainMenuDialog::~MainMenuDialog() {
@@ -216,26 +214,13 @@ void MainMenuDialog::reflowLayout() {
}
void MainMenuDialog::save() {
- const Common::String gameId = ConfMan.get("gameid");
-
- const EnginePlugin *plugin = 0;
- EngineMan.findGame(gameId, &plugin);
-
- int slot = _saveDialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ int slot = _saveDialog->runModalWithCurrentTarget();
if (slot >= 0) {
Common::String result(_saveDialog->getResultString());
if (result.empty()) {
// If the user was lazy and entered no save name, come up with a default name.
- #if defined(USE_SAVEGAME_TIMESTAMP)
- TimeDate curTime;
- g_system->getTimeAndDate(curTime);
- curTime.tm_year += 1900; // fixup year
- curTime.tm_mon++; // fixup month
- result = Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec);
- #else
- result = Common::String::format("Save %d", slot + 1);
- #endif
+ result = _saveDialog->createDefaultSaveDescription(slot);
}
Common::Error status = _engine->saveGameState(slot, result);
@@ -252,12 +237,7 @@ void MainMenuDialog::save() {
}
void MainMenuDialog::load() {
- const Common::String gameId = ConfMan.get("gameid");
-
- const EnginePlugin *plugin = 0;
- EngineMan.findGame(gameId, &plugin);
-
- int slot = _loadDialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ int slot = _loadDialog->runModalWithCurrentTarget();
_engine->setGameToLoadSlot(slot);
diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp
index c8fb537fec..ea9cdc0249 100644
--- a/engines/dreamweb/saveload.cpp
+++ b/engines/dreamweb/saveload.cpp
@@ -158,12 +158,8 @@ void DreamWebEngine::doLoad(int savegameId) {
if (savegameId == -1) {
// Open dialog to get savegameId
- const EnginePlugin *plugin = NULL;
- Common::String gameId = ConfMan.get("gameid");
- EngineMan.findGame(gameId, &plugin);
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"));
- dialog->setSaveMode(false);
- savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
+ savegameId = dialog->runModalWithCurrentTarget();
delete dialog;
}
@@ -245,12 +241,8 @@ void DreamWebEngine::saveGame() {
}
return;
} else {
- const EnginePlugin *plugin = NULL;
- Common::String gameId = ConfMan.get("gameid");
- EngineMan.findGame(gameId, &plugin);
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"));
- dialog->setSaveMode(true);
- int savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
+ int savegameId = dialog->runModalWithCurrentTarget();
Common::String game_description = dialog->getResultString();
if (game_description.empty())
game_description = "Untitled";
diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h
index 7aa58b9b97..77b54a19cd 100644
--- a/engines/gob/detection_tables.h
+++ b/engines/gob/detection_tables.h
@@ -34,7 +34,7 @@ static const GOBGameDescription gameDescriptions[] = {
GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
},
kGameTypeGob1,
- kFeaturesEGA,
+ kFeaturesEGA | kFeaturesAdLib,
0, 0, 0
},
{
@@ -48,7 +48,7 @@ static const GOBGameDescription gameDescriptions[] = {
GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH)
},
kGameTypeGob1,
- kFeaturesEGA,
+ kFeaturesEGA | kFeaturesAdLib,
0, 0, 0
},
{ // Supplied by Theruler76 in bug report #1201233
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index fb15fdbc19..878c1dc265 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -123,7 +123,7 @@ void Draw_v1::animateCursor(int16 cursor) {
(cursorIndex + 1) * _cursorWidth - 1,
_cursorHeight - 1, 0, 0);
CursorMan.replaceCursor(_scummvmCursor->getData(),
- _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat());
+ _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, false, &_vm->getPixelFormat());
if (_frontSurface != _backSurface) {
_showCursor = 3;
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index ab9a90de8f..d9b7a12639 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -161,7 +161,7 @@ void Draw_v2::animateCursor(int16 cursor) {
keyColor = _cursorKeyColors[cursorIndex];
CursorMan.replaceCursor(_scummvmCursor->getData(),
- _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat());
+ _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, false, &_vm->getPixelFormat());
if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) {
CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3),
diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp
index 1264c09860..87656a5fad 100644
--- a/engines/gob/global.cpp
+++ b/engines/gob/global.cpp
@@ -111,7 +111,6 @@ Global::Global(GobEngine *vm) : _vm(vm) {
_dontSetPalette = false;
_debugFlag = 0;
- _inVM = 0;
_inter_animDataSize = 10;
diff --git a/engines/gob/global.h b/engines/gob/global.h
index fa2f2c9637..175331dd83 100644
--- a/engines/gob/global.h
+++ b/engines/gob/global.h
@@ -127,7 +127,6 @@ public:
SurfacePtr _primarySurfDesc;
int16 _debugFlag;
- int16 _inVM;
int16 _inter_animDataSize;
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index ea2323807a..6277585015 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -50,6 +50,10 @@ class StaticTextWidget;
* - Bargon Attack
* - Lost in Time
* - The Bizarre Adventures of Woodruff and the Schnibble
+ * - Fascination
+ * - Urban Runner
+ * - Bambou le sauveur de la jungle
+ * - Geisha
*/
namespace Gob {
diff --git a/engines/gob/init.h b/engines/gob/init.h
index 946a3fa4f1..ac460fd654 100644
--- a/engines/gob/init.h
+++ b/engines/gob/init.h
@@ -62,7 +62,6 @@ public:
~Init_Geisha();
void initVideo();
- void initGame();
};
class Init_v2 : public Init_v1 {
diff --git a/engines/gob/init_fascin.cpp b/engines/gob/init_fascin.cpp
index b87d816406..e6d82faa68 100644
--- a/engines/gob/init_fascin.cpp
+++ b/engines/gob/init_fascin.cpp
@@ -44,10 +44,10 @@ void Init_Fascination::updateConfig() {
}
void Init_Fascination::initGame() {
-// HACK - Suppress ADLIB_FLAG as the MDY/TBR player is not working. suppress
-// the PC Speaker too, as the script checks in the intro for it's presence
+// HACK - Suppress
+// the PC Speaker, as the script checks in the intro for it's presence
// to play or not some noices.
- _vm->_global->_soundFlags = MIDI_FLAG | BLASTER_FLAG;
+ _vm->_global->_soundFlags = MIDI_FLAG | BLASTER_FLAG | ADLIB_FLAG;
Init::initGame();
}
diff --git a/engines/gob/init_geisha.cpp b/engines/gob/init_geisha.cpp
index b5bbcff400..01081a5af6 100644
--- a/engines/gob/init_geisha.cpp
+++ b/engines/gob/init_geisha.cpp
@@ -44,11 +44,4 @@ void Init_Geisha::initVideo() {
_vm->_draw->_transparentCursor = 1;
}
-void Init_Geisha::initGame() {
- // HACK - Since the MDY/TBR player is not working, claim we have no AdLib
- _vm->_global->_soundFlags = 0;
-
- Init::initGame();
-}
-
} // End of namespace Gob
diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp
index 25d521aca6..a8e8cbe2c3 100644
--- a/engines/gob/init_v1.cpp
+++ b/engines/gob/init_v1.cpp
@@ -41,8 +41,6 @@ void Init_v1::initVideo() {
_vm->_global->_mousePresent = 1;
- _vm->_global->_inVM = 0;
-
if ((_vm->_global->_videoMode == 0x13) && !_vm->isEGA())
_vm->_global->_colorCount = 256;
diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp
index 1289d561ea..c204b04a40 100644
--- a/engines/gob/init_v2.cpp
+++ b/engines/gob/init_v2.cpp
@@ -45,8 +45,6 @@ void Init_v2::initVideo() {
_vm->_global->_mousePresent = 1;
- _vm->_global->_inVM = 0;
-
_vm->_global->_colorCount = 16;
if (!_vm->isEGA() &&
((_vm->getPlatform() == Common::kPlatformPC) ||
diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp
index 081b48fbad..001ec06635 100644
--- a/engines/gob/inter_fascin.cpp
+++ b/engines/gob/inter_fascin.cpp
@@ -248,12 +248,11 @@ void Inter_Fascination::oFascin_playTira(OpGobParams &params) {
void Inter_Fascination::oFascin_loadExtasy(OpGobParams &params) {
_vm->_sound->adlibLoadTBR("extasy.tbr");
_vm->_sound->adlibLoadMDY("extasy.mdy");
+ _vm->_sound->adlibSetRepeating(-1);
}
void Inter_Fascination::oFascin_adlibPlay(OpGobParams &params) {
-#ifdef ENABLE_FASCIN_ADLIB
_vm->_sound->adlibPlay();
-#endif
}
void Inter_Fascination::oFascin_adlibStop(OpGobParams &params) {
diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp
index 75204a3f55..8a4d4246b6 100644
--- a/engines/gob/inter_geisha.cpp
+++ b/engines/gob/inter_geisha.cpp
@@ -298,9 +298,8 @@ void Inter_Geisha::oGeisha_loadTitleMusic(OpGobParams &params) {
}
void Inter_Geisha::oGeisha_playMusic(OpGobParams &params) {
- // TODO: The MDYPlayer is still broken!
- warning("Geisha Stub: oGeisha_playMusic");
- // _vm->_sound->adlibPlay();
+ _vm->_sound->adlibSetRepeating(-1);
+ _vm->_sound->adlibPlay();
}
void Inter_Geisha::oGeisha_stopMusic(OpGobParams &params) {
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 4aa54f720b..6fc472a0ac 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -286,10 +286,40 @@ void Inter_v1::o1_loadMult() {
}
void Inter_v1::o1_playMult() {
- int16 checkEscape;
+ // NOTE: The EGA version of Gobliiins has an MDY tune.
+ // While the original doesn't play it, we do.
+ bool isGob1EGAIntro = _vm->getGameType() == kGameTypeGob1 &&
+ _vm->isEGA() &&
+ _vm->_game->_script->pos() == 1010 &&
+ _vm->isCurrentTot("intro.tot") &&
+ VAR(57) != 0xFFFFFFFF &&
+ _vm->_dataIO->hasFile("goblins.mdy") &&
+ _vm->_dataIO->hasFile("goblins.tbr");
+
+ int16 checkEscape = _vm->_game->_script->readInt16();
+
+ if (isGob1EGAIntro) {
+ _vm->_sound->adlibLoadTBR("goblins.tbr");
+ _vm->_sound->adlibLoadMDY("goblins.mdy");
+ _vm->_sound->adlibSetRepeating(-1);
+
+ _vm->_sound->adlibPlay();
+ }
- checkEscape = _vm->_game->_script->readInt16();
_vm->_mult->playMult(VAR(57), -1, checkEscape, 0);
+
+ if (isGob1EGAIntro) {
+
+ // User didn't escape the intro mult, wait for an escape here
+ if (VAR(57) != 0xFFFFFFFF) {
+ while (_vm->_util->getKey() != kKeyEscape) {
+ _vm->_util->processInput();
+ _vm->_util->longDelay(1);
+ }
+ }
+
+ _vm->_sound->adlibUnload();
+ }
}
void Inter_v1::o1_freeMultKeys() {
diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp
index 719ecf3d18..7ec3119866 100644
--- a/engines/gob/minigames/geisha/meter.cpp
+++ b/engines/gob/minigames/geisha/meter.cpp
@@ -67,7 +67,7 @@ int32 Meter::increase(int32 n) {
if (n < 0)
return decrease(-n);
- int32 overflow = MAX(0, (_value + n) - _maxValue);
+ int32 overflow = MAX<int32>(0, (_value + n) - _maxValue);
int32 value = CLIP<int32>(_value + n, 0, _maxValue);
if (_value == value)
@@ -83,7 +83,7 @@ int32 Meter::decrease(int32 n) {
if (n < 0)
return increase(-n);
- int32 underflow = -MIN(0, _value - n);
+ int32 underflow = -MIN<int32>(0, _value - n);
int32 value = CLIP<int32>(_value - n, 0, _maxValue);
if (_value == value)
diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp
index 9791757984..3be9f1f651 100644
--- a/engines/gob/minigames/geisha/penetration.cpp
+++ b/engines/gob/minigames/geisha/penetration.cpp
@@ -55,12 +55,24 @@ enum Sprite {
kSpriteFloor = 30,
kSpriteWall = 31,
kSpriteMouthBite = 32,
- kSpriteMouthKiss = 33
+ kSpriteMouthKiss = 33,
+ kSpriteBulletN = 65,
+ kSpriteBulletS = 66,
+ kSpriteBulletW = 67,
+ kSpriteBulletE = 68,
+ kSpriteBulletSW = 85,
+ kSpriteBulletSE = 86,
+ kSpriteBulletNW = 87,
+ kSpriteBulletNE = 88
};
enum Animation {
- kAnimationMouthKiss = 33,
- kAnimationMouthBite = 34
+ kAnimationEnemyRound = 0,
+ kAnimationEnemyRoundExplode = 1,
+ kAnimationEnemySquare = 2,
+ kAnimationEnemySquareExplode = 3,
+ kAnimationMouthKiss = 33,
+ kAnimationMouthBite = 34
};
static const int kMapTileWidth = 24;
@@ -353,12 +365,55 @@ static const char *kStrings[kLanguageCount][kStringCount] = {
}
};
-Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) {
+
+Penetration::MapObject::MapObject(uint16 tX, uint16 tY, uint16 mX, uint16 mY, uint16 w, uint16 h) :
+ tileX(tX), tileY(tY), mapX(mX), mapY(mY), width(w), height(h) {
+
+ isBlocking = true;
+}
+
+Penetration::MapObject::MapObject(uint16 tX, uint16 tY, uint16 w, uint16 h) :
+ tileX(tX), tileY(tY), width(w), height(h) {
+
+ isBlocking = true;
+
+ setMapFromTilePosition();
+}
+
+void Penetration::MapObject::setTileFromMapPosition() {
+ tileX = (mapX + (width / 2)) / kMapTileWidth;
+ tileY = (mapY + (height / 2)) / kMapTileHeight;
+}
+
+void Penetration::MapObject::setMapFromTilePosition() {
+ mapX = tileX * kMapTileWidth;
+ mapY = tileY * kMapTileHeight;
+}
+
+bool Penetration::MapObject::isIn(uint16 mX, uint16 mY) const {
+ if ((mX < mapX) || (mY < mapY))
+ return false;
+ if ((mX > (mapX + width - 1)) || (mY > (mapY + height - 1)))
+ return false;
+
+ return true;
+}
+
+bool Penetration::MapObject::isIn(uint16 mX, uint16 mY, uint16 w, uint16 h) const {
+ return isIn(mX , mY ) ||
+ isIn(mX + w - 1, mY ) ||
+ isIn(mX , mY + h - 1) ||
+ isIn(mX + w - 1, mY + h - 1);
+}
+
+bool Penetration::MapObject::isIn(const MapObject &obj) const {
+ return isIn(obj.mapX, obj.mapY, obj.width, obj.height);
}
-Penetration::ManagedMouth::ManagedMouth(uint16 pX, uint16 pY, MouthType t) :
- Position(pX, pY), mouth(0), type(t) {
+Penetration::ManagedMouth::ManagedMouth(uint16 tX, uint16 tY, MouthType t) :
+ MapObject(tX, tY, 0, 0), mouth(0), type(t) {
+
}
Penetration::ManagedMouth::~ManagedMouth() {
@@ -366,9 +421,9 @@ Penetration::ManagedMouth::~ManagedMouth() {
}
-Penetration::ManagedSub::ManagedSub(uint16 pX, uint16 pY) : Position(pX, pY), sub(0) {
- mapX = x * kMapTileWidth;
- mapY = y * kMapTileHeight;
+Penetration::ManagedSub::ManagedSub(uint16 tX, uint16 tY) :
+ MapObject(tX, tY, kMapTileWidth, kMapTileHeight), sub(0) {
+
}
Penetration::ManagedSub::~ManagedSub() {
@@ -376,6 +431,34 @@ Penetration::ManagedSub::~ManagedSub() {
}
+Penetration::ManagedEnemy::ManagedEnemy() : MapObject(0, 0, 0, 0), enemy(0), dead(false) {
+}
+
+Penetration::ManagedEnemy::~ManagedEnemy() {
+ delete enemy;
+}
+
+void Penetration::ManagedEnemy::clear() {
+ delete enemy;
+
+ enemy = 0;
+}
+
+
+Penetration::ManagedBullet::ManagedBullet() : MapObject(0, 0, 0, 0), bullet(0) {
+}
+
+Penetration::ManagedBullet::~ManagedBullet() {
+ delete bullet;
+}
+
+void Penetration::ManagedBullet::clear() {
+ delete bullet;
+
+ bullet = 0;
+}
+
+
Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0),
_shieldMeter(0), _healthMeter(0), _floor(0), _isPlaying(false) {
@@ -415,6 +498,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) {
_vm->_video->retrace();
while (!_vm->shouldQuit() && !_quit && !isDead() && !hasWon()) {
+ enemiesCreate();
+ bulletsMove();
updateAnims();
// Draw, fade in if necessary and wait for the end of the frame
@@ -428,7 +513,13 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) {
// Handle the sub movement
handleSub();
+ // Handle the enemies movement
+ enemiesMove();
+
checkExited();
+
+ if (_shotCoolDown > 0)
+ _shotCoolDown--;
}
deinit();
@@ -449,11 +540,12 @@ void Penetration::cheatWin() {
void Penetration::init() {
// Load sounds
- _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd");
- _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd");
- _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd");
- _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd");
- _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd");
+ _vm->_sound->sampleLoad(&_soundShield , SOUND_SND, "boucl.snd");
+ _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd");
+ _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd");
+ _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd");
+ _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd");
+ _vm->_sound->sampleLoad(&_soundExplode, SOUND_SND, "virmor.snd");
_quit = false;
for (int i = 0; i < kKeyCount; i++)
@@ -477,6 +569,8 @@ void Penetration::init() {
_floor = 0;
+ _shotCoolDown = 0;
+
createMap();
}
@@ -486,6 +580,7 @@ void Penetration::deinit() {
_soundKiss.free();
_soundShoot.free();
_soundExit.free();
+ _soundExplode.free();
clearMap();
@@ -500,10 +595,18 @@ void Penetration::clearMap() {
_mapAnims.clear();
_anims.clear();
+ _blockingObjects.clear();
+
+ _walls.clear();
_exits.clear();
_shields.clear();
_mouths.clear();
+ for (int i = 0; i < kEnemyCount; i++)
+ _enemies[i].clear();
+ for (int i = 0; i < kMaxBulletCount; i++)
+ _bullets[i].clear();
+
delete _sub;
_sub = 0;
@@ -526,13 +629,9 @@ void Penetration::createMap() {
for (int x = 0; x < kMapWidth; x++) {
const byte mapTile = mapTiles[y * kMapWidth + x];
- bool *walkMap = _walkMap + (y * kMapWidth + x);
-
const int posX = kPlayAreaBorderWidth + x * kMapTileWidth;
const int posY = kPlayAreaBorderHeight + y * kMapTileHeight;
- *walkMap = true;
-
switch (mapTile) {
case 0: // Floor
_sprites->draw(*_map, kSpriteFloor, posX, posY);
@@ -542,18 +641,18 @@ void Penetration::createMap() {
exitWorks = _hasAccessPass;
if (exitWorks) {
- _exits.push_back(Position(x, y));
_sprites->draw(*_map, kSpriteExit, posX, posY);
+ _exits.push_back(MapObject(x, y, 0, 0));
} else {
_sprites->draw(*_map, kSpriteWall, posX, posY);
- *walkMap = false;
+ _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight));
}
break;
case 50: // Wall
_sprites->draw(*_map, kSpriteWall, posX, posY);
- *walkMap = false;
+ _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight));
break;
case 51: // Regular exit
@@ -563,11 +662,11 @@ void Penetration::createMap() {
exitWorks = _testMode || (_floor < 2) || _hasAccessPass;
if (exitWorks) {
- _exits.push_back(Position(x, y));
_sprites->draw(*_map, kSpriteExit, posX, posY);
+ _exits.push_back(MapObject(x, y, 0, 0));
} else {
_sprites->draw(*_map, kSpriteWall, posX, posY);
- *walkMap = false;
+ _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight));
}
break;
@@ -603,7 +702,7 @@ void Penetration::createMap() {
_map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield
_map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield
- _shields.push_back(Position(x, y));
+ _shields.push_back(MapObject(x, y, 0, 0));
break;
case 57: // Start position
@@ -623,10 +722,42 @@ void Penetration::createMap() {
if (!_sub)
error("Geisha: No starting position in floor %d (testmode: %d)", _floor, _testMode);
- for (Common::List<ManagedMouth>::iterator m = _mouths.begin(); m != _mouths.end(); m++)
+ // Walls
+ for (Common::List<MapObject>::iterator w = _walls.begin(); w != _walls.end(); ++w)
+ _blockingObjects.push_back(&*w);
+
+ // Mouths
+ for (Common::List<ManagedMouth>::iterator m = _mouths.begin(); m != _mouths.end(); ++m)
_mapAnims.push_back(m->mouth);
+ // Sub
+ _blockingObjects.push_back(_sub);
_anims.push_back(_sub->sub);
+
+ // Moving enemies
+ for (int i = 0; i < kEnemyCount; i++) {
+ _enemies[i].enemy = new ANIObject(*_objects);
+
+ _enemies[i].enemy->setPause(true);
+ _enemies[i].enemy->setVisible(false);
+
+ _enemies[i].isBlocking = false;
+
+ _blockingObjects.push_back(&_enemies[i]);
+ _mapAnims.push_back(_enemies[i].enemy);
+ }
+
+ // Bullets
+ for (int i = 0; i < kMaxBulletCount; i++) {
+ _bullets[i].bullet = new ANIObject(*_sprites);
+
+ _bullets[i].bullet->setPause(true);
+ _bullets[i].bullet->setVisible(false);
+
+ _bullets[i].isBlocking = false;
+
+ _mapAnims.push_back(_bullets[i].bullet);
+ }
}
void Penetration::drawFloorText() {
@@ -741,6 +872,105 @@ void Penetration::initScreen() {
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
}
+void Penetration::enemiesCreate() {
+ for (int i = 0; i < kEnemyCount; i++) {
+ ManagedEnemy &enemy = _enemies[i];
+
+ if (enemy.enemy->isVisible())
+ continue;
+
+ enemy.enemy->setAnimation((i & 1) ? kAnimationEnemySquare : kAnimationEnemyRound);
+ enemy.enemy->setMode(ANIObject::kModeContinuous);
+ enemy.enemy->setPause(false);
+ enemy.enemy->setVisible(true);
+
+ int16 width, height;
+ enemy.enemy->getFrameSize(width, height);
+
+ enemy.width = width;
+ enemy.height = height;
+
+ do {
+ enemy.mapX = _vm->_util->getRandom(kMapWidth) * kMapTileWidth + 2;
+ enemy.mapY = _vm->_util->getRandom(kMapHeight) * kMapTileHeight + 4;
+ enemy.setTileFromMapPosition();
+ } while (isBlocked(enemy, enemy.mapX, enemy.mapY));
+
+ const int posX = kPlayAreaBorderWidth + enemy.mapX;
+ const int posY = kPlayAreaBorderHeight + enemy.mapY;
+
+ enemy.enemy->setPosition(posX, posY);
+
+ enemy.isBlocking = true;
+ enemy.dead = false;
+ }
+}
+
+void Penetration::enemyMove(ManagedEnemy &enemy, int x, int y) {
+ if ((x == 0) && (y == 0))
+ return;
+
+ MapObject *blockedBy;
+ findPath(enemy, x, y, &blockedBy);
+
+ enemy.setTileFromMapPosition();
+
+ const int posX = kPlayAreaBorderWidth + enemy.mapX;
+ const int posY = kPlayAreaBorderHeight + enemy.mapY;
+
+ enemy.enemy->setPosition(posX, posY);
+
+ if (blockedBy == _sub)
+ enemyAttack(enemy);
+}
+
+void Penetration::enemiesMove() {
+ for (int i = 0; i < kEnemyCount; i++) {
+ ManagedEnemy &enemy = _enemies[i];
+
+ if (!enemy.enemy->isVisible() || enemy.dead)
+ continue;
+
+ int x = 0, y = 0;
+
+ if (enemy.mapX > _sub->mapX)
+ x = -8;
+ else if (enemy.mapX < _sub->mapX)
+ x = 8;
+
+ if (enemy.mapY > _sub->mapY)
+ y = -8;
+ else if (enemy.mapY < _sub->mapY)
+ y = 8;
+
+ enemyMove(enemy, x, y);
+ }
+}
+
+void Penetration::enemyAttack(ManagedEnemy &enemy) {
+ // If we have shields, the enemy explodes at them, taking a huge chunk of energy with it.
+ // Otherwise, the enemy nibbles a small amount of health away.
+
+ if (_shieldMeter->getValue() > 0) {
+ enemyExplode(enemy);
+
+ healthLose(80);
+ } else
+ healthLose(5);
+}
+
+void Penetration::enemyExplode(ManagedEnemy &enemy) {
+ enemy.dead = true;
+ enemy.isBlocking = false;
+
+ bool isSquare = enemy.enemy->getAnimation() == kAnimationEnemySquare;
+
+ enemy.enemy->setAnimation(isSquare ? kAnimationEnemySquareExplode : kAnimationEnemyRoundExplode);
+ enemy.enemy->setMode(ANIObject::kModeOnce);
+
+ _vm->_sound->blasterPlay(&_soundExplode, 1, 0);
+}
+
void Penetration::checkInput() {
Common::Event event;
Common::EventManager *eventMan = g_system->getEventManager();
@@ -785,13 +1015,6 @@ void Penetration::checkInput() {
}
}
-bool Penetration::isWalkable(int16 x, int16 y) const {
- if ((x < 0) || (x >= kMapWidth) || (y < 0) || (y >= kMapHeight))
- return false;
-
- return _walkMap[y * kMapWidth + x];
-}
-
void Penetration::handleSub() {
int x, y;
Submarine::Direction direction = getDirection(x, y);
@@ -802,34 +1025,86 @@ void Penetration::handleSub() {
subShoot();
}
-void Penetration::subMove(int x, int y, Submarine::Direction direction) {
- if (!_sub->sub->canMove())
- return;
+bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, MapObject **blockedBy) {
+
+ if ((x < 0) || (y < 0))
+ return true;
+ if (((x + self.width - 1) >= (kMapWidth * kMapTileWidth)) ||
+ ((y + self.height - 1) >= (kMapHeight * kMapTileHeight)))
+ return true;
+
+ MapObject checkSelf(0, 0, self.width, self.height);
+
+ checkSelf.mapX = x;
+ checkSelf.mapY = y;
+
+ for (Common::List<MapObject *>::iterator o = _blockingObjects.begin(); o != _blockingObjects.end(); ++o) {
+ MapObject &obj = **o;
+
+ if (&obj == &self)
+ continue;
- // Limit the movement to walkable tiles
+ if (!obj.isBlocking)
+ continue;
+
+ if (obj.isIn(checkSelf) || checkSelf.isIn(obj)) {
+ if (blockedBy && !*blockedBy)
+ *blockedBy = &obj;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void Penetration::findPath(MapObject &obj, int x, int y, MapObject **blockedBy) {
+ if (blockedBy)
+ *blockedBy = 0;
+
+ while ((x != 0) || (y != 0)) {
+ uint16 oldX = obj.mapX;
+ uint16 oldY = obj.mapY;
+
+ uint16 newX = obj.mapX;
+ if (x > 0) {
+ newX++;
+ x--;
+ } else if (x < 0) {
+ newX--;
+ x++;
+ }
+
+ if (!isBlocked(obj, newX, obj.mapY, blockedBy))
+ obj.mapX = newX;
+
+ uint16 newY = obj.mapY;
+ if (y > 0) {
+ newY++;
+ y--;
+ } else if (y < 0) {
+ newY--;
+ y++;
+ }
- int16 minX = 0;
- if (!isWalkable(_sub->x - 1, _sub->y))
- minX = _sub->x * kMapTileWidth;
+ if (!isBlocked(obj, obj.mapX, newY, blockedBy))
+ obj.mapY = newY;
- int16 maxX = kMapWidth * kMapTileWidth;
- if (!isWalkable(_sub->x + 1, _sub->y))
- maxX = _sub->x * kMapTileWidth;
+ if ((obj.mapX == oldX) && (obj.mapY == oldY))
+ break;
+ }
+}
- int16 minY = 0;
- if (!isWalkable(_sub->x, _sub->y - 1))
- minY = _sub->y * kMapTileHeight;
+void Penetration::subMove(int x, int y, Submarine::Direction direction) {
+ if (!_sub->sub->canMove())
+ return;
- int16 maxY = kMapHeight * kMapTileHeight;
- if (!isWalkable(_sub->x, _sub->y + 1))
- maxY = _sub->y * kMapTileHeight;
+ if ((x == 0) && (y == 0))
+ return;
- _sub->mapX = CLIP<int16>(_sub->mapX + x, minX, maxX);
- _sub->mapY = CLIP<int16>(_sub->mapY + y, minY, maxY);
+ findPath(*_sub, x, y);
- // The tile the sub is on is where its mid-point is
- _sub->x = (_sub->mapX + (kMapTileWidth / 2)) / kMapTileWidth;
- _sub->y = (_sub->mapY + (kMapTileHeight / 2)) / kMapTileHeight;
+ _sub->setTileFromMapPosition();
_sub->sub->turn(direction);
@@ -842,9 +1117,185 @@ void Penetration::subShoot() {
if (!_sub->sub->canMove() || _sub->sub->isShooting())
return;
- _sub->sub->shoot();
+ if (_shotCoolDown > 0)
+ return;
+
+ // Creating a bullet
+ int slot = findEmptyBulletSlot();
+ if (slot < 0)
+ return;
+
+ ManagedBullet &bullet = _bullets[slot];
+ bullet.bullet->setAnimation(directionToBullet(_sub->sub->getDirection()));
+
+ setBulletPosition(*_sub, bullet);
+
+ const int posX = kPlayAreaBorderWidth + bullet.mapX;
+ const int posY = kPlayAreaBorderHeight + bullet.mapY;
+
+ bullet.bullet->setPosition(posX, posY);
+ bullet.bullet->setVisible(true);
+
+ // Shooting
+ _sub->sub->shoot();
_vm->_sound->blasterPlay(&_soundShoot, 1, 0);
+
+ _shotCoolDown = 3;
+}
+
+void Penetration::setBulletPosition(const ManagedSub &sub, ManagedBullet &bullet) const {
+ bullet.mapX = sub.mapX;
+ bullet.mapY= sub.mapY;
+
+ int16 sWidth, sHeight;
+ sub.sub->getFrameSize(sWidth, sHeight);
+
+ int16 bWidth, bHeight;
+ bullet.bullet->getFrameSize(bWidth, bHeight);
+
+ switch (sub.sub->getDirection()) {
+ case Submarine::kDirectionN:
+ bullet.mapX += sWidth / 2;
+ bullet.mapY -= bHeight;
+
+ bullet.deltaX = 0;
+ bullet.deltaY = -8;
+ break;
+
+ case Submarine::kDirectionNE:
+ bullet.mapX += sWidth;
+ bullet.mapY -= bHeight * 2;
+
+ bullet.deltaX = 8;
+ bullet.deltaY = -8;
+ break;
+
+ case Submarine::kDirectionE:
+ bullet.mapX += sWidth;
+ bullet.mapY += sHeight / 2 - bHeight;
+
+ bullet.deltaX = 8;
+ bullet.deltaY = 0;
+ break;
+
+ case Submarine::kDirectionSE:
+ bullet.mapX += sWidth;
+ bullet.mapY += sHeight;
+
+ bullet.deltaX = 8;
+ bullet.deltaY = 8;
+ break;
+
+ case Submarine::kDirectionS:
+ bullet.mapX += sWidth / 2;
+ bullet.mapY += sHeight;
+
+ bullet.deltaX = 0;
+ bullet.deltaY = 8;
+ break;
+
+ case Submarine::kDirectionSW:
+ bullet.mapX -= bWidth;
+ bullet.mapY += sHeight;
+
+ bullet.deltaX = -8;
+ bullet.deltaY = 8;
+ break;
+
+ case Submarine::kDirectionW:
+ bullet.mapX -= bWidth;
+ bullet.mapY += sHeight / 2 - bHeight;
+
+ bullet.deltaX = -8;
+ bullet.deltaY = 0;
+ break;
+
+ case Submarine::kDirectionNW:
+ bullet.mapX -= bWidth;
+ bullet.mapY -= bHeight;
+
+ bullet.deltaX = -8;
+ bullet.deltaY = -8;
+ break;
+
+ default:
+ break;
+ }
+}
+
+uint16 Penetration::directionToBullet(Submarine::Direction direction) const {
+ switch (direction) {
+ case Submarine::kDirectionN:
+ return kSpriteBulletN;
+
+ case Submarine::kDirectionNE:
+ return kSpriteBulletNE;
+
+ case Submarine::kDirectionE:
+ return kSpriteBulletE;
+
+ case Submarine::kDirectionSE:
+ return kSpriteBulletSE;
+
+ case Submarine::kDirectionS:
+ return kSpriteBulletS;
+
+ case Submarine::kDirectionSW:
+ return kSpriteBulletSW;
+
+ case Submarine::kDirectionW:
+ return kSpriteBulletW;
+
+ case Submarine::kDirectionNW:
+ return kSpriteBulletNW;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int Penetration::findEmptyBulletSlot() const {
+ for (int i = 0; i < kMaxBulletCount; i++)
+ if (!_bullets[i].bullet->isVisible())
+ return i;
+
+ return -1;
+}
+
+void Penetration::bulletsMove() {
+ for (int i = 0; i < kMaxBulletCount; i++)
+ if (_bullets[i].bullet->isVisible())
+ bulletMove(_bullets[i]);
+}
+
+void Penetration::bulletMove(ManagedBullet &bullet) {
+ MapObject *blockedBy;
+ findPath(bullet, bullet.deltaX, bullet.deltaY, &blockedBy);
+
+ if (blockedBy) {
+ checkShotEnemy(*blockedBy);
+ bullet.bullet->setVisible(false);
+ return;
+ }
+
+ const int posX = kPlayAreaBorderWidth + bullet.mapX;
+ const int posY = kPlayAreaBorderHeight + bullet.mapY;
+
+ bullet.bullet->setPosition(posX, posY);
+}
+
+void Penetration::checkShotEnemy(MapObject &shotObject) {
+ for (int i = 0; i < kEnemyCount; i++) {
+ ManagedEnemy &enemy = _enemies[i];
+
+ if ((&enemy == &shotObject) && !enemy.dead && enemy.enemy->isVisible()) {
+ enemyExplode(enemy);
+ return;
+ }
+ }
}
Submarine::Direction Penetration::getDirection(int &x, int &y) const {
@@ -872,8 +1323,8 @@ Submarine::Direction Penetration::getDirection(int &x, int &y) const {
}
void Penetration::checkShields() {
- for (Common::List<Position>::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) {
- if ((pos->x == _sub->x) && (pos->y == _sub->y)) {
+ for (Common::List<MapObject>::iterator s = _shields.begin(); s != _shields.end(); ++s) {
+ if ((s->tileX == _sub->tileX) && (s->tileY == _sub->tileY)) {
// Charge shields
_shieldMeter->setMaxValue();
@@ -881,11 +1332,8 @@ void Penetration::checkShields() {
_vm->_sound->blasterPlay(&_soundShield, 1, 0);
// Erase the shield from the map
- const int mapX = kPlayAreaBorderWidth + pos->x * kMapTileWidth;
- const int mapY = kPlayAreaBorderHeight + pos->y * kMapTileHeight;
- _sprites->draw(*_map, 30, mapX, mapY);
-
- _shields.erase(pos);
+ _sprites->draw(*_map, 30, s->mapX + kPlayAreaBorderWidth, s->mapY + kPlayAreaBorderHeight);
+ _shields.erase(s);
break;
}
}
@@ -896,8 +1344,8 @@ void Penetration::checkMouths() {
if (!m->mouth->isDeactivated())
continue;
- if ((( m->x == _sub->x) && (m->y == _sub->y)) ||
- (((m->x + 1) == _sub->x) && (m->y == _sub->y))) {
+ if ((( m->tileX == _sub->tileX) && (m->tileY == _sub->tileY)) ||
+ (((m->tileX + 1) == _sub->tileX) && (m->tileY == _sub->tileY))) {
m->mouth->activate();
@@ -917,10 +1365,9 @@ void Penetration::checkExits() {
if (!_sub->sub->canMove())
return;
- for (Common::List<Position>::iterator e = _exits.begin(); e != _exits.end(); ++e) {
- if ((e->x == _sub->x) && (e->y == _sub->y)) {
- _sub->mapX = e->x * kMapTileWidth;
- _sub->mapY = e->y * kMapTileHeight;
+ for (Common::List<MapObject>::iterator e = _exits.begin(); e != _exits.end(); ++e) {
+ if ((e->tileX == _sub->tileX) && (e->tileY == _sub->tileY)) {
+ _sub->setMapFromTilePosition();
_sub->sub->leave();
diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h
index 0336ef8dcb..50004eba8e 100644
--- a/engines/gob/minigames/geisha/penetration.h
+++ b/engines/gob/minigames/geisha/penetration.h
@@ -65,11 +65,30 @@ private:
static const byte kPalettes[kFloorCount][3 * kPaletteSize];
static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight];
- struct Position {
- uint16 x;
- uint16 y;
+ static const int kEnemyCount = 9;
+ static const int kMaxBulletCount = 10;
- Position(uint16 pX, uint16 pY);
+ struct MapObject {
+ uint16 tileX;
+ uint16 tileY;
+
+ uint16 mapX;
+ uint16 mapY;
+
+ uint16 width;
+ uint16 height;
+
+ bool isBlocking;
+
+ MapObject(uint16 tX, uint16 tY, uint16 mX, uint16 mY, uint16 w, uint16 h);
+ MapObject(uint16 tX, uint16 tY, uint16 w, uint16 h);
+
+ void setTileFromMapPosition();
+ void setMapFromTilePosition();
+
+ bool isIn(uint16 mX, uint16 mY) const;
+ bool isIn(uint16 mX, uint16 mY, uint16 w, uint16 h) const;
+ bool isIn(const MapObject &obj) const;
};
enum MouthType {
@@ -77,24 +96,43 @@ private:
kMouthTypeKiss
};
- struct ManagedMouth : public Position {
+ struct ManagedMouth : public MapObject {
Mouth *mouth;
+
MouthType type;
- ManagedMouth(uint16 pX, uint16 pY, MouthType t);
+ ManagedMouth(uint16 tX, uint16 tY, MouthType t);
~ManagedMouth();
};
- struct ManagedSub : public Position {
+ struct ManagedSub : public MapObject {
Submarine *sub;
- uint16 mapX;
- uint16 mapY;
-
- ManagedSub(uint16 pX, uint16 pY);
+ ManagedSub(uint16 tX, uint16 tY);
~ManagedSub();
+ };
+
+ struct ManagedEnemy : public MapObject {
+ ANIObject *enemy;
+
+ bool dead;
- void setPosition(uint16 pX, uint16 pY);
+ ManagedEnemy();
+ ~ManagedEnemy();
+
+ void clear();
+ };
+
+ struct ManagedBullet : public MapObject {
+ ANIObject *bullet;
+
+ int16 deltaX;
+ int16 deltaY;
+
+ ManagedBullet();
+ ~ManagedBullet();
+
+ void clear();
};
enum Keys {
@@ -130,19 +168,27 @@ private:
uint8 _floor;
Surface *_map;
- bool _walkMap[kMapWidth * kMapHeight];
ManagedSub *_sub;
- Common::List<Position> _exits;
- Common::List<Position> _shields;
+ Common::List<MapObject> _walls;
+ Common::List<MapObject> _exits;
+ Common::List<MapObject> _shields;
Common::List<ManagedMouth> _mouths;
+ ManagedEnemy _enemies[kEnemyCount];
+ ManagedBullet _bullets[kMaxBulletCount];
+
+ Common::List<MapObject *> _blockingObjects;
+
+ uint8 _shotCoolDown;
+
SoundDesc _soundShield;
SoundDesc _soundBite;
SoundDesc _soundKiss;
SoundDesc _soundShoot;
SoundDesc _soundExit;
+ SoundDesc _soundExplode;
bool _isPlaying;
@@ -161,17 +207,26 @@ private:
void drawFloorText();
void drawEndText();
+ bool isBlocked(const MapObject &self, int16 x, int16 y, MapObject **blockedBy = 0);
+ void findPath(MapObject &obj, int x, int y, MapObject **blockedBy = 0);
+
void updateAnims();
void checkInput();
+ Submarine::Direction getDirection(int &x, int &y) const;
+
void handleSub();
void subMove(int x, int y, Submarine::Direction direction);
void subShoot();
- Submarine::Direction getDirection(int &x, int &y) const;
+ int findEmptyBulletSlot() const;
+ uint16 directionToBullet(Submarine::Direction direction) const;
+ void setBulletPosition(const ManagedSub &sub, ManagedBullet &bullet) const;
- bool isWalkable(int16 x, int16 y) const;
+ void bulletsMove();
+ void bulletMove(ManagedBullet &bullet);
+ void checkShotEnemy(MapObject &shotObject);
void checkExits();
void checkShields();
@@ -182,6 +237,12 @@ private:
void checkExited();
+ void enemiesCreate();
+ void enemiesMove();
+ void enemyMove(ManagedEnemy &enemy, int x, int y);
+ void enemyAttack(ManagedEnemy &enemy);
+ void enemyExplode(ManagedEnemy &enemy);
+
bool isDead() const;
bool hasWon() const;
diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp
index 9c12a56a85..bf15306e5a 100644
--- a/engines/gob/minigames/geisha/submarine.cpp
+++ b/engines/gob/minigames/geisha/submarine.cpp
@@ -51,13 +51,17 @@ enum Animation {
};
-Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove) {
+Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove), _direction(kDirectionNone) {
turn(kDirectionN);
}
Submarine::~Submarine() {
}
+Submarine::Direction Submarine::getDirection() const {
+ return _direction;
+}
+
void Submarine::turn(Direction to) {
// Nothing to do
if ((to == kDirectionNone) || ((_state == kStateMove) && (_direction == to)))
@@ -90,6 +94,9 @@ void Submarine::shoot() {
}
void Submarine::die() {
+ if (!canMove())
+ return;
+
_state = kStateDie;
setAnimation(directionToExplode(_direction));
diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h
index 8a6d679bdd..a6eae57095 100644
--- a/engines/gob/minigames/geisha/submarine.h
+++ b/engines/gob/minigames/geisha/submarine.h
@@ -47,6 +47,8 @@ public:
Submarine(const ANIFile &ani);
~Submarine();
+ Direction getDirection() const;
+
/** Turn to the specified direction. */
void turn(Direction to);
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index b9680fad6b..7c5d7de158 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -103,6 +103,8 @@ MODULE_OBJS := \
sound/sounddesc.o \
sound/pcspeaker.o \
sound/adlib.o \
+ sound/musplayer.o \
+ sound/adlplayer.o \
sound/infogrames.o \
sound/protracker.o \
sound/soundmixer.o \
diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp
index 06a7130cef..b3d7ea6263 100644
--- a/engines/gob/mult.cpp
+++ b/engines/gob/mult.cpp
@@ -366,10 +366,11 @@ void Mult::doPalAnim() {
palPtr->blue, 0, 0x13);
palPtr = _vm->_global->_pPaletteDesc->vgaPal;
- for (_counter = 0; _counter < 16; _counter++, palPtr++)
+ for (_counter = 0; _counter < 16; _counter++, palPtr++) {
_vm->_global->_redPalette[_counter] = palPtr->red;
_vm->_global->_greenPalette[_counter] = palPtr->green;
_vm->_global->_bluePalette[_counter] = palPtr->blue;
+ }
} else
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp
index 8a5327c3f1..f90b141725 100644
--- a/engines/gob/palanim.cpp
+++ b/engines/gob/palanim.cpp
@@ -75,47 +75,28 @@ bool PalAnim::fadeStepColor(int color) {
bool PalAnim::fadeStep(int16 oper) {
bool stop = true;
- byte newRed;
- byte newGreen;
- byte newBlue;
if (oper == 0) {
- if (_vm->_global->_setAllPalette) {
- if (_vm->_global->_inVM != 0)
- error("PalAnim::fadeStep(): _vm->_global->_inVM != 0 not supported");
-
- for (int i = 0; i < 256; i++) {
- newRed = fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]);
- newGreen = fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]);
- newBlue = fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]);
-
- if ((_vm->_global->_redPalette[i] != newRed) ||
- (_vm->_global->_greenPalette[i] != newGreen) ||
- (_vm->_global->_bluePalette[i] != newBlue)) {
-
- _vm->_video->setPalElem(i, newRed, newGreen, newBlue, 0, 0x13);
-
- _vm->_global->_redPalette[i] = newRed;
- _vm->_global->_greenPalette[i] = newGreen;
- _vm->_global->_bluePalette[i] = newBlue;
- stop = false;
- }
- }
- } else {
- for (int i = 0; i < 16; i++) {
-
- _vm->_video->setPalElem(i,
- fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]),
- fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]),
- fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]),
- -1, _vm->_global->_videoMode);
-
- if ((_vm->_global->_redPalette[i] != _toFadeRed[i]) ||
- (_vm->_global->_greenPalette[i] != _toFadeGreen[i]) ||
- (_vm->_global->_bluePalette[i] != _toFadeBlue[i]))
- stop = false;
+ int colorCount = _vm->_global->_setAllPalette ? _vm->_global->_colorCount : 256;
+
+ for (int i = 0; i < colorCount; i++) {
+ byte newRed = fadeColor(_vm->_global->_redPalette [i], _toFadeRed [i]);
+ byte newGreen = fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]);
+ byte newBlue = fadeColor(_vm->_global->_bluePalette [i], _toFadeBlue [i]);
+
+ if ((_vm->_global->_redPalette [i] != newRed ) ||
+ (_vm->_global->_greenPalette[i] != newGreen) ||
+ (_vm->_global->_bluePalette [i] != newBlue)) {
+
+ _vm->_video->setPalElem(i, newRed, newGreen, newBlue, 0, 0x13);
+
+ _vm->_global->_redPalette [i] = newRed;
+ _vm->_global->_greenPalette[i] = newGreen;
+ _vm->_global->_bluePalette [i] = newBlue;
+ stop = false;
}
}
+
} else if ((oper > 0) && (oper < 4))
stop = fadeStepColor(oper - 1);
@@ -124,44 +105,18 @@ bool PalAnim::fadeStep(int16 oper) {
void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) {
bool stop;
- int16 i;
if (_vm->shouldQuit())
return;
_fadeValue = (fadeV < 0) ? -fadeV : 2;
- if (!_vm->_global->_setAllPalette) {
- if (!palDesc) {
- for (i = 0; i < 16; i++) {
- _toFadeRed[i] = 0;
- _toFadeGreen[i] = 0;
- _toFadeBlue[i] = 0;
- }
- } else {
- for (i = 0; i < 16; i++) {
- _toFadeRed[i] = palDesc->vgaPal[i].red;
- _toFadeGreen[i] = palDesc->vgaPal[i].green;
- _toFadeBlue[i] = palDesc->vgaPal[i].blue;
- }
- }
- } else {
- if (_vm->_global->_inVM != 0)
- error("PalAnim::fade(): _vm->_global->_inVM != 0 is not supported");
-
- if (!palDesc) {
- for (i = 0; i < 256; i++) {
- _toFadeRed[i] = 0;
- _toFadeGreen[i] = 0;
- _toFadeBlue[i] = 0;
- }
- } else {
- for (i = 0; i < 256; i++) {
- _toFadeRed[i] = palDesc->vgaPal[i].red;
- _toFadeGreen[i] = palDesc->vgaPal[i].green;
- _toFadeBlue[i] = palDesc->vgaPal[i].blue;
- }
- }
+ int colorCount = _vm->_global->_setAllPalette ? _vm->_global->_colorCount : 256;
+
+ for (int i = 0; i < colorCount; i++) {
+ _toFadeRed [i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].red;
+ _toFadeGreen[i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].green;
+ _toFadeBlue [i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].blue;
}
if (allColors == 0) {
diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp
index f1ab2a2d79..d9fc362547 100644
--- a/engines/gob/sound/adlib.cpp
+++ b/engines/gob/sound/adlib.cpp
@@ -20,771 +20,621 @@
*
*/
-#include "common/debug.h"
-#include "common/file.h"
-#include "common/endian.h"
+#include "common/util.h"
#include "common/textconsole.h"
+#include "common/debug.h"
+#include "common/config-manager.h"
+
+#include "audio/fmopl.h"
#include "gob/gob.h"
#include "gob/sound/adlib.h"
namespace Gob {
-const unsigned char AdLib::_operators[] = {0, 1, 2, 8, 9, 10, 16, 17, 18};
-const unsigned char AdLib::_volRegNums[] = {
- 3, 4, 5,
- 11, 12, 13,
- 19, 20, 21
+static const int kPitchTom = 24;
+static const int kPitchTomToSnare = 7;
+static const int kPitchSnareDrum = kPitchTom + kPitchTomToSnare;
+
+
+// Is the operator a modulator (0) or a carrier (1)?
+const uint8 AdLib::kOperatorType[kOperatorCount] = {
+ 0, 0, 0, 1, 1, 1,
+ 0, 0, 0, 1, 1, 1,
+ 0, 0, 0, 1, 1, 1
+};
+
+// Operator number to register offset on the OPL
+const uint8 AdLib::kOperatorOffset[kOperatorCount] = {
+ 0, 1, 2, 3, 4, 5,
+ 8, 9, 10, 11, 12, 13,
+ 16, 17, 18, 19, 20, 21
+};
+
+// For each operator, the voice it belongs to
+const uint8 AdLib::kOperatorVoice[kOperatorCount] = {
+ 0, 1, 2,
+ 0, 1, 2,
+ 3, 4, 5,
+ 3, 4, 5,
+ 6, 7, 8,
+ 6, 7, 8,
+};
+
+// Voice to operator set, for the 9 melodyvoices (only 6 useable in percussion mode)
+const uint8 AdLib::kVoiceMelodyOperator[kOperatorsPerVoice][kMelodyVoiceCount] = {
+ {0, 1, 2, 6, 7, 8, 12, 13, 14},
+ {3, 4, 5, 9, 10, 11, 15, 16, 17}
};
-AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer) {
- init();
+// Voice to operator set, for the 5 percussion voices (only useable in percussion mode)
+const uint8 AdLib::kVoicePercussionOperator[kOperatorsPerVoice][kPercussionVoiceCount] = {
+ {12, 16, 14, 17, 13},
+ {15, 0, 0, 0, 0}
+};
+
+// Mask bits to set each percussion instrument on/off
+const byte AdLib::kPercussionMasks[kPercussionVoiceCount] = {0x10, 0x08, 0x04, 0x02, 0x01};
+
+// Default instrument presets
+const uint16 AdLib::kPianoParams [kOperatorsPerVoice][kParamCount] = {
+ { 1, 1, 3, 15, 5, 0, 1, 3, 15, 0, 0, 0, 1, 0},
+ { 0, 1, 1, 15, 7, 0, 2, 4, 0, 0, 0, 1, 0, 0} };
+const uint16 AdLib::kBaseDrumParams[kOperatorsPerVoice][kParamCount] = {
+ { 0, 0, 0, 10, 4, 0, 8, 12, 11, 0, 0, 0, 1, 0 },
+ { 0, 0, 0, 13, 4, 0, 6, 15, 0, 0, 0, 0, 1, 0 } };
+const uint16 AdLib::kSnareDrumParams[kParamCount] = {
+ 0, 12, 0, 15, 11, 0, 8, 5, 0, 0, 0, 0, 0, 0 };
+const uint16 AdLib::kTomParams [kParamCount] = {
+ 0, 4, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0 };
+const uint16 AdLib::kCymbalParams [kParamCount] = {
+ 0, 1, 0, 15, 11, 0, 5, 5, 0, 0, 0, 0, 0, 0 };
+const uint16 AdLib::kHihatParams [kParamCount] = {
+ 0, 1, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0 };
+
+
+AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer), _opl(0),
+ _toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true) {
+
+ _rate = _mixer->getOutputRate();
+
+ initFreqs();
+
+ createOPL();
+ initOPL();
+
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,
+ this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
}
AdLib::~AdLib() {
- Common::StackLock slock(_mutex);
-
_mixer->stopHandle(_handle);
- OPLDestroy(_opl);
- if (_data && _freeData)
- delete[] _data;
-}
-void AdLib::init() {
- _index = -1;
- _data = 0;
- _playPos = 0;
- _dataSize = 0;
+ delete _opl;
+}
- _rate = _mixer->getOutputRate();
+// Creates the OPL. Try to use the DOSBox emulator, unless that one is not compiled in,
+// or the user explicitly wants the MAME emulator. The MAME one is slightly buggy, leading
+// to some wrong sounds, especially noticeable in the title music of Gobliins 2, so we
+// really don't want to use it, if we can help it.
+void AdLib::createOPL() {
+ Common::String oplDriver = ConfMan.get("opl_driver");
- _opl = makeAdLibOPL(_rate);
+ if (oplDriver.empty() || (oplDriver == "auto") || (OPL::Config::parse(oplDriver) == -1)) {
+ // User has selected OPL driver auto detection or an invalid OPL driver.
+ // Set it to our preferred driver (DOSBox), if we can.
- _first = true;
- _ended = false;
- _playing = false;
+ if (OPL::Config::parse("db") <= 0) {
+ warning("The DOSBox AdLib emulator is not compiled in. Please keep in mind that the MAME one is buggy");
+ } else
+ oplDriver = "db";
- _freeData = false;
+ } else if (oplDriver == "mame") {
+ // User has selected the MAME OPL driver. It is buggy, so warn the user about that.
- _repCount = -1;
- _samplesTillPoll = 0;
+ warning("You have selected the MAME AdLib emulator. It is buggy; AdLib music might be slightly glitchy now");
+ }
- for (int i = 0; i < 16; i ++)
- _pollNotes[i] = 0;
- setFreqs();
+ _opl = OPL::Config::create(OPL::Config::parse(oplDriver), OPL::Config::kOpl2);
+ if (!_opl || !_opl->init(_rate)) {
+ delete _opl;
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,
- this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ error("Could not create an AdLib emulator");
+ }
}
int AdLib::readBuffer(int16 *buffer, const int numSamples) {
Common::StackLock slock(_mutex);
- int samples;
- int render;
- if (!_playing || (numSamples < 0)) {
+ // Nothing to do, fill with silence
+ if (!_playing) {
memset(buffer, 0, numSamples * sizeof(int16));
return numSamples;
}
- if (_first) {
- memset(buffer, 0, numSamples * sizeof(int16));
- pollMusic();
- return numSamples;
- }
- samples = numSamples;
+ // Read samples from the OPL, polling in more music when necessary
+ uint32 samples = numSamples;
while (samples && _playing) {
- if (_samplesTillPoll) {
- render = (samples > _samplesTillPoll) ? (_samplesTillPoll) : (samples);
+ if (_toPoll) {
+ const uint32 render = MIN(samples, _toPoll);
+
+ _opl->readBuffer(buffer, render);
+
+ buffer += render;
samples -= render;
- _samplesTillPoll -= render;
- YM3812UpdateOne(_opl, buffer, render);
- buffer += render;
+ _toPoll -= render;
+
} else {
- pollMusic();
+ // Song ended, fill the rest with silence
if (_ended) {
memset(buffer, 0, samples * sizeof(int16));
samples = 0;
+ break;
}
+
+ // Poll more music
+ _toPoll = pollMusic(_first);
+ _first = false;
}
}
+ // Song ended, loop if requested
if (_ended) {
- _first = true;
- _ended = false;
+ _toPoll = 0;
- rewind();
+ // _repCount == 0: No looping (anymore); _repCount < 0: Infinite looping
+ if (_repCount != 0) {
+ if (_repCount > 0)
+ _repCount--;
+
+ _first = true;
+ _ended = false;
- _samplesTillPoll = 0;
- if (_repCount == -1) {
- reset();
- setVoices();
- } else if (_repCount > 0) {
- _repCount--;
reset();
- setVoices();
- }
- else
+ rewind();
+ } else
_playing = false;
}
- return numSamples;
-}
-void AdLib::writeOPL(byte reg, byte val) {
- debugC(6, kDebugSound, "AdLib::writeOPL (%02X, %02X)", reg, val);
- OPLWriteReg(_opl, reg, val);
+ return numSamples;
}
-void AdLib::setFreqs() {
- byte lin;
- byte col;
- long val = 0;
-
- // Run through the 11 channels
- for (lin = 0; lin < 11; lin ++) {
- _notes[lin] = 0;
- _notCol[lin] = 0;
- _notLin[lin] = 0;
- _notOn[lin] = false;
- }
-
- // Run through the 25 lines
- for (lin = 0; lin < 25; lin ++) {
- // Run through the 12 columns
- for (col = 0; col < 12; col ++) {
- if (!col)
- val = (((0x2710L + lin * 0x18) * 0xCB78 / 0x3D090) << 0xE) *
- 9 / 0x1B503;
- _freqs[lin][col] = (short)((val + 4) >> 3);
- val = val * 0x6A / 0x64;
- }
- }
+bool AdLib::isStereo() const {
+ return _opl->isStereo();
}
-void AdLib::reset() {
- _first = true;
- OPLResetChip(_opl);
- _samplesTillPoll = 0;
-
- setFreqs();
- // Set frequencies and octave to 0; notes off
- for (int i = 0; i < 9; i++) {
- writeOPL(0xA0 | i, 0);
- writeOPL(0xB0 | i, 0);
- writeOPL(0xE0 | _operators[i] , 0);
- writeOPL(0xE0 |(_operators[i] + 3), 0);
- }
-
- // Authorize the control of the waveformes
- writeOPL(0x01, 0x20);
-}
-
-void AdLib::setKey(byte voice, byte note, bool on, bool spec) {
- short freq = 0;
- short octa = 0;
-
- // Instruction AX
- if (spec) {
- // 0x7F donne 0x16B;
- // 7F
- // << 7 = 3F80
- // + E000 = 11F80
- // & FFFF = 1F80
- // * 19 = 31380
- // / 2000 = 18 => Ligne 18h, colonne 0 => freq 16B
-
- // 0x3A donne 0x2AF;
- // 3A
- // << 7 = 1D00
- // + E000 = FD00 negatif
- // * 19 = xB500
- // / 2000 = -2 => Ligne 17h, colonne -1
-
- // 2E
- // << 7 = 1700
- // + E000 = F700 negatif
- // * 19 = x1F00
- // / 2000 =
- short a;
- short lin;
- short col;
-
- a = (note << 7) + 0xE000; // Volontairement tronque
- a = (short)((long)a * 25 / 0x2000);
- if (a < 0) {
- col = - ((24 - a) / 25);
- lin = (-a % 25);
- if (lin)
- lin = 25 - lin;
- }
- else {
- col = a / 25;
- lin = a % 25;
- }
-
- _notCol[voice] = col;
- _notLin[voice] = lin;
- note = _notes[voice];
- }
- // Instructions 0X 9X 8X
- else {
- note -= 12;
- _notOn[voice] = on;
- }
-
- _notes[voice] = note;
- note += _notCol[voice];
- note = MIN((byte) 0x5F, note);
- octa = note / 12;
- freq = _freqs[_notLin[voice]][note - octa * 12];
-
- writeOPL(0xA0 + voice, freq & 0xFF);
- writeOPL(0xB0 + voice, (freq >> 8) | (octa << 2) | (0x20 * (on ? 1 : 0)));
-
- if (!freq)
- warning("AdLib::setKey Voice %d, note %02X unknown", voice, note);
+bool AdLib::endOfData() const {
+ return !_playing;
}
-void AdLib::setVolume(byte voice, byte volume) {
- debugC(6, kDebugSound, "AdLib::setVolume(%d, %d)", voice, volume);
- //assert(voice >= 0 && voice <= 9);
- volume = 0x3F - ((volume * 0x7E) + 0x7F) / 0xFE;
- writeOPL(0x40 + _volRegNums[voice], volume);
+bool AdLib::endOfStream() const {
+ return false;
}
-void AdLib::pollMusic() {
- if ((_playPos > (_data + _dataSize)) && (_dataSize != 0xFFFFFFFF)) {
- _ended = true;
- return;
- }
-
- interpret();
-}
-
-void AdLib::unload() {
- _playing = false;
- _index = -1;
-
- if (_data && _freeData)
- delete[] _data;
-
- _freeData = false;
+int AdLib::getRate() const {
+ return _rate;
}
bool AdLib::isPlaying() const {
return _playing;
}
-bool AdLib::getRepeating() const {
- return _repCount != 0;
+int32 AdLib::getRepeating() const {
+ Common::StackLock slock(_mutex);
+
+ return _repCount;
}
void AdLib::setRepeating(int32 repCount) {
+ Common::StackLock slock(_mutex);
+
_repCount = repCount;
}
-int AdLib::getIndex() const {
- return _index;
+uint32 AdLib::getSamplesPerSecond() const {
+ return _rate * (isStereo() ? 2 : 1);
}
void AdLib::startPlay() {
- if (_data) _playing = true;
+ Common::StackLock slock(_mutex);
+
+ _playing = true;
+ _ended = false;
+ _first = true;
+
+ reset();
+ rewind();
}
void AdLib::stopPlay() {
Common::StackLock slock(_mutex);
+
+ end(true);
+
_playing = false;
}
-ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer) {
-}
+void AdLib::writeOPL(byte reg, byte val) {
+ debugC(6, kDebugSound, "AdLib::writeOPL (%02X, %02X)", reg, val);
-ADLPlayer::~ADLPlayer() {
+ _opl->writeReg(reg, val);
}
-bool ADLPlayer::load(const char *fileName) {
- Common::File song;
+void AdLib::reset() {
+ allOff();
+ initOPL();
+}
- unload();
- song.open(fileName);
- if (!song.isOpen())
- return false;
+void AdLib::allOff() {
+ // NOTE: Explicit casts are necessary, because of 5.16 paragraph 4 of the C++ standard
+ int numVoices = isPercussionMode() ? (int)kMaxVoiceCount : (int)kMelodyVoiceCount;
- _freeData = true;
- _dataSize = song.size();
- _data = new byte[_dataSize];
- song.read(_data, _dataSize);
- song.close();
+ for (int i = 0; i < numVoices; i++)
+ noteOff(i);
+}
+void AdLib::end(bool killRepeat) {
reset();
- setVoices();
- _playPos = _data + 3 + (_data[1] + 1) * 0x38;
- return true;
+ _ended = true;
+
+ if (killRepeat)
+ _repCount = 0;
}
-bool ADLPlayer::load(byte *data, uint32 size, int index) {
- unload();
- _repCount = 0;
+void AdLib::initOPL() {
+ _tremoloDepth = false;
+ _vibratoDepth = false;
+ _keySplit = false;
- _dataSize = size;
- _data = data;
- _index = index;
+ _enableWaveSelect = true;
- reset();
- setVoices();
- _playPos = _data + 3 + (_data[1] + 1) * 0x38;
+ for (int i = 0; i < kMaxVoiceCount; i++) {
+ _voiceNote[i] = 0;
+ _voiceOn [i] = 0;
+ }
+
+ _opl->reset();
+
+ initOperatorVolumes();
+ resetFreqs();
+
+ setPercussionMode(false);
+
+ setTremoloDepth(false);
+ setVibratoDepth(false);
+ setKeySplit(false);
+
+ for(int i = 0; i < kMelodyVoiceCount; i++)
+ voiceOff(i);
- return true;
+ setPitchRange(1);
+
+ enableWaveSelect(true);
}
-void ADLPlayer::unload() {
- AdLib::unload();
+bool AdLib::isPercussionMode() const {
+ return _percussionMode;
}
-void ADLPlayer::interpret() {
- unsigned char instr;
- byte channel;
- byte note;
- byte volume;
- uint16 tempo;
+void AdLib::setPercussionMode(bool percussion) {
+ if (percussion) {
+ voiceOff(kVoiceBaseDrum);
+ voiceOff(kVoiceSnareDrum);
+ voiceOff(kVoiceTom);
- // First tempo, we'll ignore it...
- if (_first) {
- tempo = *(_playPos++);
- // Tempo on 2 bytes
- if (tempo & 0x80)
- tempo = ((tempo & 3) << 8) | *(_playPos++);
- }
- _first = false;
-
- // Instruction
- instr = *(_playPos++);
- channel = instr & 0x0F;
-
- switch (instr & 0xF0) {
- // Note on + Volume
- case 0x00:
- note = *(_playPos++);
- _pollNotes[channel] = note;
- setVolume(channel, *(_playPos++));
- setKey(channel, note, true, false);
- break;
- // Note on
- case 0x90:
- note = *(_playPos++);
- _pollNotes[channel] = note;
- setKey(channel, note, true, false);
- break;
- // Last note off
- case 0x80:
- note = _pollNotes[channel];
- setKey(channel, note, false, false);
- break;
- // Frequency on/off
- case 0xA0:
- note = *(_playPos++);
- setKey(channel, note, _notOn[channel], true);
- break;
- // Volume
- case 0xB0:
- volume = *(_playPos++);
- setVolume(channel, volume);
- break;
- // Program change
- case 0xC0:
- setVoice(channel, *(_playPos++), false);
- break;
- // Special
- case 0xF0:
- switch (instr & 0x0F) {
- case 0xF: // End instruction
- _ended = true;
- _samplesTillPoll = 0;
- return;
- default:
- warning("ADLPlayer: Unknown special command %X, stopping playback",
- instr & 0x0F);
- _repCount = 0;
- _ended = true;
- break;
- }
- break;
- default:
- warning("ADLPlayer: Unknown command %X, stopping playback",
- instr & 0xF0);
- _repCount = 0;
- _ended = true;
- break;
+ /* set the frequency for the last 4 percussion voices: */
+ setFreq(kVoiceTom, kPitchTom, 0);
+ setFreq(kVoiceSnareDrum, kPitchSnareDrum, 0);
}
- // Temporization
- tempo = *(_playPos++);
- // End tempo
- if (tempo == 0xFF) {
- _ended = true;
- return;
- }
- // Tempo on 2 bytes
- if (tempo & 0x80)
- tempo = ((tempo & 3) << 8) | *(_playPos++);
- if (!tempo)
- tempo ++;
+ _percussionMode = percussion;
+ _percussionBits = 0;
- _samplesTillPoll = tempo * (_rate / 1000);
+ initOperatorParams();
+ writeTremoloVibratoDepthPercMode();
}
-void ADLPlayer::reset() {
- AdLib::reset();
+void AdLib::enableWaveSelect(bool enable) {
+ _enableWaveSelect = enable;
+
+ for (int i = 0; i < kOperatorCount; i++)
+ writeOPL(0xE0 + kOperatorOffset[i], 0);
+
+ writeOPL(0x011, _enableWaveSelect ? 0x20 : 0);
}
-void ADLPlayer::rewind() {
- _playPos = _data + 3 + (_data[1] + 1) * 0x38;
+void AdLib::setPitchRange(uint8 range) {
+ _pitchRange = CLIP<uint8>(range, 0, 12);
+ _pitchRangeStep = _pitchRange * kPitchStepCount;
}
-void ADLPlayer::setVoices() {
- // Definitions of the 9 instruments
- for (int i = 0; i < 9; i++)
- setVoice(i, i, true);
+void AdLib::setTremoloDepth(bool tremoloDepth) {
+ _tremoloDepth = tremoloDepth;
+
+ writeTremoloVibratoDepthPercMode();
}
-void ADLPlayer::setVoice(byte voice, byte instr, bool set) {
- uint16 strct[27];
- byte channel;
- byte *dataPtr;
+void AdLib::setVibratoDepth(bool vibratoDepth) {
+ _vibratoDepth = vibratoDepth;
- // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26
- // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27
- for (int i = 0; i < 2; i++) {
- dataPtr = _data + 3 + instr * 0x38 + i * 0x1A;
- for (int j = 0; j < 27; j++) {
- strct[j] = READ_LE_UINT16(dataPtr);
- dataPtr += 2;
- }
- channel = _operators[voice] + i * 3;
- writeOPL(0xBD, 0x00);
- writeOPL(0x08, 0x00);
- writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F));
- if (!i)
- writeOPL(0xC0 | voice,
- ((strct[2] & 7) << 1) | (1 - (strct[12] & 1)));
- writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF));
- writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF));
- writeOPL(0x20 | channel, ((strct[9] & 1) << 7) |
- ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) |
- ((strct[11] & 1) << 4) | (strct[1] & 0xF));
- if (!i)
- writeOPL(0xE0 | channel, (strct[26] & 3));
- else
- writeOPL(0xE0 | channel, (strct[14] & 3));
- if (i && set)
- writeOPL(0x40 | channel, 0);
+ writeTremoloVibratoDepthPercMode();
+}
+
+void AdLib::setKeySplit(bool keySplit) {
+ _keySplit = keySplit;
+
+ writeKeySplit();
+}
+
+void AdLib::setVoiceTimbre(uint8 voice, const uint16 *params) {
+ const uint16 *params0 = params;
+ const uint16 *params1 = params + kParamCount - 1;
+ const uint16 *waves = params + 2 * (kParamCount - 1);
+
+ const int voicePerc = voice - kVoiceBaseDrum;
+
+ if (!isPercussionMode() || (voice < kVoiceBaseDrum)) {
+ setOperatorParams(kVoiceMelodyOperator[0][voice], params0, waves[0]);
+ setOperatorParams(kVoiceMelodyOperator[1][voice], params1, waves[1]);
+ } else if (voice == kVoiceBaseDrum) {
+ setOperatorParams(kVoicePercussionOperator[0][voicePerc], params0, waves[0]);
+ setOperatorParams(kVoicePercussionOperator[1][voicePerc], params1, waves[1]);
+ } else {
+ setOperatorParams(kVoicePercussionOperator[0][voicePerc], params0, waves[0]);
}
}
+void AdLib::setVoiceVolume(uint8 voice, uint8 volume) {
+ int oper;
+
+ const int voicePerc = voice - kVoiceBaseDrum;
-MDYPlayer::MDYPlayer(Audio::Mixer &mixer) : AdLib(mixer) {
- init();
+ if (!isPercussionMode() || (voice < kVoiceBaseDrum))
+ oper = kVoiceMelodyOperator[1][ voice];
+ else
+ oper = kVoicePercussionOperator[voice == kVoiceBaseDrum ? 1 : 0][voicePerc];
+
+ _operatorVolume[oper] = MIN<uint8>(volume, kMaxVolume);
+ writeKeyScaleLevelVolume(oper);
}
-MDYPlayer::~MDYPlayer() {
+void AdLib::bendVoicePitch(uint8 voice, uint16 pitchBend) {
+ if (isPercussionMode() && (voice > kVoiceBaseDrum))
+ return;
+
+ changePitch(voice, MIN<uint16>(pitchBend, kMaxPitch));
+ setFreq(voice, _voiceNote[voice], _voiceOn[voice]);
}
-void MDYPlayer::init() {
- _soundMode = 0;
+void AdLib::noteOn(uint8 voice, uint8 note) {
+ note = MAX<int>(0, note - (kStandardMidC - kOPLMidC));
+
+ if (isPercussionMode() && (voice >= kVoiceBaseDrum)) {
+
+ if (voice == kVoiceBaseDrum) {
+ setFreq(kVoiceBaseDrum , note , false);
+ } else if (voice == kVoiceTom) {
+ setFreq(kVoiceTom , note , false);
+ setFreq(kVoiceSnareDrum, note + kPitchTomToSnare, false);
+ }
+
+ _percussionBits |= kPercussionMasks[voice - kVoiceBaseDrum];
+ writeTremoloVibratoDepthPercMode();
- _timbres = 0;
- _tbrCount = 0;
- _tbrStart = 0;
- _timbresSize = 0;
+ } else
+ setFreq(voice, note, true);
}
-bool MDYPlayer::loadMDY(Common::SeekableReadStream &stream) {
- unloadMDY();
+void AdLib::noteOff(uint8 voice) {
+ if (isPercussionMode() && (voice >= kVoiceBaseDrum)) {
+ _percussionBits &= ~kPercussionMasks[voice - kVoiceBaseDrum];
+ writeTremoloVibratoDepthPercMode();
+ } else
+ setFreq(voice, _voiceNote[voice], false);
+}
- _freeData = true;
+void AdLib::writeKeyScaleLevelVolume(uint8 oper) {
+ uint16 volume = 0;
- byte mdyHeader[70];
- stream.read(mdyHeader, 70);
+ volume = (63 - (_operatorParams[oper][kParamLevel] & 0x3F)) * _operatorVolume[oper];
+ volume = 63 - ((2 * volume + kMaxVolume) / (2 * kMaxVolume));
- _tickBeat = mdyHeader[36];
- _beatMeasure = mdyHeader[37];
- _totalTick = mdyHeader[38] + (mdyHeader[39] << 8) + (mdyHeader[40] << 16) + (mdyHeader[41] << 24);
- _dataSize = mdyHeader[42] + (mdyHeader[43] << 8) + (mdyHeader[44] << 16) + (mdyHeader[45] << 24);
- _nrCommand = mdyHeader[46] + (mdyHeader[47] << 8) + (mdyHeader[48] << 16) + (mdyHeader[49] << 24);
-// _soundMode is either 0 (melodic) or 1 (percussive)
- _soundMode = mdyHeader[58];
- assert((_soundMode == 0) || (_soundMode == 1));
+ uint8 keyScale = _operatorParams[oper][kParamKeyScaleLevel] << 6;
- _pitchBendRangeStep = 25*mdyHeader[59];
- _basicTempo = mdyHeader[60] + (mdyHeader[61] << 8);
+ writeOPL(0x40 + kOperatorOffset[oper], volume | keyScale);
+}
- if (_pitchBendRangeStep < 25)
- _pitchBendRangeStep = 25;
- else if (_pitchBendRangeStep > 300)
- _pitchBendRangeStep = 300;
+void AdLib::writeKeySplit() {
+ writeOPL(0x08, _keySplit ? 0x40 : 0);
+}
- _data = new byte[_dataSize];
- stream.read(_data, _dataSize);
+void AdLib::writeFeedbackFM(uint8 oper) {
+ if (kOperatorType[oper] == 1)
+ return;
- reset();
- _playPos = _data;
+ uint8 value = 0;
- return true;
+ value |= _operatorParams[oper][kParamFeedback] << 1;
+ value |= _operatorParams[oper][kParamFM] ? 0 : 1;
+
+ writeOPL(0xC0 + kOperatorVoice[oper], value);
}
-bool MDYPlayer::loadMDY(const char *fileName) {
- Common::File song;
+void AdLib::writeAttackDecay(uint8 oper) {
+ uint8 value = 0;
+
+ value |= _operatorParams[oper][kParamAttack] << 4;
+ value |= _operatorParams[oper][kParamDecay] & 0x0F;
- song.open(fileName);
- if (!song.isOpen())
- return false;
+ writeOPL(0x60 + kOperatorOffset[oper], value);
+}
- bool loaded = loadMDY(song);
+void AdLib::writeSustainRelease(uint8 oper) {
+ uint8 value = 0;
- song.close();
+ value |= _operatorParams[oper][kParamSustain] << 4;
+ value |= _operatorParams[oper][kParamRelease] & 0x0F;
- return loaded;
+ writeOPL(0x80 + kOperatorOffset[oper], value);
}
-bool MDYPlayer::loadTBR(Common::SeekableReadStream &stream) {
- unloadTBR();
+void AdLib::writeTremoloVibratoSustainingKeyScaleRateFreqMulti(uint8 oper) {
+ uint8 value = 0;
- _timbresSize = stream.size();
+ value |= _operatorParams[oper][kParamAM] ? 0x80 : 0;
+ value |= _operatorParams[oper][kParamVib] ? 0x40 : 0;
+ value |= _operatorParams[oper][kParamSustaining] ? 0x20 : 0;
+ value |= _operatorParams[oper][kParamKeyScaleRate] ? 0x10 : 0;
+ value |= _operatorParams[oper][kParamFreqMulti] & 0x0F;
- _timbres = new byte[_timbresSize];
- stream.read(_timbres, _timbresSize);
+ writeOPL(0x20 + kOperatorOffset[oper], value);
+}
- reset();
- setVoices();
+void AdLib::writeTremoloVibratoDepthPercMode() {
+ uint8 value = 0;
+
+ value |= _tremoloDepth ? 0x80 : 0;
+ value |= _vibratoDepth ? 0x40 : 0;
+ value |= isPercussionMode() ? 0x20 : 0;
+ value |= _percussionBits;
- return true;
+ writeOPL(0xBD, value);
}
-bool MDYPlayer::loadTBR(const char *fileName) {
- Common::File timbres;
+void AdLib::writeWaveSelect(uint8 oper) {
+ uint8 wave = 0;
+ if (_enableWaveSelect)
+ wave = _operatorParams[oper][kParamWaveSelect] & 0x03;
- timbres.open(fileName);
- if (!timbres.isOpen())
- return false;
+ writeOPL(0xE0 + kOperatorOffset[ oper], wave);
+}
- bool loaded = loadTBR(timbres);
+void AdLib::writeAllParams(uint8 oper) {
+ writeTremoloVibratoDepthPercMode();
+ writeKeySplit();
+ writeKeyScaleLevelVolume(oper);
+ writeFeedbackFM(oper);
+ writeAttackDecay(oper);
+ writeSustainRelease(oper);
+ writeTremoloVibratoSustainingKeyScaleRateFreqMulti(oper);
+ writeWaveSelect(oper);
+}
- timbres.close();
+void AdLib::initOperatorParams() {
+ for (int i = 0; i < kOperatorCount; i++)
+ setOperatorParams(i, kPianoParams[kOperatorType[i]], kPianoParams[kOperatorType[i]][kParamCount - 1]);
- return loaded;
+ if (isPercussionMode()) {
+ setOperatorParams(12, kBaseDrumParams [0], kBaseDrumParams [0][kParamCount - 1]);
+ setOperatorParams(15, kBaseDrumParams [1], kBaseDrumParams [1][kParamCount - 1]);
+ setOperatorParams(16, kSnareDrumParams , kSnareDrumParams [kParamCount - 1]);
+ setOperatorParams(14, kTomParams , kTomParams [kParamCount - 1]);
+ setOperatorParams(17, kCymbalParams , kCymbalParams [kParamCount - 1]);
+ setOperatorParams(13, kHihatParams , kHihatParams [kParamCount - 1]);
+ }
}
-void MDYPlayer::unload() {
- unloadTBR();
- unloadMDY();
+void AdLib::initOperatorVolumes() {
+ for(int i = 0; i < kOperatorCount; i++)
+ _operatorVolume[i] = kMaxVolume;
}
-void MDYPlayer::unloadMDY() {
- AdLib::unload();
+void AdLib::setOperatorParams(uint8 oper, const uint16 *params, uint8 wave) {
+ byte *operParams = _operatorParams[oper];
+
+ for (int i = 0; i < (kParamCount - 1); i++)
+ operParams[i] = params[i];
+
+ operParams[kParamCount - 1] = wave & 0x03;
+
+ writeAllParams(oper);
+}
+
+void AdLib::voiceOff(uint8 voice) {
+ writeOPL(0xA0 + voice, 0);
+ writeOPL(0xB0 + voice, 0);
}
-void MDYPlayer::unloadTBR() {
- delete[] _timbres;
+int32 AdLib::calcFreq(int32 deltaDemiToneNum, int32 deltaDemiToneDenom) {
+ int32 freq = 0;
- _timbres = 0;
- _timbresSize = 0;
+ freq = ((deltaDemiToneDenom * 100) + 6 * deltaDemiToneNum) * 52088;
+ freq /= deltaDemiToneDenom * 2500;
+
+ return (freq * 147456) / 111875;
}
-void MDYPlayer::interpret() {
- unsigned char instr;
- byte channel;
- byte note;
- byte volume;
- uint8 tempoMult, tempoFrac;
- uint8 ctrlByte1, ctrlByte2;
- uint8 timbre;
+void AdLib::setFreqs(uint16 *freqs, int32 num, int32 denom) {
+ int32 val = calcFreq(num, denom);
-// TODO : Verify the loop for percussive mode (11 ?)
- if (_first) {
- for (int i = 0; i < 9; i ++)
- setVolume(i, 0);
+ *freqs++ = (4 + val) >> 3;
-// TODO : Set pitch range
+ for (int i = 1; i < kHalfToneCount; i++) {
+ val = (val * 106) / 100;
- _tempo = _basicTempo;
- _wait = *(_playPos++);
- _first = false;
+ *freqs++ = (4 + val) >> 3;
}
- do {
- instr = *_playPos;
- debugC(6, kDebugSound, "MDYPlayer::interpret instr 0x%X", instr);
- switch (instr) {
- case 0xF8:
- _wait = *(_playPos++);
- break;
- case 0xFC:
- _ended = true;
- _samplesTillPoll = 0;
- return;
- case 0xF0:
- _playPos++;
- ctrlByte1 = *(_playPos++);
- ctrlByte2 = *(_playPos++);
- debugC(6, kDebugSound, "MDYPlayer::interpret ctrlBytes 0x%X 0x%X", ctrlByte1, ctrlByte2);
- if (ctrlByte1 != 0x7F || ctrlByte2 != 0) {
- _playPos -= 2;
- while (*(_playPos++) != 0xF7)
- ;
- } else {
- tempoMult = *(_playPos++);
- tempoFrac = *(_playPos++);
- _tempo = _basicTempo * tempoMult + (unsigned)(((long)_basicTempo * tempoFrac) >> 7);
- _playPos++;
- }
- _wait = *(_playPos++);
- break;
- default:
- if (instr >= 0x80) {
- _playPos++;
- }
- channel = (int)(instr & 0x0f);
-
- switch (instr & 0xf0) {
- case 0x90:
- note = *(_playPos++);
- volume = *(_playPos++);
- _pollNotes[channel] = note;
- setVolume(channel, volume);
- setKey(channel, note, true, false);
- break;
- case 0x80:
- _playPos += 2;
- note = _pollNotes[channel];
- setKey(channel, note, false, false);
- break;
- case 0xA0:
- setVolume(channel, *(_playPos++));
- break;
- case 0xC0:
- timbre = *(_playPos++);
- setVoice(channel, timbre, false);
- break;
- case 0xE0:
- warning("MDYPlayer: Pitch bend not yet implemented");
+}
- note = *(_playPos)++;
- note += (unsigned)(*(_playPos++)) << 7;
+void AdLib::initFreqs() {
+ const int numStep = 100 / kPitchStepCount;
- setKey(channel, note, _notOn[channel], true);
+ for (int i = 0; i < kPitchStepCount; i++)
+ setFreqs(_freqs[i], i * numStep, 100);
- break;
- case 0xB0:
- _playPos += 2;
- break;
- case 0xD0:
- _playPos++;
- break;
- default:
- warning("MDYPlayer: Bad MIDI instr byte: 0%X", instr);
- while ((*_playPos) < 0x80)
- _playPos++;
- if (*_playPos != 0xF8)
- _playPos--;
- break;
- } //switch instr & 0xF0
- _wait = *(_playPos++);
- break;
- } //switch instr
- } while (_wait == 0);
-
- if (_wait == 0xF8) {
- _wait = 0xF0;
- if (*_playPos != 0xF8)
- _wait += *(_playPos++) & 0x0F;
+ resetFreqs();
+}
+
+void AdLib::resetFreqs() {
+ for (int i = 0; i < kMaxVoiceCount; i++) {
+ _freqPtr [i] = _freqs[0];
+ _halfToneOffset[i] = 0;
}
-// _playPos++;
- _samplesTillPoll = _wait * (_rate / 1000);
}
-void MDYPlayer::reset() {
- AdLib::reset();
+void AdLib::changePitch(uint8 voice, uint16 pitchBend) {
+
+ int full = 0;
+ int frac = 0;
+ int amount = ((pitchBend - kMidPitch) * _pitchRangeStep) / kMidPitch;
+
+ if (amount >= 0) {
+ // Bend up
+
+ full = amount / kPitchStepCount;
+ frac = amount % kPitchStepCount;
-// _soundMode 1 : Percussive mode.
- if (_soundMode == 1) {
- writeOPL(0xA6, 0);
- writeOPL(0xB6, 0);
- writeOPL(0xA7, 0);
- writeOPL(0xB7, 0);
- writeOPL(0xA8, 0);
- writeOPL(0xB8, 0);
+ } else {
+ // Bend down
+
+ amount = kPitchStepCount - 1 - amount;
+
+ full = -(amount / kPitchStepCount);
+ frac = (amount - kPitchStepCount + 1) % kPitchStepCount;
+ if (frac)
+ frac = kPitchStepCount - frac;
-// TODO set the correct frequency for the last 4 percussive voices
}
+
+ _halfToneOffset[voice] = full;
+ _freqPtr [voice] = _freqs[frac];
}
-void MDYPlayer::rewind() {
- _playPos = _data;
-}
-
-void MDYPlayer::setVoices() {
- byte *timbrePtr;
-
- timbrePtr = _timbres;
- debugC(6, kDebugSound, "MDYPlayer::setVoices TBR version: %X.%X", timbrePtr[0], timbrePtr[1]);
- timbrePtr += 2;
-
- _tbrCount = READ_LE_UINT16(timbrePtr);
- debugC(6, kDebugSound, "MDYPlayer::setVoices Timbres counter: %d", _tbrCount);
- timbrePtr += 2;
- _tbrStart = READ_LE_UINT16(timbrePtr);
-
- timbrePtr += 2;
- for (int i = 0; i < _tbrCount; i++)
- setVoice(i, i, true);
-}
-
-void MDYPlayer::setVoice(byte voice, byte instr, bool set) {
-// uint16 strct[27];
- uint8 strct[27];
- byte channel;
- byte *timbrePtr;
- char timbreName[10];
-
- timbreName[9] = '\0';
- for (int j = 0; j < 9; j++)
- timbreName[j] = _timbres[6 + j + (instr * 9)];
- debugC(6, kDebugSound, "MDYPlayer::setVoice Loading timbre %s", timbreName);
-
- // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26
- // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27
- for (int i = 0; i < 2; i++) {
- timbrePtr = _timbres + _tbrStart + instr * 0x38 + i * 0x1A;
- for (int j = 0; j < 27; j++) {
- if (timbrePtr >= (_timbres + _timbresSize)) {
- warning("MDYPlayer: Instrument %d out of range (%d, %d)", instr,
- (uint32) (timbrePtr - _timbres), _timbresSize);
- strct[j] = 0;
- } else
- //strct[j] = READ_LE_UINT16(timbrePtr);
- strct[j] = timbrePtr[0];
- //timbrePtr += 2;
- timbrePtr++;
- }
- channel = _operators[voice] + i * 3;
- writeOPL(0xBD, 0x00);
- writeOPL(0x08, 0x00);
- writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F));
- if (!i)
- writeOPL(0xC0 | voice,
- ((strct[2] & 7) << 1) | (1 - (strct[12] & 1)));
- writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF));
- writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF));
- writeOPL(0x20 | channel, ((strct[9] & 1) << 7) |
- ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) |
- ((strct[11] & 1) << 4) | (strct[1] & 0xF));
- if (!i)
- writeOPL(0xE0 | channel, (strct[26] & 3));
- else {
- writeOPL(0xE0 | channel, (strct[14] & 3));
- writeOPL(0x40 | channel, 0);
- }
- }
+void AdLib::setFreq(uint8 voice, uint16 note, bool on) {
+ _voiceOn [voice] = on;
+ _voiceNote[voice] = note;
+
+ note = CLIP<int>(note + _halfToneOffset[voice], 0, kNoteCount - 1);
+
+ uint16 freq = _freqPtr[voice][note % kHalfToneCount];
+
+ uint8 value = 0;
+ value |= on ? 0x20 : 0;
+ value |= ((note / kHalfToneCount) << 2) | ((freq >> 8) & 0x03);
+
+ writeOPL(0xA0 + voice, freq);
+ writeOPL(0xB0 + voice, value);
}
} // End of namespace Gob
diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h
index 934e9966eb..bd1778d2ed 100644
--- a/engines/gob/sound/adlib.h
+++ b/engines/gob/sound/adlib.h
@@ -24,148 +24,282 @@
#define GOB_SOUND_ADLIB_H
#include "common/mutex.h"
+
#include "audio/audiostream.h"
#include "audio/mixer.h"
-#include "audio/fmopl.h"
-namespace Gob {
+namespace OPL {
+ class OPL;
+}
-class GobEngine;
+namespace Gob {
+/** Base class for a player of an AdLib music format. */
class AdLib : public Audio::AudioStream {
public:
AdLib(Audio::Mixer &mixer);
virtual ~AdLib();
- bool isPlaying() const;
- int getIndex() const;
- bool getRepeating() const;
+ bool isPlaying() const; ///< Are we currently playing?
+ int32 getRepeating() const; ///< Return number of times left to loop.
+ /** Set the loop counter.
+ *
+ * @param repCount Number of times to loop (i.e. number of additional
+ * paythroughs to the first one, not overall).
+ * A negative value means infinite looping.
+ */
void setRepeating(int32 repCount);
void startPlay();
void stopPlay();
- virtual void unload();
-
// AudioStream API
int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const { return false; }
- bool endOfData() const { return !_playing; }
- bool endOfStream() const { return false; }
- int getRate() const { return _rate; }
+ bool isStereo() const;
+ bool endOfData() const;
+ bool endOfStream() const;
+ int getRate() const;
protected:
- static const unsigned char _operators[];
- static const unsigned char _volRegNums [];
+ enum kVoice {
+ kVoiceMelody0 = 0,
+ kVoiceMelody1 = 1,
+ kVoiceMelody2 = 2,
+ kVoiceMelody3 = 3,
+ kVoiceMelody4 = 4,
+ kVoiceMelody5 = 5,
+ kVoiceMelody6 = 6, // Only available in melody mode.
+ kVoiceMelody7 = 7, // Only available in melody mode.
+ kVoiceMelody8 = 8, // Only available in melody mode.
+ kVoiceBaseDrum = 6, // Only available in percussion mode.
+ kVoiceSnareDrum = 7, // Only available in percussion mode.
+ kVoiceTom = 8, // Only available in percussion mode.
+ kVoiceCymbal = 9, // Only available in percussion mode.
+ kVoiceHihat = 10 // Only available in percussion mode.
+ };
+
+ /** Operator parameters. */
+ enum kParam {
+ kParamKeyScaleLevel = 0,
+ kParamFreqMulti = 1,
+ kParamFeedback = 2,
+ kParamAttack = 3,
+ kParamSustain = 4,
+ kParamSustaining = 5,
+ kParamDecay = 6,
+ kParamRelease = 7,
+ kParamLevel = 8,
+ kParamAM = 9,
+ kParamVib = 10,
+ kParamKeyScaleRate = 11,
+ kParamFM = 12,
+ kParamWaveSelect = 13
+ };
+
+ static const int kOperatorCount = 18; ///< Number of operators.
+ static const int kParamCount = 14; ///< Number of operator parameters.
+ static const int kPitchStepCount = 25; ///< Number of pitch bend steps in a half tone.
+ static const int kOctaveCount = 8; ///< Number of octaves we can play.
+ static const int kHalfToneCount = 12; ///< Number of half tones in an octave.
+
+ static const int kOperatorsPerVoice = 2; ///< Number of operators per voice.
+
+ static const int kMelodyVoiceCount = 9; ///< Number of melody voices.
+ static const int kPercussionVoiceCount = 5; ///< Number of percussion voices.
+ static const int kMaxVoiceCount = 11; ///< Max number of voices.
+
+ /** Number of notes we can play. */
+ static const int kNoteCount = kHalfToneCount * kOctaveCount;
+
+ static const int kMaxVolume = 0x007F;
+ static const int kMaxPitch = 0x3FFF;
+ static const int kMidPitch = 0x2000;
+
+ static const int kStandardMidC = 60; ///< A mid C in standard MIDI.
+ static const int kOPLMidC = 48; ///< A mid C for the OPL.
+
+
+ /** Return the number of samples per second. */
+ uint32 getSamplesPerSecond() const;
+
+ /** Write a value into an OPL register. */
+ void writeOPL(byte reg, byte val);
+
+ /** Signal that the playback ended.
+ *
+ * @param killRepeat Explicitly request that the song is not to be looped.
+ */
+ void end(bool killRepeat = false);
+
+ /** The callback function that's called for polling more AdLib commands.
+ *
+ * @param first Is this the first poll since the start of the song?
+ * @return The number of samples until the next poll.
+ */
+ virtual uint32 pollMusic(bool first) = 0;
+
+ /** Rewind the song. */
+ virtual void rewind() = 0;
+
+ /** Return whether we're in percussion mode. */
+ bool isPercussionMode() const;
+
+ /** Set percussion or melody mode. */
+ void setPercussionMode(bool percussion);
+
+ /** Enable/Disable the wave select operator parameters.
+ *
+ * When disabled, all operators use the sine wave, regardless of the parameter.
+ */
+ void enableWaveSelect(bool enable);
+
+ /** Change the pitch bend range.
+ *
+ * @param range The range in half tones from 1 to 12 inclusive.
+ * See bendVoicePitch() for how this works in practice.
+ */
+ void setPitchRange(uint8 range);
+
+ /** Set the tremolo (amplitude vibrato) depth.
+ *
+ * @param tremoloDepth false: 1.0dB, true: 4.8dB.
+ */
+ void setTremoloDepth(bool tremoloDepth);
+
+ /** Set the frequency vibrato depth.
+ *
+ * @param vibratoDepth false: 7 cent, true: 14 cent. 1 cent = 1/100 half tone.
+ */
+ void setVibratoDepth(bool vibratoDepth);
+
+ /** Set the keyboard split point. */
+ void setKeySplit(bool keySplit);
+
+ /** Set the timbre of a voice.
+ *
+ * Layout of the operator parameters is as follows:
+ * - First 13 parameter for the first operator
+ * - First 13 parameter for the second operator
+ * - 14th parameter (wave select) for the first operator
+ * - 14th parameter (wave select) for the second operator
+ */
+ void setVoiceTimbre(uint8 voice, const uint16 *params);
+
+ /** Set a voice's volume. */
+ void setVoiceVolume(uint8 voice, uint8 volume);
+
+ /** Bend a voice's pitch.
+ *
+ * The pitchBend parameter is a value between 0 (full down) and kMaxPitch (full up).
+ * The actual frequency depends on the pitch range set previously by setPitchRange(),
+ * with full down being -range half tones and full up range half tones.
+ */
+ void bendVoicePitch(uint8 voice, uint16 pitchBend);
+
+ /** Switch a voice on.
+ *
+ * Plays one of the kNoteCount notes. However, the valid range of a note is between
+ * 0 and 127, of which only 12 to 107 are audible.
+ */
+ void noteOn(uint8 voice, uint8 note);
+
+ /** Switch a voice off. */
+ void noteOff(uint8 voice);
+
+private:
+ static const uint8 kOperatorType [kOperatorCount];
+ static const uint8 kOperatorOffset[kOperatorCount];
+ static const uint8 kOperatorVoice [kOperatorCount];
+
+ static const uint8 kVoiceMelodyOperator [kOperatorsPerVoice][kMelodyVoiceCount];
+ static const uint8 kVoicePercussionOperator[kOperatorsPerVoice][kPercussionVoiceCount];
+
+ static const byte kPercussionMasks[kPercussionVoiceCount];
+
+ static const uint16 kPianoParams [kOperatorsPerVoice][kParamCount];
+ static const uint16 kBaseDrumParams [kOperatorsPerVoice][kParamCount];
+
+ static const uint16 kSnareDrumParams[kParamCount];
+ static const uint16 kTomParams [kParamCount];
+ static const uint16 kCymbalParams [kParamCount];
+ static const uint16 kHihatParams [kParamCount];
+
Audio::Mixer *_mixer;
Audio::SoundHandle _handle;
- FM_OPL *_opl;
+ OPL::OPL *_opl;
Common::Mutex _mutex;
uint32 _rate;
- byte *_data;
- byte *_playPos;
- uint32 _dataSize;
-
- short _freqs[25][12];
- byte _notes[11];
- byte _notCol[11];
- byte _notLin[11];
- bool _notOn[11];
- byte _pollNotes[16];
+ uint32 _toPoll;
- int _samplesTillPoll;
int32 _repCount;
- bool _playing;
bool _first;
+ bool _playing;
bool _ended;
- bool _freeData;
+ bool _tremoloDepth;
+ bool _vibratoDepth;
+ bool _keySplit;
- int _index;
+ bool _enableWaveSelect;
- unsigned char _wait;
- uint8 _tickBeat;
- uint8 _beatMeasure;
- uint32 _totalTick;
- uint32 _nrCommand;
- uint16 _pitchBendRangeStep;
- uint16 _basicTempo, _tempo;
+ bool _percussionMode;
+ byte _percussionBits;
- void writeOPL(byte reg, byte val);
- void setFreqs();
- void setKey(byte voice, byte note, bool on, bool spec);
- void setVolume(byte voice, byte volume);
- void pollMusic();
+ uint8 _pitchRange;
+ uint16 _pitchRangeStep;
- virtual void interpret() = 0;
+ uint8 _voiceNote[kMaxVoiceCount]; // Last note of each voice
+ uint8 _voiceOn [kMaxVoiceCount]; // Whether each voice is currently on
- virtual void reset();
- virtual void rewind() = 0;
- virtual void setVoices() = 0;
+ uint8 _operatorVolume[kOperatorCount]; // Volume of each operator
-private:
- void init();
-};
+ byte _operatorParams[kOperatorCount][kParamCount]; // All operator parameters
-class ADLPlayer : public AdLib {
-public:
- ADLPlayer(Audio::Mixer &mixer);
- ~ADLPlayer();
+ uint16 _freqs[kPitchStepCount][kHalfToneCount];
+ uint16 *_freqPtr[kMaxVoiceCount];
- bool load(const char *fileName);
- bool load(byte *data, uint32 size, int index = -1);
+ int _halfToneOffset[kMaxVoiceCount];
- void unload();
-protected:
- void interpret();
+ void createOPL();
+ void initOPL();
void reset();
- void rewind();
+ void allOff();
- void setVoices();
- void setVoice(byte voice, byte instr, bool set);
-};
+ // Write global parameters into the OPL
+ void writeTremoloVibratoDepthPercMode();
+ void writeKeySplit();
-class MDYPlayer : public AdLib {
-public:
- MDYPlayer(Audio::Mixer &mixer);
- ~MDYPlayer();
-
- bool loadMDY(const char *fileName);
- bool loadMDY(Common::SeekableReadStream &stream);
- bool loadTBR(const char *fileName);
- bool loadTBR(Common::SeekableReadStream &stream);
-
- void unload();
-
-protected:
- byte _soundMode;
-
- byte *_timbres;
- uint16 _tbrCount;
- uint16 _tbrStart;
- uint32 _timbresSize;
+ // Write operator parameters into the OPL
+ void writeWaveSelect(uint8 oper);
+ void writeTremoloVibratoSustainingKeyScaleRateFreqMulti(uint8 oper);
+ void writeSustainRelease(uint8 oper);
+ void writeAttackDecay(uint8 oper);
+ void writeFeedbackFM(uint8 oper);
+ void writeKeyScaleLevelVolume(uint8 oper);
+ void writeAllParams(uint8 oper);
- void interpret();
+ void initOperatorParams();
+ void initOperatorVolumes();
+ void setOperatorParams(uint8 oper, const uint16 *params, uint8 wave);
- void reset();
- void rewind();
+ void voiceOff(uint8 voice);
- void setVoices();
- void setVoice(byte voice, byte instr, bool set);
+ void initFreqs();
+ void setFreqs(uint16 *freqs, int32 num, int32 denom);
+ int32 calcFreq(int32 deltaDemiToneNum, int32 deltaDemiToneDenom);
+ void resetFreqs();
- void unloadTBR();
- void unloadMDY();
+ void changePitch(uint8 voice, uint16 pitchBend);
-private:
- void init();
+ void setFreq(uint8 voice, uint16 note, bool on);
};
} // End of namespace Gob
diff --git a/engines/gob/sound/adlplayer.cpp b/engines/gob/sound/adlplayer.cpp
new file mode 100644
index 0000000000..ee23191c0d
--- /dev/null
+++ b/engines/gob/sound/adlplayer.cpp
@@ -0,0 +1,257 @@
+/* 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/stream.h"
+#include "common/memstream.h"
+#include "common/textconsole.h"
+
+#include "gob/sound/adlplayer.h"
+
+namespace Gob {
+
+ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer),
+ _songData(0), _songDataSize(0), _playPos(0) {
+
+}
+
+ADLPlayer::~ADLPlayer() {
+ unload();
+}
+
+void ADLPlayer::unload() {
+ stopPlay();
+
+ _timbres.clear();
+
+ delete[] _songData;
+
+ _songData = 0;
+ _songDataSize = 0;
+
+ _playPos = 0;
+}
+
+uint32 ADLPlayer::pollMusic(bool first) {
+ if (_timbres.empty() || !_songData || !_playPos || (_playPos >= (_songData + _songDataSize))) {
+ end();
+ return 0;
+ }
+
+ // We'll ignore the first delay
+ if (first)
+ _playPos += (*_playPos & 0x80) ? 2 : 1;
+
+ byte cmd = *_playPos++;
+
+ // Song end marker
+ if (cmd == 0xFF) {
+ end();
+ return 0;
+ }
+
+ // Set the instrument that should be modified
+ if (cmd == 0xFE)
+ _modifyInstrument = *_playPos++;
+
+ if (cmd >= 0xD0) {
+ // Modify an instrument
+
+ if (_modifyInstrument == 0xFF)
+ warning("ADLPlayer: No instrument to modify");
+ else if (_modifyInstrument >= _timbres.size())
+ warning("ADLPlayer: Can't modify invalid instrument %d (%d)", _modifyInstrument, _timbres.size());
+ else
+ _timbres[_modifyInstrument].params[_playPos[0]] = _playPos[1];
+
+ _playPos += 2;
+
+ // If we currently have that instrument loaded, reload it
+ for (int i = 0; i < kMaxVoiceCount; i++)
+ if (_currentInstruments[i] == _modifyInstrument)
+ setInstrument(i, _modifyInstrument);
+ } else {
+ // Voice command
+
+ uint8 voice = cmd & 0x0F;
+ uint8 note, volume;
+
+ switch (cmd & 0xF0) {
+ case 0x00: // Note on with volume
+ note = *_playPos++;
+ volume = *_playPos++;
+
+ setVoiceVolume(voice, volume);
+ noteOn(voice, note);
+ break;
+
+ case 0xA0: // Pitch bend
+ bendVoicePitch(voice, ((uint16)*_playPos++) << 7);
+ break;
+
+ case 0xB0: // Set volume
+ setVoiceVolume(voice, *_playPos++);
+ break;
+
+ case 0xC0: // Set instrument
+ setInstrument(voice, *_playPos++);
+ break;
+
+ case 0x90: // Note on
+ noteOn(voice, *_playPos++);
+ break;
+
+ case 0x80: // Note off
+ noteOff(voice);
+ break;
+
+ default:
+ warning("ADLPlayer: Unsupported command: 0x%02X. Stopping playback.", cmd);
+ end(true);
+ return 0;
+ }
+ }
+
+ uint16 delay = *_playPos++;
+
+ if (delay & 0x80)
+ delay = ((delay & 3) << 8) | *_playPos++;
+
+ return getSampleDelay(delay);
+}
+
+uint32 ADLPlayer::getSampleDelay(uint16 delay) const {
+ if (delay == 0)
+ return 0;
+
+ return ((uint32)delay * getSamplesPerSecond()) / 1000;
+}
+
+void ADLPlayer::rewind() {
+ // Reset song data
+ _playPos = _songData;
+
+ // Set melody/percussion mode
+ setPercussionMode(_soundMode != 0);
+
+ // Reset instruments
+ for (Common::Array<Timbre>::iterator t = _timbres.begin(); t != _timbres.end(); ++t)
+ memcpy(t->params, t->startParams, kOperatorsPerVoice * kParamCount * sizeof(uint16));
+
+ for (int i = 0; i < kMaxVoiceCount; i++)
+ _currentInstruments[i] = 0;
+
+ // Reset voices
+ int numVoice = MIN<int>(_timbres.size(), _soundMode ? (int)kMaxVoiceCount : (int)kMelodyVoiceCount);
+ for (int i = 0; i < numVoice; i++) {
+ setInstrument(i, _currentInstruments[i]);
+ setVoiceVolume(i, kMaxVolume);
+ }
+
+ _modifyInstrument = 0xFF;
+}
+
+bool ADLPlayer::load(Common::SeekableReadStream &adl) {
+ unload();
+
+ int timbreCount;
+ if (!readHeader(adl, timbreCount)) {
+ unload();
+ return false;
+ }
+
+ if (!readTimbres(adl, timbreCount) || !readSongData(adl) || adl.err()) {
+ unload();
+ return false;
+ }
+
+ rewind();
+
+ return true;
+}
+
+bool ADLPlayer::readHeader(Common::SeekableReadStream &adl, int &timbreCount) {
+ // Sanity check
+ if (adl.size() < 60) {
+ warning("ADLPlayer::readHeader(): File too small (%d)", adl.size());
+ return false;
+ }
+
+ _soundMode = adl.readByte();
+ timbreCount = adl.readByte() + 1;
+
+ adl.skip(1);
+
+ return true;
+}
+
+bool ADLPlayer::readTimbres(Common::SeekableReadStream &adl, int timbreCount) {
+ _timbres.resize(timbreCount);
+ for (Common::Array<Timbre>::iterator t = _timbres.begin(); t != _timbres.end(); ++t) {
+ for (int i = 0; i < (kOperatorsPerVoice * kParamCount); i++)
+ t->startParams[i] = adl.readUint16LE();
+ }
+
+ if (adl.err()) {
+ warning("ADLPlayer::readTimbres(): Read failed");
+ return false;
+ }
+
+ return true;
+}
+
+bool ADLPlayer::readSongData(Common::SeekableReadStream &adl) {
+ _songDataSize = adl.size() - adl.pos();
+ _songData = new byte[_songDataSize];
+
+ if (adl.read(_songData, _songDataSize) != _songDataSize) {
+ warning("ADLPlayer::readSongData(): Read failed");
+ return false;
+ }
+
+ return true;
+}
+
+bool ADLPlayer::load(const byte *data, uint32 dataSize, int index) {
+ unload();
+
+ Common::MemoryReadStream stream(data, dataSize);
+ if (!load(stream))
+ return false;
+
+ _index = index;
+ return true;
+}
+
+void ADLPlayer::setInstrument(int voice, int instrument) {
+ if ((voice >= kMaxVoiceCount) || ((uint)instrument >= _timbres.size()))
+ return;
+
+ _currentInstruments[voice] = instrument;
+
+ setVoiceTimbre(voice, _timbres[instrument].params);
+}
+
+int ADLPlayer::getIndex() const {
+ return _index;
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/sound/adlplayer.h b/engines/gob/sound/adlplayer.h
new file mode 100644
index 0000000000..9596447bbc
--- /dev/null
+++ b/engines/gob/sound/adlplayer.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 GOB_SOUND_ADLPLAYER_H
+#define GOB_SOUND_ADLPLAYER_H
+
+#include "common/array.h"
+
+#include "gob/sound/adlib.h"
+
+namespace Common {
+ class SeekableReadStream;
+}
+
+namespace Gob {
+
+/** A player for Coktel Vision's ADL music format. */
+class ADLPlayer : public AdLib {
+public:
+ ADLPlayer(Audio::Mixer &mixer);
+ ~ADLPlayer();
+
+ bool load(Common::SeekableReadStream &adl);
+ bool load(const byte *data, uint32 dataSize, int index = -1);
+ void unload();
+
+ int getIndex() const;
+
+protected:
+ // AdLib interface
+ uint32 pollMusic(bool first);
+ void rewind();
+
+private:
+ struct Timbre {
+ uint16 startParams[kOperatorsPerVoice * kParamCount];
+ uint16 params[kOperatorsPerVoice * kParamCount];
+ };
+
+ uint8 _soundMode;
+
+ Common::Array<Timbre> _timbres;
+
+ byte *_songData;
+ uint32 _songDataSize;
+
+ const byte *_playPos;
+
+ int _index;
+
+ uint8 _modifyInstrument;
+ uint16 _currentInstruments[kMaxVoiceCount];
+
+
+ void setInstrument(int voice, int instrument);
+
+ bool readHeader (Common::SeekableReadStream &adl, int &timbreCount);
+ bool readTimbres (Common::SeekableReadStream &adl, int timbreCount);
+ bool readSongData(Common::SeekableReadStream &adl);
+
+ uint32 getSampleDelay(uint16 delay) const;
+};
+
+} // End of namespace Gob
+
+#endif // GOB_SOUND_ADLPLAYER_H
diff --git a/engines/gob/sound/musplayer.cpp b/engines/gob/sound/musplayer.cpp
new file mode 100644
index 0000000000..3e41dc6ed1
--- /dev/null
+++ b/engines/gob/sound/musplayer.cpp
@@ -0,0 +1,391 @@
+/* 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/stream.h"
+#include "common/textconsole.h"
+
+#include "gob/sound/musplayer.h"
+
+namespace Gob {
+
+MUSPlayer::MUSPlayer(Audio::Mixer &mixer) : AdLib(mixer),
+ _songData(0), _songDataSize(0), _playPos(0), _songID(0) {
+
+}
+
+MUSPlayer::~MUSPlayer() {
+ unload();
+}
+
+void MUSPlayer::unload() {
+ stopPlay();
+
+ unloadSND();
+ unloadMUS();
+}
+
+uint32 MUSPlayer::getSampleDelay(uint16 delay) const {
+ if (delay == 0)
+ return 0;
+
+ uint32 freq = (_ticksPerBeat * _tempo) / 60;
+
+ return ((uint32)delay * getSamplesPerSecond()) / freq;
+}
+
+void MUSPlayer::skipToTiming() {
+ while (*_playPos < 0x80)
+ _playPos++;
+
+ if (*_playPos != 0xF8)
+ _playPos--;
+}
+
+uint32 MUSPlayer::pollMusic(bool first) {
+ if (_timbres.empty() || !_songData || !_playPos || (_playPos >= (_songData + _songDataSize))) {
+ end();
+ return 0;
+ }
+
+ if (first)
+ return getSampleDelay(*_playPos++);
+
+ uint16 delay = 0;
+ while (delay == 0) {
+ byte cmd = *_playPos;
+
+ // Delay overflow
+ if (cmd == 0xF8) {
+ _playPos++;
+ delay = 0xF8;
+ break;
+ }
+
+ // Song end marker
+ if (cmd == 0xFC) {
+ end();
+ return 0;
+ }
+
+ // Global command
+ if (cmd == 0xF0) {
+ _playPos++;
+
+ byte type1 = *_playPos++;
+ byte type2 = *_playPos++;
+
+ if ((type1 == 0x7F) && (type2 == 0)) {
+ // Tempo change, as a fraction of the base tempo
+
+ uint32 num = *_playPos++;
+ uint32 denom = *_playPos++;
+
+ _tempo = _baseTempo * num + ((_baseTempo * denom) >> 7);
+
+ _playPos++;
+ } else {
+
+ // Unsupported global command, skip it
+ _playPos -= 2;
+ while(*_playPos++ != 0xF7)
+ ;
+ }
+
+ delay = *_playPos++;
+ break;
+ }
+
+ // Voice command
+
+ if (cmd >= 0x80) {
+ _playPos++;
+
+ _lastCommand = cmd;
+ } else
+ cmd = _lastCommand;
+
+ uint8 voice = cmd & 0x0F;
+ uint8 note, volume;
+ uint16 pitch;
+
+ switch (cmd & 0xF0) {
+ case 0x80: // Note off
+ _playPos += 2;
+ noteOff(voice);
+ break;
+
+ case 0x90: // Note on
+ note = *_playPos++;
+ volume = *_playPos++;
+
+ if (volume) {
+ setVoiceVolume(voice, volume);
+ noteOn(voice, note);
+ } else
+ noteOff(voice);
+ break;
+
+ case 0xA0: // Set volume
+ setVoiceVolume(voice, *_playPos++);
+ break;
+
+ case 0xB0:
+ _playPos += 2;
+ break;
+
+ case 0xC0: // Set instrument
+ setInstrument(voice, *_playPos++);
+ break;
+
+ case 0xD0:
+ _playPos++;
+ break;
+
+ case 0xE0: // Pitch bend
+ pitch = *_playPos++;
+ pitch += *_playPos++ << 7;
+ bendVoicePitch(voice, pitch);
+ break;
+
+ default:
+ warning("MUSPlayer: Unsupported command: 0x%02X", cmd);
+ skipToTiming();
+ break;
+ }
+
+ delay = *_playPos++;
+ }
+
+ if (delay == 0xF8) {
+ delay = 240;
+
+ if (*_playPos != 0xF8)
+ delay += *_playPos++;
+ }
+
+ return getSampleDelay(delay);
+}
+
+void MUSPlayer::rewind() {
+ _playPos = _songData;
+ _tempo = _baseTempo;
+
+ _lastCommand = 0;
+
+ setPercussionMode(_soundMode != 0);
+ setPitchRange(_pitchBendRange);
+}
+
+bool MUSPlayer::loadSND(Common::SeekableReadStream &snd) {
+ unloadSND();
+
+ int timbreCount, timbrePos;
+ if (!readSNDHeader(snd, timbreCount, timbrePos))
+ return false;
+
+ if (!readSNDTimbres(snd, timbreCount, timbrePos) || snd.err()) {
+ unloadSND();
+ return false;
+ }
+
+ return true;
+}
+
+bool MUSPlayer::readString(Common::SeekableReadStream &stream, Common::String &string, byte *buffer, uint size) {
+ if (stream.read(buffer, size) != size)
+ return false;
+
+ buffer[size] = '\0';
+
+ string = (char *) buffer;
+
+ return true;
+}
+
+bool MUSPlayer::readSNDHeader(Common::SeekableReadStream &snd, int &timbreCount, int &timbrePos) {
+ // Sanity check
+ if (snd.size() <= 6) {
+ warning("MUSPlayer::readSNDHeader(): File too small (%d)", snd.size());
+ return false;
+ }
+
+ // Version
+ const uint8 versionMajor = snd.readByte();
+ const uint8 versionMinor = snd.readByte();
+
+ if ((versionMajor != 1) && (versionMinor != 0)) {
+ warning("MUSPlayer::readSNDHeader(): Unsupported version %d.%d", versionMajor, versionMinor);
+ return false;
+ }
+
+ // Number of timbres and where they start
+ timbreCount = snd.readUint16LE();
+ timbrePos = snd.readUint16LE();
+
+ const uint16 minTimbrePos = 6 + timbreCount * 9;
+
+ // Sanity check
+ if (timbrePos < minTimbrePos) {
+ warning("MUSPlayer::readSNDHeader(): Timbre offset too small: %d < %d", timbrePos, minTimbrePos);
+ return false;
+ }
+
+ const uint32 timbreParametersSize = snd.size() - timbrePos;
+ const uint32 paramSize = kOperatorsPerVoice * kParamCount * sizeof(uint16);
+
+ // Sanity check
+ if (timbreParametersSize != (timbreCount * paramSize)) {
+ warning("MUSPlayer::loadSND(): Timbre parameters size mismatch: %d != %d",
+ timbreParametersSize, timbreCount * paramSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool MUSPlayer::readSNDTimbres(Common::SeekableReadStream &snd, int timbreCount, int timbrePos) {
+ _timbres.resize(timbreCount);
+
+ // Read names
+ byte nameBuffer[10];
+ for (Common::Array<Timbre>::iterator t = _timbres.begin(); t != _timbres.end(); ++t) {
+ if (!readString(snd, t->name, nameBuffer, 9)) {
+ warning("MUSPlayer::readMUSTimbres(): Failed to read timbre name");
+ return false;
+ }
+ }
+
+ if (!snd.seek(timbrePos)) {
+ warning("MUSPlayer::readMUSTimbres(): Failed to seek to timbres");
+ return false;
+ }
+
+ // Read parameters
+ for (Common::Array<Timbre>::iterator t = _timbres.begin(); t != _timbres.end(); ++t) {
+ for (int i = 0; i < (kOperatorsPerVoice * kParamCount); i++)
+ t->params[i] = snd.readUint16LE();
+ }
+
+ return true;
+}
+
+bool MUSPlayer::loadMUS(Common::SeekableReadStream &mus) {
+ unloadMUS();
+
+ if (!readMUSHeader(mus) || !readMUSSong(mus) || mus.err()) {
+ unloadMUS();
+ return false;
+ }
+
+ rewind();
+
+ return true;
+}
+
+bool MUSPlayer::readMUSHeader(Common::SeekableReadStream &mus) {
+ // Sanity check
+ if (mus.size() <= 6)
+ return false;
+
+ // Version
+ const uint8 versionMajor = mus.readByte();
+ const uint8 versionMinor = mus.readByte();
+
+ if ((versionMajor != 1) && (versionMinor != 0)) {
+ warning("MUSPlayer::readMUSHeader(): Unsupported version %d.%d", versionMajor, versionMinor);
+ return false;
+ }
+
+ _songID = mus.readUint32LE();
+
+ byte nameBuffer[31];
+ if (!readString(mus, _songName, nameBuffer, 30)) {
+ warning("MUSPlayer::readMUSHeader(): Failed to read the song name");
+ return false;
+ }
+
+ _ticksPerBeat = mus.readByte();
+ _beatsPerMeasure = mus.readByte();
+
+ mus.skip(4); // Length of song in ticks
+
+ _songDataSize = mus.readUint32LE();
+
+ mus.skip(4); // Number of commands
+ mus.skip(8); // Unused
+
+ _soundMode = mus.readByte();
+ _pitchBendRange = mus.readByte();
+ _baseTempo = mus.readUint16LE();
+
+ mus.skip(8); // Unused
+
+ return true;
+}
+
+bool MUSPlayer::readMUSSong(Common::SeekableReadStream &mus) {
+ const uint32 realSongDataSize = mus.size() - mus.pos();
+
+ if (realSongDataSize < _songDataSize) {
+ warning("MUSPlayer::readMUSSong(): File too small for the song data: %d < %d", realSongDataSize, _songDataSize);
+ return false;
+ }
+
+ _songData = new byte[_songDataSize];
+
+ if (mus.read(_songData, _songDataSize) != _songDataSize) {
+ warning("MUSPlayer::readMUSSong(): Read failed");
+ return false;
+ }
+
+ return true;
+}
+
+void MUSPlayer::unloadSND() {
+ _timbres.clear();
+}
+
+void MUSPlayer::unloadMUS() {
+ delete[] _songData;
+
+ _songData = 0;
+ _songDataSize = 0;
+
+ _playPos = 0;
+}
+
+uint32 MUSPlayer::getSongID() const {
+ return _songID;
+}
+
+const Common::String &MUSPlayer::getSongName() const {
+ return _songName;
+}
+
+void MUSPlayer::setInstrument(uint8 voice, uint8 instrument) {
+ if (instrument >= _timbres.size())
+ return;
+
+ setVoiceTimbre(voice, _timbres[instrument].params);
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/sound/musplayer.h b/engines/gob/sound/musplayer.h
new file mode 100644
index 0000000000..6cc2a2d2ca
--- /dev/null
+++ b/engines/gob/sound/musplayer.h
@@ -0,0 +1,109 @@
+/* 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 GOB_SOUND_MUSPLAYER_H
+#define GOB_SOUND_MUSPLAYER_H
+
+#include "common/str.h"
+#include "common/array.h"
+
+#include "gob/sound/adlib.h"
+
+namespace Common {
+ class SeekableReadStream;
+}
+
+namespace Gob {
+
+/** A player for the AdLib MUS format, with the instrument information in SND files.
+ *
+ * In the Gob engine, those files are usually named .MDY and .TBR instead.
+ */
+class MUSPlayer : public AdLib {
+public:
+ MUSPlayer(Audio::Mixer &mixer);
+ ~MUSPlayer();
+
+ /** Load the instruments (.SND or .TBR) */
+ bool loadSND(Common::SeekableReadStream &snd);
+ /** Load the melody (.MUS or .MDY) */
+ bool loadMUS(Common::SeekableReadStream &mus);
+
+ void unload();
+
+ uint32 getSongID() const;
+ const Common::String &getSongName() const;
+
+protected:
+ // AdLib interface
+ uint32 pollMusic(bool first);
+ void rewind();
+
+private:
+ struct Timbre {
+ Common::String name;
+
+ uint16 params[kOperatorsPerVoice * kParamCount];
+ };
+
+ Common::Array<Timbre> _timbres;
+
+ byte *_songData;
+ uint32 _songDataSize;
+
+ const byte *_playPos;
+
+ uint32 _songID;
+ Common::String _songName;
+
+ uint8 _ticksPerBeat;
+ uint8 _beatsPerMeasure;
+
+ uint8 _soundMode;
+ uint8 _pitchBendRange;
+
+ uint16 _baseTempo;
+
+ uint16 _tempo;
+
+ byte _lastCommand;
+
+
+ void unloadSND();
+ void unloadMUS();
+
+ bool readSNDHeader (Common::SeekableReadStream &snd, int &timbreCount, int &timbrePos);
+ bool readSNDTimbres(Common::SeekableReadStream &snd, int timbreCount, int timbrePos);
+
+ bool readMUSHeader(Common::SeekableReadStream &mus);
+ bool readMUSSong (Common::SeekableReadStream &mus);
+
+ uint32 getSampleDelay(uint16 delay) const;
+ void setInstrument(uint8 voice, uint8 instrument);
+ void skipToTiming();
+
+ static bool readString(Common::SeekableReadStream &stream, Common::String &string, byte *buffer, uint size);
+};
+
+} // End of namespace Gob
+
+#endif // GOB_SOUND_MUSPLAYER_H
diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp
index bfe0394390..9f72d1a98f 100644
--- a/engines/gob/sound/sound.cpp
+++ b/engines/gob/sound/sound.cpp
@@ -30,7 +30,8 @@
#include "gob/sound/pcspeaker.h"
#include "gob/sound/soundblaster.h"
-#include "gob/sound/adlib.h"
+#include "gob/sound/adlplayer.h"
+#include "gob/sound/musplayer.h"
#include "gob/sound/infogrames.h"
#include "gob/sound/protracker.h"
#include "gob/sound/cdrom.h"
@@ -50,6 +51,8 @@ Sound::Sound(GobEngine *vm) : _vm(vm) {
_hasAdLib = (!_vm->_noMusic && _vm->hasAdLib());
+ _hasAdLibBg = _hasAdLib;
+
if (!_vm->_noMusic && (_vm->getPlatform() == Common::kPlatformAmiga)) {
_infogrames = new Infogrames(*_vm->_mixer);
_protracker = new Protracker(*_vm->_mixer);
@@ -131,10 +134,7 @@ void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdLib, int index) {
if (noteAdLib) {
if (_adlPlayer)
if ((index == -1) || (_adlPlayer->getIndex() == index))
- _adlPlayer->stopPlay();
- if (_mdyPlayer)
- if ((index == -1) || (_mdyPlayer->getIndex() == index))
- _mdyPlayer->stopPlay();
+ _adlPlayer->unload();
}
} else {
@@ -235,7 +235,17 @@ bool Sound::adlibLoadADL(const char *fileName) {
debugC(1, kDebugSound, "AdLib: Loading ADL data (\"%s\")", fileName);
- return _adlPlayer->load(fileName);
+ Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName);
+ if (!stream) {
+ warning("Can't open ADL file \"%s\"", fileName);
+ return false;
+ }
+
+ bool loaded = _adlPlayer->load(*stream);
+
+ delete stream;
+
+ return loaded;
}
bool Sound::adlibLoadADL(byte *data, uint32 size, int index) {
@@ -266,8 +276,7 @@ bool Sound::adlibLoadMDY(const char *fileName) {
if (!_hasAdLib)
return false;
- if (!_mdyPlayer)
- _mdyPlayer = new MDYPlayer(*_vm->_mixer);
+ createMDYPlayer();
debugC(1, kDebugSound, "AdLib: Loading MDY data (\"%s\")", fileName);
@@ -277,7 +286,7 @@ bool Sound::adlibLoadMDY(const char *fileName) {
return false;
}
- bool loaded = _mdyPlayer->loadMDY(*stream);
+ bool loaded = _mdyPlayer->loadMUS(*stream);
delete stream;
@@ -288,8 +297,7 @@ bool Sound::adlibLoadTBR(const char *fileName) {
if (!_hasAdLib)
return false;
- if (!_mdyPlayer)
- _mdyPlayer = new MDYPlayer(*_vm->_mixer);
+ createMDYPlayer();
Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName);
if (!stream) {
@@ -299,7 +307,7 @@ bool Sound::adlibLoadTBR(const char *fileName) {
debugC(1, kDebugSound, "AdLib: Loading MDY instruments (\"%s\")", fileName);
- bool loaded = _mdyPlayer->loadTBR(*stream);
+ bool loaded = _mdyPlayer->loadSND(*stream);
delete stream;
@@ -310,28 +318,23 @@ void Sound::adlibPlayTrack(const char *trackname) {
if (!_hasAdLib)
return;
- if (!_adlPlayer)
- _adlPlayer = new ADLPlayer(*_vm->_mixer);
+ createADLPlayer();
if (_adlPlayer->isPlaying())
return;
- debugC(1, kDebugSound, "AdLib: Playing ADL track \"%s\"", trackname);
-
- _adlPlayer->unload();
- _adlPlayer->load(trackname);
- _adlPlayer->startPlay();
+ if (adlibLoadADL(trackname))
+ adlibPlay();
}
void Sound::adlibPlayBgMusic() {
- if (!_hasAdLib)
+ if (!_hasAdLib || _hasAdLibBg)
return;
- if (!_adlPlayer)
- _adlPlayer = new ADLPlayer(*_vm->_mixer);
+ createADLPlayer();
static const char *const tracksMac[] = {
-// "musmac1.adl", // TODO: This track isn't played correctly at all yet
+// "musmac1.adl", // This track seems to be missing instruments...
"musmac2.adl",
"musmac3.adl",
"musmac4.adl",
@@ -347,13 +350,18 @@ void Sound::adlibPlayBgMusic() {
"musmac5.mid"
};
- if (_vm->getPlatform() == Common::kPlatformWindows) {
- int track = _vm->_util->getRandom(ARRAYSIZE(tracksWin));
- adlibPlayTrack(tracksWin[track]);
- } else {
- int track = _vm->_util->getRandom(ARRAYSIZE(tracksMac));
- adlibPlayTrack(tracksMac[track]);
+ const char *track = 0;
+ if (_vm->getPlatform() == Common::kPlatformWindows)
+ track = tracksWin[ARRAYSIZE(tracksWin)];
+ else
+ track = tracksMac[_vm->_util->getRandom(ARRAYSIZE(tracksMac))];
+
+ if (!track || !_vm->_dataIO->hasFile(track)) {
+ _hasAdLibBg = false;
+ return;
}
+
+ adlibPlayTrack(track);
}
void Sound::adlibPlay() {
@@ -398,13 +406,11 @@ int Sound::adlibGetIndex() const {
if (_adlPlayer)
return _adlPlayer->getIndex();
- if (_mdyPlayer)
- return _mdyPlayer->getIndex();
return -1;
}
-bool Sound::adlibGetRepeating() const {
+int32 Sound::adlibGetRepeating() const {
if (!_hasAdLib)
return false;
@@ -719,4 +725,24 @@ void Sound::bgUnshade() {
_bgatmos->unshade();
}
+void Sound::createMDYPlayer() {
+ if (_mdyPlayer)
+ return;
+
+ delete _adlPlayer;
+ _adlPlayer = 0;
+
+ _mdyPlayer = new MUSPlayer(*_vm->_mixer);
+}
+
+void Sound::createADLPlayer() {
+ if (_adlPlayer)
+ return;
+
+ delete _mdyPlayer;
+ _mdyPlayer= 0;
+
+ _adlPlayer = new ADLPlayer(*_vm->_mixer);
+}
+
} // End of namespace Gob
diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h
index 585cf36703..064a249253 100644
--- a/engines/gob/sound/sound.h
+++ b/engines/gob/sound/sound.h
@@ -32,7 +32,7 @@ class GobEngine;
class PCSpeaker;
class SoundBlaster;
class ADLPlayer;
-class MDYPlayer;
+class MUSPlayer;
class Infogrames;
class Protracker;
class CDROM;
@@ -92,7 +92,7 @@ public:
bool adlibIsPlaying() const;
int adlibGetIndex() const;
- bool adlibGetRepeating() const;
+ int32 adlibGetRepeating() const;
void adlibSetRepeating(int32 repCount);
@@ -142,17 +142,30 @@ private:
GobEngine *_vm;
bool _hasAdLib;
+ bool _hasAdLibBg;
SoundDesc _sounds[kSoundsCount];
+ // Speaker
PCSpeaker *_pcspeaker;
+
+ // PCM based
SoundBlaster *_blaster;
+ BackgroundAtmosphere *_bgatmos;
+
+ // AdLib
+ MUSPlayer *_mdyPlayer;
ADLPlayer *_adlPlayer;
- MDYPlayer *_mdyPlayer;
+
+ // Amiga Paula
Infogrames *_infogrames;
Protracker *_protracker;
+
+ // Audio CD
CDROM *_cdrom;
- BackgroundAtmosphere *_bgatmos;
+
+ void createMDYPlayer();
+ void createADLPlayer();
};
} // End of namespace Gob
diff --git a/engines/groovie/cursor.cpp b/engines/groovie/cursor.cpp
index abefac54bd..6422570220 100644
--- a/engines/groovie/cursor.cpp
+++ b/engines/groovie/cursor.cpp
@@ -387,7 +387,7 @@ void Cursor_v2::enable() {
void Cursor_v2::showFrame(uint16 frame) {
int offset = _width * _height * frame * 2;
- CursorMan.replaceCursor((const byte *)(_img + offset), _width, _height, _width >> 1, _height >> 1, 0, 1, &_format);
+ CursorMan.replaceCursor((const byte *)(_img + offset), _width, _height, _width >> 1, _height >> 1, 0, false, &_format);
}
diff --git a/engines/hugo/console.cpp b/engines/hugo/console.cpp
index 19fd91e3fa..414c86e1d4 100644
--- a/engines/hugo/console.cpp
+++ b/engines/hugo/console.cpp
@@ -96,8 +96,8 @@ bool HugoConsole::Cmd_listObjects(int argc, const char **argv) {
DebugPrintf("Available objects for this game are:\n");
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (_vm->_object->_objects[i].genericCmd & TAKE)
- DebugPrintf("%2d - %s\n", i, _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2));
+ if (_vm->_object->_objects[i]._genericCmd & TAKE)
+ DebugPrintf("%2d - %s\n", i, _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2));
}
return true;
}
@@ -111,7 +111,7 @@ bool HugoConsole::Cmd_getObject(int argc, const char **argv) {
return true;
}
- if (_vm->_object->_objects[strToInt(argv[1])].genericCmd & TAKE)
+ if (_vm->_object->_objects[strToInt(argv[1])]._genericCmd & TAKE)
_vm->_parser->takeObject(&_vm->_object->_objects[strToInt(argv[1])]);
else
DebugPrintf("Object not available\n");
@@ -129,7 +129,7 @@ bool HugoConsole::Cmd_getAllObjects(int argc, const char **argv) {
}
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (_vm->_object->_objects[i].genericCmd & TAKE)
+ if (_vm->_object->_objects[i]._genericCmd & TAKE)
_vm->_parser->takeObject(&_vm->_object->_objects[i]);
}
@@ -145,7 +145,7 @@ bool HugoConsole::Cmd_boundaries(int argc, const char **argv) {
return true;
}
- _vm->getGameStatus().showBoundariesFl = !_vm->getGameStatus().showBoundariesFl;
+ _vm->getGameStatus()._showBoundariesFl = !_vm->getGameStatus()._showBoundariesFl;
return false;
}
diff --git a/engines/hugo/dialogs.cpp b/engines/hugo/dialogs.cpp
index e0b0198470..0f07d52aee 100644
--- a/engines/hugo/dialogs.cpp
+++ b/engines/hugo/dialogs.cpp
@@ -34,19 +34,19 @@
namespace Hugo {
-TopMenu::TopMenu(HugoEngine *vm) : Dialog(0, 0, kMenuWidth, kMenuHeight), arrayBmp(0), arraySize(0),
+TopMenu::TopMenu(HugoEngine *vm) : Dialog(0, 0, kMenuWidth, kMenuHeight), _arrayBmp(0), _arraySize(0),
_vm(vm) {
init();
}
TopMenu::~TopMenu() {
- for (int i = 0; i < arraySize; i++) {
- arrayBmp[i * 2]->free();
- delete arrayBmp[i * 2];
- arrayBmp[i * 2 + 1]->free();
- delete arrayBmp[i * 2 + 1];
+ for (int i = 0; i < _arraySize; i++) {
+ _arrayBmp[i * 2]->free();
+ delete _arrayBmp[i * 2];
+ _arrayBmp[i * 2 + 1]->free();
+ delete _arrayBmp[i * 2 + 1];
}
- delete[] arrayBmp;
+ delete[] _arrayBmp;
}
void TopMenu::init() {
@@ -108,23 +108,23 @@ void TopMenu::reflowLayout() {
x += kButtonWidth + kButtonPad;
// Set the graphics to the 'on' buttons, except for the variable ones
- _whatButton->setGfx(arrayBmp[4 * kMenuWhat + scale - 1]);
- _musicButton->setGfx(arrayBmp[4 * kMenuMusic + scale - 1 + ((_vm->_config.musicFl) ? 0 : 2)]);
- _soundFXButton->setGfx(arrayBmp[4 * kMenuSoundFX + scale - 1 + ((_vm->_config.soundFl) ? 0 : 2)]);
- _saveButton->setGfx(arrayBmp[4 * kMenuSave + scale - 1]);
- _loadButton->setGfx(arrayBmp[4 * kMenuLoad + scale - 1]);
- _recallButton->setGfx(arrayBmp[4 * kMenuRecall + scale - 1]);
- _turboButton->setGfx(arrayBmp[4 * kMenuTurbo + scale - 1 + ((_vm->_config.turboFl) ? 0 : 2)]);
- _lookButton->setGfx(arrayBmp[4 * kMenuLook + scale - 1]);
- _inventButton->setGfx(arrayBmp[4 * kMenuInventory + scale - 1]);
+ _whatButton->setGfx(_arrayBmp[4 * kMenuWhat + scale - 1]);
+ _musicButton->setGfx(_arrayBmp[4 * kMenuMusic + scale - 1 + ((_vm->_config._musicFl) ? 0 : 2)]);
+ _soundFXButton->setGfx(_arrayBmp[4 * kMenuSoundFX + scale - 1 + ((_vm->_config._soundFl) ? 0 : 2)]);
+ _saveButton->setGfx(_arrayBmp[4 * kMenuSave + scale - 1]);
+ _loadButton->setGfx(_arrayBmp[4 * kMenuLoad + scale - 1]);
+ _recallButton->setGfx(_arrayBmp[4 * kMenuRecall + scale - 1]);
+ _turboButton->setGfx(_arrayBmp[4 * kMenuTurbo + scale - 1 + ((_vm->_config._turboFl) ? 0 : 2)]);
+ _lookButton->setGfx(_arrayBmp[4 * kMenuLook + scale - 1]);
+ _inventButton->setGfx(_arrayBmp[4 * kMenuInventory + scale - 1]);
}
void TopMenu::loadBmpArr(Common::SeekableReadStream &in) {
- arraySize = in.readUint16BE();
+ _arraySize = in.readUint16BE();
- delete arrayBmp;
- arrayBmp = new Graphics::Surface *[arraySize * 2];
- for (int i = 0; i < arraySize; i++) {
+ delete _arrayBmp;
+ _arrayBmp = new Graphics::Surface *[_arraySize * 2];
+ for (int i = 0; i < _arraySize; i++) {
uint16 bmpSize = in.readUint16BE();
uint32 filPos = in.pos();
Common::SeekableSubReadStream stream(&in, filPos, filPos + bmpSize);
@@ -137,28 +137,28 @@ void TopMenu::loadBmpArr(Common::SeekableReadStream &in) {
if (bitmapSrc->format.bytesPerPixel == 1)
error("TopMenu::loadBmpArr(): Unhandled paletted image");
- arrayBmp[i * 2] = bitmapSrc->convertTo(g_system->getOverlayFormat());
- arrayBmp[i * 2 + 1] = new Graphics::Surface();
- arrayBmp[i * 2 + 1]->create(arrayBmp[i * 2]->w * 2, arrayBmp[i * 2]->h * 2, g_system->getOverlayFormat());
- byte *src = (byte *)arrayBmp[i * 2]->pixels;
- byte *dst = (byte *)arrayBmp[i * 2 + 1]->pixels;
-
- for (int j = 0; j < arrayBmp[i * 2]->h; j++) {
- src = (byte *)arrayBmp[i * 2]->getBasePtr(0, j);
- dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
- for (int k = arrayBmp[i * 2]->w; k > 0; k--) {
- for (int m = arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) {
+ _arrayBmp[i * 2] = bitmapSrc->convertTo(g_system->getOverlayFormat());
+ _arrayBmp[i * 2 + 1] = new Graphics::Surface();
+ _arrayBmp[i * 2 + 1]->create(_arrayBmp[i * 2]->w * 2, _arrayBmp[i * 2]->h * 2, g_system->getOverlayFormat());
+ byte *src = (byte *)_arrayBmp[i * 2]->pixels;
+ byte *dst = (byte *)_arrayBmp[i * 2 + 1]->pixels;
+
+ for (int j = 0; j < _arrayBmp[i * 2]->h; j++) {
+ src = (byte *)_arrayBmp[i * 2]->getBasePtr(0, j);
+ dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
+ for (int k = _arrayBmp[i * 2]->w; k > 0; k--) {
+ for (int m = _arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) {
*dst++ = *src++;
}
- src -= arrayBmp[i * 2]->format.bytesPerPixel;
+ src -= _arrayBmp[i * 2]->format.bytesPerPixel;
- for (int m = arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) {
+ for (int m = _arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) {
*dst++ = *src++;
}
}
- src = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
- dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2 + 1);
- for (int k = arrayBmp[i * 2 + 1]->pitch; k > 0; k--) {
+ src = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
+ dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2 + 1);
+ for (int k = _arrayBmp[i * 2 + 1]->pitch; k > 0; k--) {
*dst++ = *src++;
}
}
@@ -171,12 +171,12 @@ void TopMenu::handleCommand(GUI::CommandSender *sender, uint32 command, uint32 d
switch (command) {
case kCmdWhat:
close();
- _vm->getGameStatus().helpFl = true;
+ _vm->getGameStatus()._helpFl = true;
break;
case kCmdMusic:
_vm->_sound->toggleMusic();
- _musicButton->setGfx(arrayBmp[4 * kMenuMusic + (g_system->getOverlayWidth() > 320 ? 2 : 1) - 1 + ((_vm->_config.musicFl) ? 0 : 2)]);
+ _musicButton->setGfx(_arrayBmp[4 * kMenuMusic + (g_system->getOverlayWidth() > 320 ? 2 : 1) - 1 + ((_vm->_config._musicFl) ? 0 : 2)]);
_musicButton->draw();
g_gui.theme()->updateScreen();
g_system->updateScreen();
@@ -194,8 +194,8 @@ void TopMenu::handleCommand(GUI::CommandSender *sender, uint32 command, uint32 d
break;
case kCmdSave:
close();
- if (_vm->getGameStatus().viewState == kViewPlay) {
- if (_vm->getGameStatus().gameOverFl)
+ if (_vm->getGameStatus()._viewState == kViewPlay) {
+ if (_vm->getGameStatus()._gameOverFl)
_vm->gameOverMsg();
else
_vm->_file->saveGame(-1, Common::String());
@@ -207,7 +207,7 @@ void TopMenu::handleCommand(GUI::CommandSender *sender, uint32 command, uint32 d
break;
case kCmdRecall:
close();
- _vm->getGameStatus().recallFl = true;
+ _vm->getGameStatus()._recallFl = true;
break;
case kCmdTurbo:
_vm->_parser->switchTurbo();
diff --git a/engines/hugo/dialogs.h b/engines/hugo/dialogs.h
index 4e710ff2f8..114bcf56a9 100644
--- a/engines/hugo/dialogs.h
+++ b/engines/hugo/dialogs.h
@@ -94,8 +94,8 @@ protected:
GUI::PicButtonWidget *_lookButton;
GUI::PicButtonWidget *_inventButton;
- Graphics::Surface **arrayBmp;
- uint16 arraySize;
+ Graphics::Surface **_arrayBmp;
+ uint16 _arraySize;
};
class EntryDialog : public GUI::Dialog {
diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp
index fa18d6b791..b86b1f0366 100644
--- a/engines/hugo/display.cpp
+++ b/engines/hugo/display.cpp
@@ -85,43 +85,43 @@ Screen::Screen(HugoEngine *vm) : _vm(vm) {
fontLoadedFl[i] = false;
}
for (int i = 0; i < kBlitListSize; i++) {
- _dlBlistList[i].x = 0;
- _dlBlistList[i].y = 0;
- _dlBlistList[i].dx = 0;
- _dlBlistList[i].dy = 0;
+ _dlBlistList[i]._x = 0;
+ _dlBlistList[i]._y = 0;
+ _dlBlistList[i]._dx = 0;
+ _dlBlistList[i]._dy = 0;
}
for (int i = 0; i < kRectListSize; i++) {
- _dlAddList[i].x = 0;
- _dlAddList[i].y = 0;
- _dlAddList[i].dx = 0;
- _dlAddList[i].dy = 0;
- _dlRestoreList[i].x = 0;
- _dlRestoreList[i].y = 0;
- _dlRestoreList[i].dx = 0;
- _dlRestoreList[i].dy = 0;
+ _dlAddList[i]._x = 0;
+ _dlAddList[i]._y = 0;
+ _dlAddList[i]._dx = 0;
+ _dlAddList[i]._dy = 0;
+ _dlRestoreList[i]._x = 0;
+ _dlRestoreList[i]._y = 0;
+ _dlRestoreList[i]._dx = 0;
+ _dlRestoreList[i]._dy = 0;
}
}
Screen::~Screen() {
}
-icondib_t &Screen::getIconBuffer() {
+Icondib &Screen::getIconBuffer() {
return _iconBuffer;
}
-viewdib_t &Screen::getBackBuffer() {
+Viewdib &Screen::getBackBuffer() {
return _backBuffer;
}
-viewdib_t &Screen::getBackBufferBackup() {
+Viewdib &Screen::getBackBufferBackup() {
return _backBufferBackup;
}
-viewdib_t &Screen::getFrontBuffer() {
+Viewdib &Screen::getFrontBuffer() {
return _frontBuffer;
}
-viewdib_t &Screen::getGUIBuffer() {
+Viewdib &Screen::getGUIBuffer() {
return _GUIBuffer;
}
@@ -149,7 +149,7 @@ void Screen::initDisplay() {
/**
* Move an image from source to destination
*/
-void Screen::moveImage(image_pt srcImage, const int16 x1, const int16 y1, const int16 dx, int16 dy, const int16 width1, image_pt dstImage, const int16 x2, const int16 y2, const int16 width2) {
+void Screen::moveImage(ImagePtr srcImage, const int16 x1, const int16 y1, const int16 dx, int16 dy, const int16 width1, ImagePtr dstImage, const int16 x2, const int16 y2, const int16 width2) {
debugC(3, kDebugDisplay, "moveImage(srcImage, %d, %d, %d, %d, %d, dstImage, %d, %d, %d)", x1, y1, dx, dy, width1, x2, y2, width2);
int16 wrap_src = width1 - dx; // Wrap to next src row
@@ -236,16 +236,16 @@ void Screen::setBackgroundColor(const uint16 color) {
* Merge an object frame into _frontBuffer at sx, sy and update rectangle list.
* If fore TRUE, force object above any overlay
*/
-void Screen::displayFrame(const int sx, const int sy, seq_t *seq, const bool foreFl) {
+void Screen::displayFrame(const int sx, const int sy, Seq *seq, const bool foreFl) {
debugC(3, kDebugDisplay, "displayFrame(%d, %d, seq, %d)", sx, sy, (foreFl) ? 1 : 0);
- image_pt image = seq->imagePtr; // Ptr to object image data
- image_pt subFrontBuffer = &_frontBuffer[sy * kXPix + sx]; // Ptr to offset in _frontBuffer
- int16 frontBufferwrap = kXPix - seq->x2 - 1; // Wraps dest_p after each line
- int16 imageWrap = seq->bytesPerLine8 - seq->x2 - 1;
- overlayState_t overlayState = (foreFl) ? kOvlForeground : kOvlUndef; // Overlay state of object
- for (uint16 y = 0; y < seq->lines; y++) { // Each line in object
- for (uint16 x = 0; x <= seq->x2; x++) {
+ ImagePtr image = seq->_imagePtr; // Ptr to object image data
+ ImagePtr subFrontBuffer = &_frontBuffer[sy * kXPix + sx]; // Ptr to offset in _frontBuffer
+ int16 frontBufferwrap = kXPix - seq->_x2 - 1; // Wraps dest_p after each line
+ int16 imageWrap = seq->_bytesPerLine8 - seq->_x2 - 1;
+ OverlayState overlayState = (foreFl) ? kOvlForeground : kOvlUndef; // Overlay state of object
+ for (uint16 y = 0; y < seq->_lines; y++) { // Each line in object
+ for (uint16 x = 0; x <= seq->_x2; x++) {
if (*image) { // Non-transparent
byte ovlBound = _vm->_object->getFirstOverlay((uint16)(subFrontBuffer - _frontBuffer) >> 3); // Ptr into overlay bits
if (ovlBound & (0x80 >> ((uint16)(subFrontBuffer - _frontBuffer) & 7))) { // Overlay bit is set
@@ -265,24 +265,24 @@ void Screen::displayFrame(const int sx, const int sy, seq_t *seq, const bool for
}
// Add this rectangle to the display list
- displayList(kDisplayAdd, sx, sy, seq->x2 + 1, seq->lines);
+ displayList(kDisplayAdd, sx, sy, seq->_x2 + 1, seq->_lines);
}
/**
* Merge rectangles A,B leaving result in B
*/
-void Screen::merge(const rect_t *rectA, rect_t *rectB) {
+void Screen::merge(const Rect *rectA, Rect *rectB) {
debugC(6, kDebugDisplay, "merge()");
- int16 xa = rectA->x + rectA->dx; // Find x2,y2 for each rectangle
- int16 xb = rectB->x + rectB->dx;
- int16 ya = rectA->y + rectA->dy;
- int16 yb = rectB->y + rectB->dy;
+ int16 xa = rectA->_x + rectA->_dx; // Find x2,y2 for each rectangle
+ int16 xb = rectB->_x + rectB->_dx;
+ int16 ya = rectA->_y + rectA->_dy;
+ int16 yb = rectB->_y + rectB->_dy;
- rectB->x = MIN(rectA->x, rectB->x); // Minimum x,y
- rectB->y = MIN(rectA->y, rectB->y);
- rectB->dx = MAX(xa, xb) - rectB->x; // Maximum dx,dy
- rectB->dy = MAX(ya, yb) - rectB->y;
+ rectB->_x = MIN(rectA->_x, rectB->_x); // Minimum x,y
+ rectB->_y = MIN(rectA->_y, rectB->_y);
+ rectB->_dx = MAX(xa, xb) - rectB->_x; // Maximum dx,dy
+ rectB->_dy = MAX(ya, yb) - rectB->_y;
}
/**
@@ -291,7 +291,7 @@ void Screen::merge(const rect_t *rectA, rect_t *rectB) {
* of blist. bmax is the max size of the blist. Note that blist can
* have holes, in which case dx = 0. Returns used length of blist.
*/
-int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 blen) {
+int16 Screen::mergeLists(Rect *list, Rect *blist, const int16 len, int16 blen) {
debugC(4, kDebugDisplay, "mergeLists()");
int16 coalesce[kBlitListSize]; // List of overlapping rects
@@ -299,9 +299,9 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 ble
for (int16 a = 0; a < len; a++, list++) {
// Compile list of overlapping rectangles in blit list
int16 c = 0;
- rect_t *bp = blist;
+ Rect *bp = blist;
for (int16 b = 0; b < blen; b++, bp++) {
- if (bp->dx) // blist entry used
+ if (bp->_dx) // blist entry used
if (isOverlapping(list, bp))
coalesce[c++] = b;
}
@@ -316,9 +316,9 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 ble
// Merge any more blist entries
while (--c) {
- rect_t *cp = &blist[coalesce[c]];
+ Rect *cp = &blist[coalesce[c]];
merge(cp, bp);
- cp->dx = 0; // Delete entry
+ cp->_dx = 0; // Delete entry
}
}
}
@@ -329,12 +329,12 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 ble
* Process the display list
* Trailing args are int16 x,y,dx,dy for the D_ADD operation
*/
-void Screen::displayList(dupdate_t update, ...) {
+void Screen::displayList(Dupdate update, ...) {
debugC(6, kDebugDisplay, "displayList()");
int16 blitLength = 0; // Length of blit list
va_list marker; // Args used for D_ADD operation
- rect_t *p; // Ptr to dlist entry
+ Rect *p; // Ptr to dlist entry
switch (update) {
case kDisplayInit: // Init lists, restore whole screen
@@ -348,10 +348,10 @@ void Screen::displayList(dupdate_t update, ...) {
}
va_start(marker, update); // Initialize variable arguments
p = &_dlAddList[_dlAddIndex];
- p->x = va_arg(marker, int); // x
- p->y = va_arg(marker, int); // y
- p->dx = va_arg(marker, int); // dx
- p->dy = va_arg(marker, int); // dy
+ p->_x = va_arg(marker, int); // x
+ p->_y = va_arg(marker, int); // y
+ p->_dx = va_arg(marker, int); // dx
+ p->_dy = va_arg(marker, int); // dy
va_end(marker); // Reset variable arguments
_dlAddIndex++;
break;
@@ -359,8 +359,8 @@ void Screen::displayList(dupdate_t update, ...) {
// Don't blit if newscreen just loaded because _frontBuffer will
// get blitted via InvalidateRect() at end of this cycle
// and blitting here causes objects to appear too soon.
- if (_vm->getGameStatus().newScreenFl) {
- _vm->getGameStatus().newScreenFl = false;
+ if (_vm->getGameStatus()._newScreenFl) {
+ _vm->getGameStatus()._newScreenFl = false;
break;
}
@@ -370,15 +370,15 @@ void Screen::displayList(dupdate_t update, ...) {
// Blit the combined blit-list
for (_dlRestoreIndex = 0, p = _dlBlistList; _dlRestoreIndex < blitLength; _dlRestoreIndex++, p++) {
- if (p->dx) // Marks a used entry
- displayRect(p->x, p->y, p->dx, p->dy);
+ if (p->_dx) // Marks a used entry
+ displayRect(p->_x, p->_y, p->_dx, p->_dy);
}
break;
case kDisplayRestore: // Restore each rectangle
for (_dlRestoreIndex = 0, p = _dlAddList; _dlRestoreIndex < _dlAddIndex; _dlRestoreIndex++, p++) {
// Restoring from _backBuffer to _frontBuffer
_dlRestoreList[_dlRestoreIndex] = *p; // Copy add-list to restore-list
- moveImage(_backBuffer, p->x, p->y, p->dx, p->dy, kXPix, _frontBuffer, p->x, p->y, kXPix);
+ moveImage(_backBuffer, p->_x, p->_y, p->_dx, p->_dy, kXPix, _frontBuffer, p->_x, p->_y, kXPix);
}
_dlAddIndex = 0; // Reset add-list
break;
@@ -563,7 +563,7 @@ void Screen::initNewScreenDisplay() {
displayBackground();
// Stop premature object display in Display_list(D_DISPLAY)
- _vm->getGameStatus().newScreenFl = true;
+ _vm->getGameStatus()._newScreenFl = true;
}
/**
@@ -627,20 +627,20 @@ void Screen::hideCursor() {
CursorMan.showMouse(false);
}
-bool Screen::isInX(const int16 x, const rect_t *rect) const {
- return (x >= rect->x) && (x <= rect->x + rect->dx);
+bool Screen::isInX(const int16 x, const Rect *rect) const {
+ return (x >= rect->_x) && (x <= rect->_x + rect->_dx);
}
-bool Screen::isInY(const int16 y, const rect_t *rect) const {
- return (y >= rect->y) && (y <= rect->y + rect->dy);
+bool Screen::isInY(const int16 y, const Rect *rect) const {
+ return (y >= rect->_y) && (y <= rect->_y + rect->_dy);
}
/**
* Check if two rectangles are overlapping
*/
-bool Screen::isOverlapping(const rect_t *rectA, const rect_t *rectB) const {
- return (isInX(rectA->x, rectB) || isInX(rectA->x + rectA->dx, rectB) || isInX(rectB->x, rectA) || isInX(rectB->x + rectB->dx, rectA)) &&
- (isInY(rectA->y, rectB) || isInY(rectA->y + rectA->dy, rectB) || isInY(rectB->y, rectA) || isInY(rectB->y + rectB->dy, rectA));
+bool Screen::isOverlapping(const Rect *rectA, const Rect *rectB) const {
+ return (isInX(rectA->_x, rectB) || isInX(rectA->_x + rectA->_dx, rectB) || isInX(rectB->_x, rectA) || isInX(rectB->_x + rectB->_dx, rectA)) &&
+ (isInY(rectA->_y, rectB) || isInY(rectA->_y + rectA->_dy, rectB) || isInY(rectB->_y, rectA) || isInY(rectB->_y + rectB->_dy, rectA));
}
/**
@@ -650,19 +650,19 @@ bool Screen::isOverlapping(const rect_t *rectA, const rect_t *rectB) const {
* White = Fix objects, parts of background
*/
void Screen::drawBoundaries() {
- if (!_vm->getGameStatus().showBoundariesFl)
+ if (!_vm->getGameStatus()._showBoundariesFl)
return;
_vm->_mouse->drawHotspots();
for (int i = 0; i < _vm->_object->_numObj; i++) {
- object_t *obj = &_vm->_object->_objects[i]; // Get pointer to object
- if (obj->screenIndex == *_vm->_screen_p) {
- if ((obj->currImagePtr != 0) && (obj->cycling != kCycleInvisible))
- drawRectangle(false, obj->x + obj->currImagePtr->x1, obj->y + obj->currImagePtr->y1,
- obj->x + obj->currImagePtr->x2, obj->y + obj->currImagePtr->y2, _TLIGHTGREEN);
- else if ((obj->currImagePtr == 0) && (obj->vxPath != 0) && !obj->carriedFl)
- drawRectangle(false, obj->oldx, obj->oldy, obj->oldx + obj->vxPath, obj->oldy + obj->vyPath, _TBRIGHTWHITE);
+ Object *obj = &_vm->_object->_objects[i]; // Get pointer to object
+ if (obj->_screenIndex == *_vm->_screenPtr) {
+ if ((obj->_currImagePtr != 0) && (obj->_cycling != kCycleInvisible))
+ drawRectangle(false, obj->_x + obj->_currImagePtr->_x1, obj->_y + obj->_currImagePtr->_y1,
+ obj->_x + obj->_currImagePtr->_x2, obj->_y + obj->_currImagePtr->_y2, _TLIGHTGREEN);
+ else if ((obj->_currImagePtr == 0) && (obj->_vxPath != 0) && !obj->_carriedFl)
+ drawRectangle(false, obj->_oldx, obj->_oldy, obj->_oldx + obj->_vxPath, obj->_oldy + obj->_vyPath, _TBRIGHTWHITE);
}
}
g_system->copyRectToScreen(_frontBuffer, 320, 0, 0, 320, 200);
@@ -730,12 +730,12 @@ void Screen_v1d::loadFontArr(Common::ReadStream &in) {
* processed object by looking down the current column for an overlay
* base byte set (in which case the object is foreground).
*/
-overlayState_t Screen_v1d::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) {
+OverlayState Screen_v1d::findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y) {
debugC(4, kDebugDisplay, "findOvl()");
- uint16 index = (uint16)(dst_p - _frontBuffer) >> 3;
+ uint16 index = (uint16)(dstPtr - _frontBuffer) >> 3;
- for (int i = 0; i < seq_p->lines-y; i++) { // Each line in object
+ for (int i = 0; i < seqPtr->_lines-y; i++) { // Each line in object
if (_vm->_object->getBaseBoundary(index)) // If any overlay base byte is non-zero then the object is foreground, else back.
return kOvlForeground;
index += kCompLineSize;
@@ -799,14 +799,14 @@ void Screen_v1w::loadFontArr(Common::ReadStream &in) {
* processed object by looking down the current column for an overlay
* base bit set (in which case the object is foreground).
*/
-overlayState_t Screen_v1w::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) {
+OverlayState Screen_v1w::findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y) {
debugC(4, kDebugDisplay, "findOvl()");
- for (; y < seq_p->lines; y++) { // Each line in object
- byte ovb = _vm->_object->getBaseBoundary((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits
- if (ovb & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set
+ for (; y < seqPtr->_lines; y++) { // Each line in object
+ byte ovb = _vm->_object->getBaseBoundary((uint16)(dstPtr - _frontBuffer) >> 3); // Ptr into overlay bits
+ if (ovb & (0x80 >> ((uint16)(dstPtr - _frontBuffer) & 7))) // Overlay bit is set
return kOvlForeground; // Found a bit - must be foreground
- dst_p += kXPix;
+ dstPtr += kXPix;
}
return kOvlBackground; // No bits set, must be background
diff --git a/engines/hugo/display.h b/engines/hugo/display.h
index 38c63e9fe5..00dc1b743c 100644
--- a/engines/hugo/display.h
+++ b/engines/hugo/display.h
@@ -31,18 +31,18 @@
#define HUGO_DISPLAY_H
namespace Hugo {
-enum overlayState_t {kOvlUndef, kOvlForeground, kOvlBackground}; // Overlay state
+enum OverlayState {kOvlUndef, kOvlForeground, kOvlBackground}; // Overlay state
static const int kCenter = -1; // Used to center text in x
class Screen {
public:
- struct rect_t { // Rectangle used in Display list
- int16 x; // Position in dib
- int16 y; // Position in dib
- int16 dx; // width
- int16 dy; // height
+ struct Rect { // Rectangle used in Display list
+ int16 _x; // Position in dib
+ int16 _y; // Position in dib
+ int16 _dx; // width
+ int16 _dy; // height
};
Screen(HugoEngine *vm);
@@ -55,8 +55,8 @@ public:
int16 stringLength(const char *s) const;
void displayBackground();
- void displayFrame(const int sx, const int sy, seq_t *seq, const bool foreFl);
- void displayList(dupdate_t update, ...);
+ void displayFrame(const int sx, const int sy, Seq *seq, const bool foreFl);
+ void displayList(Dupdate update, ...);
void displayRect(const int16 x, const int16 y, const int16 dx, const int16 dy);
void drawBoundaries();
void drawRectangle(const bool filledFl, const int16 x1, const int16 y1, const int16 x2, const int16 y2, const int color);
@@ -67,7 +67,7 @@ public:
void initDisplay();
void initNewScreenDisplay();
void loadPalette(Common::ReadStream &in);
- void moveImage(image_pt srcImage, const int16 x1, const int16 y1, const int16 dx, int16 dy, const int16 width1, image_pt dstImage, const int16 x2, const int16 y2, const int16 width2);
+ void moveImage(ImagePtr srcImage, const int16 x1, const int16 y1, const int16 dx, int16 dy, const int16 width1, ImagePtr dstImage, const int16 x2, const int16 y2, const int16 width2);
void remapPal(uint16 oldIndex, uint16 newIndex);
void resetInventoryObjId();
void restorePal(Common::ReadStream *f);
@@ -80,11 +80,11 @@ public:
void userHelp() const;
void writeStr(int16 sx, const int16 sy, const char *s, const byte color);
- icondib_t &getIconBuffer();
- viewdib_t &getBackBuffer();
- viewdib_t &getBackBufferBackup();
- viewdib_t &getFrontBuffer();
- viewdib_t &getGUIBuffer();
+ Icondib &getIconBuffer();
+ Viewdib &getBackBuffer();
+ Viewdib &getBackBufferBackup();
+ Viewdib &getFrontBuffer();
+ Viewdib &getGUIBuffer();
protected:
HugoEngine *_vm;
@@ -108,37 +108,37 @@ protected:
byte *_mainPalette;
int16 _arrayFontSize[kNumFonts];
- viewdib_t _frontBuffer;
+ Viewdib _frontBuffer;
- inline bool isInX(const int16 x, const rect_t *rect) const;
- inline bool isInY(const int16 y, const rect_t *rect) const;
- inline bool isOverlapping(const rect_t *rectA, const rect_t *rectB) const;
+ inline bool isInX(const int16 x, const Rect *rect) const;
+ inline bool isInY(const int16 y, const Rect *rect) const;
+ inline bool isOverlapping(const Rect *rectA, const Rect *rectB) const;
- virtual overlayState_t findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) = 0;
+ virtual OverlayState findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y) = 0;
private:
byte *_curPalette;
byte _iconImage[kInvDx * kInvDy];
byte _paletteSize;
- icondib_t _iconBuffer; // Inventory icon DIB
+ Icondib _iconBuffer; // Inventory icon DIB
- int16 mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 blen);
+ int16 mergeLists(Rect *list, Rect *blist, const int16 len, int16 blen);
int16 center(const char *s) const;
- viewdib_t _backBuffer;
- viewdib_t _GUIBuffer; // User interface images
- viewdib_t _backBufferBackup; // Backup _backBuffer during inventory
+ Viewdib _backBuffer;
+ Viewdib _GUIBuffer; // User interface images
+ Viewdib _backBufferBackup; // Backup _backBuffer during inventory
// Formerly static variables used by displayList()
int16 _dlAddIndex, _dlRestoreIndex; // Index into add/restore lists
- rect_t _dlRestoreList[kRectListSize]; // The restore list
- rect_t _dlAddList[kRectListSize]; // The add list
- rect_t _dlBlistList[kBlitListSize]; // The blit list
+ Rect _dlRestoreList[kRectListSize]; // The restore list
+ Rect _dlAddList[kRectListSize]; // The add list
+ Rect _dlBlistList[kBlitListSize]; // The blit list
//
void createPal();
- void merge(const rect_t *rectA, rect_t *rectB);
+ void merge(const Rect *rectA, Rect *rectB);
void writeChr(const int sx, const int sy, const byte color, const char *local_fontdata);
};
@@ -150,7 +150,7 @@ public:
void loadFont(int16 fontId);
void loadFontArr(Common::ReadStream &in);
protected:
- overlayState_t findOvl(seq_t *seq_p, image_pt dst_p, uint16 y);
+ OverlayState findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y);
};
class Screen_v1w : public Screen {
@@ -161,7 +161,7 @@ public:
void loadFont(int16 fontId);
void loadFontArr(Common::ReadStream &in);
protected:
- overlayState_t findOvl(seq_t *seq_p, image_pt dst_p, uint16 y);
+ OverlayState findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y);
};
} // End of namespace Hugo
diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp
index 2217cef92a..5556f5abc0 100644
--- a/engines/hugo/file.cpp
+++ b/engines/hugo/file.cpp
@@ -53,8 +53,8 @@ static const int s_bootCypherLen = sizeof(s_bootCypher) - 1;
FileManager::FileManager(HugoEngine *vm) : _vm(vm) {
- has_read_header = false;
- firstUIFFl = true;
+ _hasReadHeader = false;
+ _firstUIFFl = true;
}
FileManager::~FileManager() {
@@ -91,8 +91,8 @@ const char *FileManager::getUifFilename() const {
* Convert 4 planes (RGBI) data to 8-bit DIB format
* Return original plane data ptr
*/
-byte *FileManager::convertPCC(byte *p, const uint16 y, const uint16 bpl, image_pt dataPtr) const {
- debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, image_pt data_p)", y, bpl);
+byte *FileManager::convertPCC(byte *p, const uint16 y, const uint16 bpl, ImagePtr dataPtr) const {
+ debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, ImagePtr dataPtr)", y, bpl);
dataPtr += y * bpl * 8; // Point to correct DIB line
for (int16 r = 0, g = bpl, b = g + bpl, i = b + bpl; r < bpl; r++, g++, b++, i++) { // Each byte in all planes
@@ -107,47 +107,47 @@ byte *FileManager::convertPCC(byte *p, const uint16 y, const uint16 bpl, image_p
}
/**
- * Read a pcx file of length len. Use supplied seq_p and image_p or
- * allocate space if NULL. Name used for errors. Returns address of seq_p
+ * Read a pcx file of length len. Use supplied seqPtr and image_p or
+ * allocate space if NULL. Name used for errors. Returns address of seqPtr
* Set first TRUE to initialize b_index (i.e. not reading a sequential image in file).
*/
-seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr, const bool firstFl, const char *name) {
+Seq *FileManager::readPCX(Common::ReadStream &f, Seq *seqPtr, byte *imagePtr, const bool firstFl, const char *name) {
debugC(1, kDebugFile, "readPCX(..., %s)", name);
// Read in the PCC header and check consistency
- PCC_header.mfctr = f.readByte();
- PCC_header.vers = f.readByte();
- PCC_header.enc = f.readByte();
- PCC_header.bpx = f.readByte();
- PCC_header.x1 = f.readUint16LE();
- PCC_header.y1 = f.readUint16LE();
- PCC_header.x2 = f.readUint16LE();
- PCC_header.y2 = f.readUint16LE();
- PCC_header.xres = f.readUint16LE();
- PCC_header.yres = f.readUint16LE();
- f.read(PCC_header.palette, sizeof(PCC_header.palette));
- PCC_header.vmode = f.readByte();
- PCC_header.planes = f.readByte();
- PCC_header.bytesPerLine = f.readUint16LE();
- f.read(PCC_header.fill2, sizeof(PCC_header.fill2));
-
- if (PCC_header.mfctr != 10)
+ _PCCHeader._mfctr = f.readByte();
+ _PCCHeader._vers = f.readByte();
+ _PCCHeader._enc = f.readByte();
+ _PCCHeader._bpx = f.readByte();
+ _PCCHeader._x1 = f.readUint16LE();
+ _PCCHeader._y1 = f.readUint16LE();
+ _PCCHeader._x2 = f.readUint16LE();
+ _PCCHeader._y2 = f.readUint16LE();
+ _PCCHeader._xres = f.readUint16LE();
+ _PCCHeader._yres = f.readUint16LE();
+ f.read(_PCCHeader._palette, sizeof(_PCCHeader._palette));
+ _PCCHeader._vmode = f.readByte();
+ _PCCHeader._planes = f.readByte();
+ _PCCHeader._bytesPerLine = f.readUint16LE();
+ f.read(_PCCHeader._fill2, sizeof(_PCCHeader._fill2));
+
+ if (_PCCHeader._mfctr != 10)
error("Bad data file format: %s", name);
- // Allocate memory for seq_t if 0
+ // Allocate memory for Seq if 0
if (seqPtr == 0) {
- if ((seqPtr = (seq_t *)malloc(sizeof(seq_t))) == 0)
+ if ((seqPtr = (Seq *)malloc(sizeof(Seq))) == 0)
error("Insufficient memory to run game.");
}
// Find size of image data in 8-bit DIB format
// Note save of x2 - marks end of valid data before garbage
- uint16 bytesPerLine4 = PCC_header.bytesPerLine * 4; // 4-bit bpl
- seqPtr->bytesPerLine8 = bytesPerLine4 * 2; // 8-bit bpl
- seqPtr->lines = PCC_header.y2 - PCC_header.y1 + 1;
- seqPtr->x2 = PCC_header.x2 - PCC_header.x1 + 1;
+ uint16 bytesPerLine4 = _PCCHeader._bytesPerLine * 4; // 4-bit bpl
+ seqPtr->_bytesPerLine8 = bytesPerLine4 * 2; // 8-bit bpl
+ seqPtr->_lines = _PCCHeader._y2 - _PCCHeader._y1 + 1;
+ seqPtr->_x2 = _PCCHeader._x2 - _PCCHeader._x1 + 1;
// Size of the image
- uint16 size = seqPtr->lines * seqPtr->bytesPerLine8;
+ uint16 size = seqPtr->_lines * seqPtr->_bytesPerLine8;
// Allocate memory for image data if NULL
if (imagePtr == 0)
@@ -155,25 +155,25 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr
assert(imagePtr);
- seqPtr->imagePtr = imagePtr;
+ seqPtr->_imagePtr = imagePtr;
// Process the image data, converting to 8-bit DIB format
uint16 y = 0; // Current line index
byte pline[kXPix]; // Hold 4 planes of data
byte *p = pline; // Ptr to above
- while (y < seqPtr->lines) {
+ while (y < seqPtr->_lines) {
byte c = f.readByte();
if ((c & kRepeatMask) == kRepeatMask) {
byte d = f.readByte(); // Read data byte
for (int i = 0; i < (c & kLengthMask); i++) {
*p++ = d;
if ((uint16)(p - pline) == bytesPerLine4)
- p = convertPCC(pline, y++, PCC_header.bytesPerLine, imagePtr);
+ p = convertPCC(pline, y++, _PCCHeader._bytesPerLine, imagePtr);
}
} else {
*p++ = c;
if ((uint16)(p - pline) == bytesPerLine4)
- p = convertPCC(pline, y++, PCC_header.bytesPerLine, imagePtr);
+ p = convertPCC(pline, y++, _PCCHeader._bytesPerLine, imagePtr);
}
}
return seqPtr;
@@ -182,8 +182,8 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr
/**
* Read object file of PCC images into object supplied
*/
-void FileManager::readImage(const int objNum, object_t *objPtr) {
- debugC(1, kDebugFile, "readImage(%d, object_t *objPtr)", objNum);
+void FileManager::readImage(const int objNum, Object *objPtr) {
+ debugC(1, kDebugFile, "readImage(%d, Object *objPtr)", objNum);
/**
* Structure of object file lookup entry
@@ -193,7 +193,7 @@ void FileManager::readImage(const int objNum, object_t *objPtr) {
uint32 objLength;
};
- if (!objPtr->seqNumb) // This object has no images
+ if (!objPtr->_seqNumb) // This object has no images
return;
if (_vm->isPacked()) {
@@ -206,72 +206,72 @@ void FileManager::readImage(const int objNum, object_t *objPtr) {
_objectsArchive.seek(objBlock.objOffset, SEEK_SET);
} else {
Common::String buf;
- buf = _vm->_picDir + Common::String(_vm->_text->getNoun(objPtr->nounIndex, 0)) + ".PIX";
+ buf = _vm->_picDir + Common::String(_vm->_text->getNoun(objPtr->_nounIndex, 0)) + ".PIX";
if (!_objectsArchive.open(buf)) {
- buf = Common::String(_vm->_text->getNoun(objPtr->nounIndex, 0)) + ".PIX";
+ buf = Common::String(_vm->_text->getNoun(objPtr->_nounIndex, 0)) + ".PIX";
if (!_objectsArchive.open(buf))
error("File not found: %s", buf.c_str());
}
}
bool firstImgFl = true; // Initializes pcx read function
- seq_t *seqPtr = 0; // Ptr to sequence structure
+ Seq *seqPtr = 0; // Ptr to sequence structure
// Now read the images into an images list
- for (int j = 0; j < objPtr->seqNumb; j++) { // for each sequence
- for (int k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image
+ for (int j = 0; j < objPtr->_seqNumb; j++) { // for each sequence
+ for (int k = 0; k < objPtr->_seqList[j]._imageNbr; k++) { // each image
if (k == 0) { // First image
// Read this image - allocate both seq and image memory
- seqPtr = readPCX(_objectsArchive, 0, 0, firstImgFl, _vm->_text->getNoun(objPtr->nounIndex, 0));
- objPtr->seqList[j].seqPtr = seqPtr;
+ seqPtr = readPCX(_objectsArchive, 0, 0, firstImgFl, _vm->_text->getNoun(objPtr->_nounIndex, 0));
+ objPtr->_seqList[j]._seqPtr = seqPtr;
firstImgFl = false;
} else { // Subsequent image
// Read this image - allocate both seq and image memory
- seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstImgFl, _vm->_text->getNoun(objPtr->nounIndex, 0));
- seqPtr = seqPtr->nextSeqPtr;
+ seqPtr->_nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstImgFl, _vm->_text->getNoun(objPtr->_nounIndex, 0));
+ seqPtr = seqPtr->_nextSeqPtr;
}
// Compute the bounding box - x1, x2, y1, y2
// Note use of x2 - marks end of valid data in row
- uint16 x2 = seqPtr->x2;
- seqPtr->x1 = seqPtr->x2;
- seqPtr->x2 = 0;
- seqPtr->y1 = seqPtr->lines;
- seqPtr->y2 = 0;
-
- image_pt dibPtr = seqPtr->imagePtr;
- for (int y = 0; y < seqPtr->lines; y++, dibPtr += seqPtr->bytesPerLine8 - x2) {
+ uint16 x2 = seqPtr->_x2;
+ seqPtr->_x1 = seqPtr->_x2;
+ seqPtr->_x2 = 0;
+ seqPtr->_y1 = seqPtr->_lines;
+ seqPtr->_y2 = 0;
+
+ ImagePtr dibPtr = seqPtr->_imagePtr;
+ for (int y = 0; y < seqPtr->_lines; y++, dibPtr += seqPtr->_bytesPerLine8 - x2) {
for (int x = 0; x < x2; x++) {
if (*dibPtr++) { // Some data found
- if (x < seqPtr->x1)
- seqPtr->x1 = x;
- if (x > seqPtr->x2)
- seqPtr->x2 = x;
- if (y < seqPtr->y1)
- seqPtr->y1 = y;
- if (y > seqPtr->y2)
- seqPtr->y2 = y;
+ if (x < seqPtr->_x1)
+ seqPtr->_x1 = x;
+ if (x > seqPtr->_x2)
+ seqPtr->_x2 = x;
+ if (y < seqPtr->_y1)
+ seqPtr->_y1 = y;
+ if (y > seqPtr->_y2)
+ seqPtr->_y2 = y;
}
}
}
}
assert(seqPtr);
- seqPtr->nextSeqPtr = objPtr->seqList[j].seqPtr; // loop linked list to head
+ seqPtr->_nextSeqPtr = objPtr->_seqList[j]._seqPtr; // loop linked list to head
}
// Set the current image sequence to first or last
- switch (objPtr->cycling) {
+ switch (objPtr->_cycling) {
case kCycleInvisible: // (May become visible later)
case kCycleAlmostInvisible:
case kCycleNotCycling:
case kCycleForward:
- objPtr->currImagePtr = objPtr->seqList[0].seqPtr;
+ objPtr->_currImagePtr = objPtr->_seqList[0]._seqPtr;
break;
case kCycleBackward:
- objPtr->currImagePtr = seqPtr;
+ objPtr->_currImagePtr = seqPtr;
break;
default:
- warning("Unexpected cycling: %d", objPtr->cycling);
+ warning("Unexpected cycling: %d", objPtr->_cycling);
}
if (!_vm->isPacked())
@@ -282,7 +282,7 @@ void FileManager::readImage(const int objNum, object_t *objPtr) {
* Read sound (or music) file data. Call with SILENCE to free-up
* any allocated memory. Also returns size of data
*/
-sound_pt FileManager::getSound(const int16 sound, uint16 *size) {
+SoundPtr FileManager::getSound(const int16 sound, uint16 *size) {
debugC(1, kDebugFile, "getSound(%d)", sound);
// No more to do if SILENCE (called for cleanup purposes)
@@ -296,27 +296,27 @@ sound_pt FileManager::getSound(const int16 sound, uint16 *size) {
return 0;
}
- if (!has_read_header) {
+ if (!_hasReadHeader) {
for (int i = 0; i < kMaxSounds; i++) {
- s_hdr[i].size = fp.readUint16LE();
- s_hdr[i].offset = fp.readUint32LE();
+ _soundHdr[i]._size = fp.readUint16LE();
+ _soundHdr[i]._offset = fp.readUint32LE();
}
if (fp.err())
error("Wrong sound file format");
- has_read_header = true;
+ _hasReadHeader = true;
}
- *size = s_hdr[sound].size;
+ *size = _soundHdr[sound]._size;
if (*size == 0)
error("Wrong sound file format or missing sound %d", sound);
// Allocate memory for sound or music, if possible
- sound_pt soundPtr = (byte *)malloc(s_hdr[sound].size); // Ptr to sound data
+ SoundPtr soundPtr = (byte *)malloc(_soundHdr[sound]._size); // Ptr to sound data
assert(soundPtr);
// Seek to data and read it
- fp.seek(s_hdr[sound].offset, SEEK_SET);
- if (fp.read(soundPtr, s_hdr[sound].size) != s_hdr[sound].size)
+ fp.seek(_soundHdr[sound]._offset, SEEK_SET);
+ if (fp.read(soundPtr, _soundHdr[sound]._size) != _soundHdr[sound]._size)
error("Wrong sound file format");
fp.close();
@@ -330,15 +330,12 @@ sound_pt FileManager::getSound(const int16 sound, uint16 *size) {
bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip.c_str());
- const EnginePlugin *plugin = NULL;
int16 savegameId;
Common::String savegameDescription;
- EngineMan.findGame(_vm->getGameId(), &plugin);
if (slot == -1) {
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save");
- dialog->setSaveMode(true);
- savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true);
+ savegameId = dialog->runModalWithCurrentTarget();
savegameDescription = dialog->getResultString();
delete dialog;
} else {
@@ -385,7 +382,7 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
_vm->_object->saveObjects(out);
- const status_t &gameStatus = _vm->getGameStatus();
+ const Status &gameStatus = _vm->getGameStatus();
// Save whether hero image is swapped
out->writeByte(_vm->_heroImage);
@@ -394,13 +391,13 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
out->writeSint16BE(_vm->getScore());
// Save story mode
- out->writeByte((gameStatus.storyModeFl) ? 1 : 0);
+ out->writeByte((gameStatus._storyModeFl) ? 1 : 0);
// Save jumpexit mode
out->writeByte((_vm->_mouse->getJumpExitFl()) ? 1 : 0);
// Save gameover status
- out->writeByte((gameStatus.gameOverFl) ? 1 : 0);
+ out->writeByte((gameStatus._gameOverFl) ? 1 : 0);
// Save screen states
for (int i = 0; i < _vm->_numStates; i++)
@@ -411,17 +408,17 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
_vm->_screen->savePal(out);
// Save maze status
- out->writeByte((_vm->_maze.enabledFl) ? 1 : 0);
- out->writeByte(_vm->_maze.size);
- out->writeSint16BE(_vm->_maze.x1);
- out->writeSint16BE(_vm->_maze.y1);
- out->writeSint16BE(_vm->_maze.x2);
- out->writeSint16BE(_vm->_maze.y2);
- out->writeSint16BE(_vm->_maze.x3);
- out->writeSint16BE(_vm->_maze.x4);
- out->writeByte(_vm->_maze.firstScreenIndex);
-
- out->writeByte((byte)_vm->getGameStatus().viewState);
+ out->writeByte((_vm->_maze._enabledFl) ? 1 : 0);
+ out->writeByte(_vm->_maze._size);
+ out->writeSint16BE(_vm->_maze._x1);
+ out->writeSint16BE(_vm->_maze._y1);
+ out->writeSint16BE(_vm->_maze._x2);
+ out->writeSint16BE(_vm->_maze._y2);
+ out->writeSint16BE(_vm->_maze._x3);
+ out->writeSint16BE(_vm->_maze._x4);
+ out->writeByte(_vm->_maze._firstScreenIndex);
+
+ out->writeByte((byte)_vm->getGameStatus()._viewState);
out->finalize();
@@ -436,14 +433,11 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
bool FileManager::restoreGame(const int16 slot) {
debugC(1, kDebugFile, "restoreGame(%d)", slot);
- const EnginePlugin *plugin = NULL;
int16 savegameId;
- EngineMan.findGame(_vm->getGameId(), &plugin);
if (slot == -1) {
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore");
- dialog->setSaveMode(false);
- savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false);
+ savegameId = dialog->runModalWithCurrentTarget();
delete dialog;
} else {
savegameId = slot;
@@ -492,14 +486,14 @@ bool FileManager::restoreGame(const int16 slot) {
_vm->_object->swapImages(kHeroIndex, _vm->_heroImage);
_vm->_heroImage = heroImg;
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
int score = in->readSint16BE();
_vm->setScore(score);
- gameStatus.storyModeFl = (in->readByte() == 1);
+ gameStatus._storyModeFl = (in->readByte() == 1);
_vm->_mouse->setJumpExitFl(in->readByte() == 1);
- gameStatus.gameOverFl = (in->readByte() == 1);
+ gameStatus._gameOverFl = (in->readByte() == 1);
for (int i = 0; i < _vm->_numStates; i++)
_vm->_screenStates[i] = in->readByte();
@@ -509,18 +503,18 @@ bool FileManager::restoreGame(const int16 slot) {
_vm->_screen->restorePal(in);
// Restore maze status
- _vm->_maze.enabledFl = (in->readByte() == 1);
- _vm->_maze.size = in->readByte();
- _vm->_maze.x1 = in->readSint16BE();
- _vm->_maze.y1 = in->readSint16BE();
- _vm->_maze.x2 = in->readSint16BE();
- _vm->_maze.y2 = in->readSint16BE();
- _vm->_maze.x3 = in->readSint16BE();
- _vm->_maze.x4 = in->readSint16BE();
- _vm->_maze.firstScreenIndex = in->readByte();
-
- _vm->_scheduler->restoreScreen(*_vm->_screen_p);
- if ((_vm->getGameStatus().viewState = (vstate_t) in->readByte()) != kViewPlay)
+ _vm->_maze._enabledFl = (in->readByte() == 1);
+ _vm->_maze._size = in->readByte();
+ _vm->_maze._x1 = in->readSint16BE();
+ _vm->_maze._y1 = in->readSint16BE();
+ _vm->_maze._x2 = in->readSint16BE();
+ _vm->_maze._y2 = in->readSint16BE();
+ _vm->_maze._x3 = in->readSint16BE();
+ _vm->_maze._x4 = in->readSint16BE();
+ _vm->_maze._firstScreenIndex = in->readByte();
+
+ _vm->_scheduler->restoreScreen(*_vm->_screenPtr);
+ if ((_vm->getGameStatus()._viewState = (Vstate) in->readByte()) != kViewPlay)
_vm->_screen->hideCursor();
@@ -542,25 +536,25 @@ void FileManager::printBootText() {
return;
} else {
Utils::notifyBox(Common::String::format("Missing startup file '%s'", getBootFilename()));
- _vm->getGameStatus().doQuitFl = true;
+ _vm->getGameStatus()._doQuitFl = true;
return;
}
}
// Allocate space for the text and print it
- char *buf = (char *)malloc(_vm->_boot.exit_len + 1);
+ char *buf = (char *)malloc(_vm->_boot._exitLen + 1);
if (buf) {
// Skip over the boot structure (already read) and read exit text
ofp.seek((long)sizeof(_vm->_boot), SEEK_SET);
- if (ofp.read(buf, _vm->_boot.exit_len) != (size_t)_vm->_boot.exit_len) {
+ if (ofp.read(buf, _vm->_boot._exitLen) != (size_t)_vm->_boot._exitLen) {
Utils::notifyBox(Common::String::format("Error while reading startup file '%s'", getBootFilename()));
- _vm->getGameStatus().doQuitFl = true;
+ _vm->getGameStatus()._doQuitFl = true;
return;
}
// Decrypt the exit text, using CRYPT substring
int i;
- for (i = 0; i < _vm->_boot.exit_len; i++)
+ for (i = 0; i < _vm->_boot._exitLen; i++)
buf[i] ^= s_bootCypher[i % s_bootCypherLen];
buf[i] = '\0';
@@ -583,32 +577,32 @@ void FileManager::readBootFile() {
if (_vm->_gameVariant == kGameVariantH1Dos) {
//TODO initialize properly _boot structure
warning("readBootFile - Skipping as H1 Dos may be a freeware");
- memset(_vm->_boot.distrib, '\0', sizeof(_vm->_boot.distrib));
- _vm->_boot.registered = kRegFreeware;
+ memset(_vm->_boot._distrib, '\0', sizeof(_vm->_boot._distrib));
+ _vm->_boot._registered = kRegFreeware;
return;
} else if (_vm->getPlatform() == Common::kPlatformPC) {
warning("readBootFile - Skipping as H2 and H3 Dos may be shareware");
- memset(_vm->_boot.distrib, '\0', sizeof(_vm->_boot.distrib));
- _vm->_boot.registered = kRegShareware;
+ memset(_vm->_boot._distrib, '\0', sizeof(_vm->_boot._distrib));
+ _vm->_boot._registered = kRegShareware;
return;
} else {
Utils::notifyBox(Common::String::format("Missing startup file '%s'", getBootFilename()));
- _vm->getGameStatus().doQuitFl = true;
+ _vm->getGameStatus()._doQuitFl = true;
return;
}
}
if (ofp.size() < (int32)sizeof(_vm->_boot)) {
Utils::notifyBox(Common::String::format("Corrupted startup file '%s'", getBootFilename()));
- _vm->getGameStatus().doQuitFl = true;
+ _vm->getGameStatus()._doQuitFl = true;
return;
}
- _vm->_boot.checksum = ofp.readByte();
- _vm->_boot.registered = ofp.readByte();
- ofp.read(_vm->_boot.pbswitch, sizeof(_vm->_boot.pbswitch));
- ofp.read(_vm->_boot.distrib, sizeof(_vm->_boot.distrib));
- _vm->_boot.exit_len = ofp.readUint16LE();
+ _vm->_boot._checksum = ofp.readByte();
+ _vm->_boot._registered = ofp.readByte();
+ ofp.read(_vm->_boot._pbswitch, sizeof(_vm->_boot._pbswitch));
+ ofp.read(_vm->_boot._distrib, sizeof(_vm->_boot._distrib));
+ _vm->_boot._exitLen = ofp.readUint16LE();
byte *p = (byte *)&_vm->_boot;
@@ -621,7 +615,7 @@ void FileManager::readBootFile() {
if (checksum) {
Utils::notifyBox(Common::String::format("Corrupted startup file '%s'", getBootFilename()));
- _vm->getGameStatus().doQuitFl = true;
+ _vm->getGameStatus()._doQuitFl = true;
}
}
@@ -630,28 +624,28 @@ void FileManager::readBootFile() {
* This file contains, between others, the bitmaps of the fonts used in the application
* UIF means User interface database (Windows Only)
*/
-uif_hdr_t *FileManager::getUIFHeader(const uif_t id) {
+UifHdr *FileManager::getUIFHeader(const Uif id) {
debugC(1, kDebugFile, "getUIFHeader(%d)", id);
// Initialize offset lookup if not read yet
- if (firstUIFFl) {
- firstUIFFl = false;
+ if (_firstUIFFl) {
+ _firstUIFFl = false;
// Open unbuffered to do far read
Common::File ip; // Image data file
if (!ip.open(getUifFilename()))
error("File not found: %s", getUifFilename());
- if (ip.size() < (int32)sizeof(UIFHeader))
+ if (ip.size() < (int32)sizeof(_UIFHeader))
error("Wrong UIF file format");
for (int i = 0; i < kMaxUifs; ++i) {
- UIFHeader[i].size = ip.readUint16LE();
- UIFHeader[i].offset = ip.readUint32LE();
+ _UIFHeader[i]._size = ip.readUint16LE();
+ _UIFHeader[i]._offset = ip.readUint32LE();
}
ip.close();
}
- return &UIFHeader[id];
+ return &_UIFHeader[id];
}
/**
@@ -666,18 +660,18 @@ void FileManager::readUIFItem(const int16 id, byte *buf) {
error("File not found: %s", getUifFilename());
// Seek to data
- uif_hdr_t *UIFHeaderPtr = getUIFHeader((uif_t)id);
- ip.seek(UIFHeaderPtr->offset, SEEK_SET);
+ UifHdr *_UIFHeaderPtr = getUIFHeader((Uif)id);
+ ip.seek(_UIFHeaderPtr->_offset, SEEK_SET);
// We support pcx images and straight data
- seq_t *dummySeq; // Dummy seq_t for image data
+ Seq *dummySeq; // Dummy Seq for image data
switch (id) {
case UIF_IMAGES: // Read uif images file
dummySeq = readPCX(ip, 0, buf, true, getUifFilename());
free(dummySeq);
break;
default: // Read file data into supplied array
- if (ip.read(buf, UIFHeaderPtr->size) != UIFHeaderPtr->size)
+ if (ip.read(buf, _UIFHeaderPtr->_size) != _UIFHeaderPtr->_size)
error("Wrong UIF file format");
break;
}
diff --git a/engines/hugo/file.h b/engines/hugo/file.h
index 3792c01ab4..e4aa7f7fec 100644
--- a/engines/hugo/file.h
+++ b/engines/hugo/file.h
@@ -34,11 +34,11 @@ namespace Hugo {
/**
* Enumerate overlay file types
*/
-enum ovl_t {kOvlBoundary, kOvlOverlay, kOvlBase};
+enum OvlType {kOvlBoundary, kOvlOverlay, kOvlBase};
-struct uif_hdr_t { // UIF font/image look up
- uint16 size; // Size of uif item
- uint32 offset; // Offset of item in file
+struct UifHdr { // UIF font/image look up
+ uint16 _size; // Size of uif item
+ uint32 _offset; // Offset of item in file
};
@@ -47,10 +47,10 @@ public:
FileManager(HugoEngine *vm);
virtual ~FileManager();
- sound_pt getSound(const int16 sound, uint16 *size);
+ SoundPtr getSound(const int16 sound, uint16 *size);
void readBootFile();
- void readImage(const int objNum, object_t *objPtr);
+ void readImage(const int objNum, Object *objPtr);
void readUIFImages();
void readUIFItem(const int16 id, byte *buf);
bool restoreGame(const int16 slot);
@@ -69,7 +69,7 @@ public:
virtual void instructions() const = 0;
virtual void readBackground(const int screenIndex) = 0;
- virtual void readOverlay(const int screenNum, image_pt image, ovl_t overlayType) = 0;
+ virtual void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType) = 0;
virtual const char *fetchString(const int index) = 0;
@@ -84,45 +84,45 @@ protected:
/**
* Structure of scenery file lookup entry
*/
- struct sceneBlock_t {
- uint32 scene_off;
- uint32 scene_len;
- uint32 b_off;
- uint32 b_len;
- uint32 o_off;
- uint32 o_len;
- uint32 ob_off;
- uint32 ob_len;
+ struct SceneBlock {
+ uint32 _sceneOffset;
+ uint32 _sceneLength;
+ uint32 _boundaryOffset;
+ uint32 _boundaryLength;
+ uint32 _overlayOffset;
+ uint32 _overlayLength;
+ uint32 _baseOffset;
+ uint32 _baseLength;
};
- struct PCC_header_t { // Structure of PCX file header
- byte mfctr, vers, enc, bpx;
- uint16 x1, y1, x2, y2; // bounding box
- uint16 xres, yres;
- byte palette[3 * kNumColors]; // EGA color palette
- byte vmode, planes;
- uint16 bytesPerLine; // Bytes per line
- byte fill2[60];
+ struct PCCHeader { // Structure of PCX file header
+ byte _mfctr, _vers, _enc, _bpx;
+ uint16 _x1, _y1, _x2, _y2; // bounding box
+ uint16 _xres, _yres;
+ byte _palette[3 * kNumColors]; // EGA color palette
+ byte _vmode, _planes;
+ uint16 _bytesPerLine; // Bytes per line
+ byte _fill2[60];
}; // Header of a PCC file
- bool firstUIFFl;
- uif_hdr_t UIFHeader[kMaxUifs]; // Lookup for uif fonts/images
+ bool _firstUIFFl;
+ UifHdr _UIFHeader[kMaxUifs]; // Lookup for uif fonts/images
Common::File _stringArchive; // Handle for string file
Common::File _sceneryArchive1; // Handle for scenery file
Common::File _objectsArchive; // Handle for objects file
- PCC_header_t PCC_header;
+ PCCHeader _PCCHeader;
- seq_t *readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr, const bool firstFl, const char *name);
+ Seq *readPCX(Common::ReadStream &f, Seq *seqPtr, byte *imagePtr, const bool firstFl, const char *name);
// If this is the first call, read the lookup table
- bool has_read_header;
- sound_hdr_t s_hdr[kMaxSounds]; // Sound lookup table
+ bool _hasReadHeader;
+ SoundHdr _soundHdr[kMaxSounds]; // Sound lookup table
private:
- byte *convertPCC(byte *p, const uint16 y, const uint16 bpl, image_pt dataPtr) const;
- uif_hdr_t *getUIFHeader(const uif_t id);
+ byte *convertPCC(byte *p, const uint16 y, const uint16 bpl, ImagePtr dataPtr) const;
+ UifHdr *getUIFHeader(const Uif id);
//Strangerke : Not used?
void printBootText();
@@ -137,7 +137,7 @@ public:
virtual void instructions() const;
virtual void openDatabaseFiles();
virtual void readBackground(const int screenIndex);
- virtual void readOverlay(const int screenNum, image_pt image, ovl_t overlayType);
+ virtual void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType);
virtual const char *fetchString(const int index);
};
@@ -149,7 +149,7 @@ public:
virtual void closeDatabaseFiles();
virtual void openDatabaseFiles();
virtual void readBackground(const int screenIndex);
- virtual void readOverlay(const int screenNum, image_pt image, ovl_t overlayType);
+ virtual void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType);
const char *fetchString(const int index);
private:
char *_fetchStringBuf;
@@ -163,7 +163,7 @@ public:
void closeDatabaseFiles();
void openDatabaseFiles();
void readBackground(const int screenIndex);
- void readOverlay(const int screenNum, image_pt image, ovl_t overlayType);
+ void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType);
private:
Common::File _sceneryArchive2; // Handle for scenery file
};
@@ -181,7 +181,7 @@ public:
FileManager_v1w(HugoEngine *vm);
~FileManager_v1w();
- void readOverlay(const int screenNum, image_pt image, ovl_t overlayType);
+ void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType);
};
} // End of namespace Hugo
diff --git a/engines/hugo/file_v1d.cpp b/engines/hugo/file_v1d.cpp
index c3bb0e275f..e42223fb13 100644
--- a/engines/hugo/file_v1d.cpp
+++ b/engines/hugo/file_v1d.cpp
@@ -55,11 +55,11 @@ void FileManager_v1d::closeDatabaseFiles() {
/**
* Open and read in an overlay file, close file
*/
-void FileManager_v1d::readOverlay(const int screenNum, image_pt image, const ovl_t overlayType) {
+void FileManager_v1d::readOverlay(const int screenNum, ImagePtr image, const OvlType overlayType) {
debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
- const char *ovl_ext[] = {".b", ".o", ".ob"};
- Common::String buf = Common::String(_vm->_text->getScreenNames(screenNum)) + Common::String(ovl_ext[overlayType]);
+ const char *ovlExt[] = {".b", ".o", ".ob"};
+ Common::String buf = Common::String(_vm->_text->getScreenNames(screenNum)) + Common::String(ovlExt[overlayType]);
if (!Common::File::exists(buf)) {
memset(image, 0, kOvlSize);
@@ -70,7 +70,7 @@ void FileManager_v1d::readOverlay(const int screenNum, image_pt image, const ovl
if (!_sceneryArchive1.open(buf))
error("File not found: %s", buf.c_str());
- image_pt tmpImage = image; // temp ptr to overlay file
+ ImagePtr tmpImage = image; // temp ptr to overlay file
_sceneryArchive1.read(tmpImage, kOvlSize);
_sceneryArchive1.close();
@@ -87,7 +87,7 @@ void FileManager_v1d::readBackground(const int screenIndex) {
if (!_sceneryArchive1.open(buf))
error("File not found: %s", buf.c_str());
// Read the image into dummy seq and static dib_a
- seq_t *dummySeq; // Image sequence structure for Read_pcx
+ Seq *dummySeq; // Image sequence structure for Read_pcx
dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex));
free(dummySeq);
_sceneryArchive1.close();
diff --git a/engines/hugo/file_v1w.cpp b/engines/hugo/file_v1w.cpp
index 8a06cef939..002a1dc103 100644
--- a/engines/hugo/file_v1w.cpp
+++ b/engines/hugo/file_v1w.cpp
@@ -45,35 +45,35 @@ FileManager_v1w::~FileManager_v1w() {
/**
* Open and read in an overlay file, close file
*/
-void FileManager_v1w::readOverlay(const int screenNum, image_pt image, ovl_t overlayType) {
+void FileManager_v1w::readOverlay(const int screenNum, ImagePtr image, OvlType overlayType) {
debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
- image_pt tmpImage = image; // temp ptr to overlay file
- _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
+ ImagePtr tmpImage = image; // temp ptr to overlay file
+ _sceneryArchive1.seek((uint32)screenNum * sizeof(SceneBlock), SEEK_SET);
- sceneBlock_t sceneBlock; // Database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+ SceneBlock sceneBlock; // Database header entry
+ sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._sceneLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseLength = _sceneryArchive1.readUint32LE();
uint32 i = 0;
switch (overlayType) {
case kOvlBoundary:
- _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
- i = sceneBlock.b_len;
+ _sceneryArchive1.seek(sceneBlock._boundaryOffset, SEEK_SET);
+ i = sceneBlock._boundaryLength;
break;
case kOvlOverlay:
- _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
- i = sceneBlock.o_len;
+ _sceneryArchive1.seek(sceneBlock._overlayOffset, SEEK_SET);
+ i = sceneBlock._overlayLength;
break;
case kOvlBase:
- _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
- i = sceneBlock.ob_len;
+ _sceneryArchive1.seek(sceneBlock._baseOffset, SEEK_SET);
+ i = sceneBlock._baseLength;
break;
default:
error("Bad overlayType: %d", overlayType);
diff --git a/engines/hugo/file_v2d.cpp b/engines/hugo/file_v2d.cpp
index 520e1b77b6..19c90980b0 100644
--- a/engines/hugo/file_v2d.cpp
+++ b/engines/hugo/file_v2d.cpp
@@ -78,22 +78,22 @@ void FileManager_v2d::closeDatabaseFiles() {
void FileManager_v2d::readBackground(const int screenIndex) {
debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
- _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET);
+ _sceneryArchive1.seek((uint32) screenIndex * sizeof(SceneBlock), SEEK_SET);
- sceneBlock_t sceneBlock; // Read a database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+ SceneBlock sceneBlock; // Read a database header entry
+ sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._sceneLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseLength = _sceneryArchive1.readUint32LE();
- _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET);
+ _sceneryArchive1.seek(sceneBlock._sceneOffset, SEEK_SET);
// Read the image into dummy seq and static dib_a
- seq_t *dummySeq; // Image sequence structure for Read_pcx
+ Seq *dummySeq; // Image sequence structure for Read_pcx
dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex));
free(dummySeq);
}
@@ -101,35 +101,35 @@ void FileManager_v2d::readBackground(const int screenIndex) {
/**
* Open and read in an overlay file, close file
*/
-void FileManager_v2d::readOverlay(const int screenNum, image_pt image, ovl_t overlayType) {
+void FileManager_v2d::readOverlay(const int screenNum, ImagePtr image, OvlType overlayType) {
debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
- image_pt tmpImage = image; // temp ptr to overlay file
- _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
+ ImagePtr tmpImage = image; // temp ptr to overlay file
+ _sceneryArchive1.seek((uint32)screenNum * sizeof(SceneBlock), SEEK_SET);
- sceneBlock_t sceneBlock; // Database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+ SceneBlock sceneBlock; // Database header entry
+ sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._sceneLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseLength = _sceneryArchive1.readUint32LE();
uint32 i = 0;
switch (overlayType) {
case kOvlBoundary:
- _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
- i = sceneBlock.b_len;
+ _sceneryArchive1.seek(sceneBlock._boundaryOffset, SEEK_SET);
+ i = sceneBlock._boundaryLength;
break;
case kOvlOverlay:
- _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
- i = sceneBlock.o_len;
+ _sceneryArchive1.seek(sceneBlock._overlayOffset, SEEK_SET);
+ i = sceneBlock._overlayLength;
break;
case kOvlBase:
- _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
- i = sceneBlock.ob_len;
+ _sceneryArchive1.seek(sceneBlock._baseOffset, SEEK_SET);
+ i = sceneBlock._baseLength;
break;
default:
error("Bad overlayType: %d", overlayType);
diff --git a/engines/hugo/file_v3d.cpp b/engines/hugo/file_v3d.cpp
index d86003a040..5eb0cfc2c8 100644
--- a/engines/hugo/file_v3d.cpp
+++ b/engines/hugo/file_v3d.cpp
@@ -50,25 +50,25 @@ FileManager_v3d::~FileManager_v3d() {
void FileManager_v3d::readBackground(const int screenIndex) {
debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
- _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET);
-
- sceneBlock_t sceneBlock; // Read a database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
-
- seq_t *dummySeq; // Image sequence structure for Read_pcx
+ _sceneryArchive1.seek((uint32) screenIndex * sizeof(SceneBlock), SEEK_SET);
+
+ SceneBlock sceneBlock; // Read a database header entry
+ sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._sceneLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseLength = _sceneryArchive1.readUint32LE();
+
+ Seq *dummySeq; // Image sequence structure for Read_pcx
if (screenIndex < 20) {
- _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET);
+ _sceneryArchive1.seek(sceneBlock._sceneOffset, SEEK_SET);
// Read the image into dummy seq and static dib_a
dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex));
} else {
- _sceneryArchive2.seek(sceneBlock.scene_off, SEEK_SET);
+ _sceneryArchive2.seek(sceneBlock._sceneOffset, SEEK_SET);
// Read the image into dummy seq and static dib_a
dummySeq = readPCX(_sceneryArchive2, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex));
}
@@ -106,37 +106,37 @@ void FileManager_v3d::closeDatabaseFiles() {
/**
* Open and read in an overlay file, close file
*/
-void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t overlayType) {
+void FileManager_v3d::readOverlay(const int screenNum, ImagePtr image, OvlType overlayType) {
debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
- image_pt tmpImage = image; // temp ptr to overlay file
- _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
+ ImagePtr tmpImage = image; // temp ptr to overlay file
+ _sceneryArchive1.seek((uint32)screenNum * sizeof(SceneBlock), SEEK_SET);
- sceneBlock_t sceneBlock; // Database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+ SceneBlock sceneBlock; // Database header entry
+ sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._sceneLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._overlayLength = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseOffset = _sceneryArchive1.readUint32LE();
+ sceneBlock._baseLength = _sceneryArchive1.readUint32LE();
uint32 i = 0;
if (screenNum < 20) {
switch (overlayType) {
case kOvlBoundary:
- _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
- i = sceneBlock.b_len;
+ _sceneryArchive1.seek(sceneBlock._boundaryOffset, SEEK_SET);
+ i = sceneBlock._boundaryLength;
break;
case kOvlOverlay:
- _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
- i = sceneBlock.o_len;
+ _sceneryArchive1.seek(sceneBlock._overlayOffset, SEEK_SET);
+ i = sceneBlock._overlayLength;
break;
case kOvlBase:
- _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
- i = sceneBlock.ob_len;
+ _sceneryArchive1.seek(sceneBlock._baseOffset, SEEK_SET);
+ i = sceneBlock._baseLength;
break;
default:
error("Bad overlayType: %d", overlayType);
@@ -166,16 +166,16 @@ void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t ove
} else {
switch (overlayType) {
case kOvlBoundary:
- _sceneryArchive2.seek(sceneBlock.b_off, SEEK_SET);
- i = sceneBlock.b_len;
+ _sceneryArchive2.seek(sceneBlock._boundaryOffset, SEEK_SET);
+ i = sceneBlock._boundaryLength;
break;
case kOvlOverlay:
- _sceneryArchive2.seek(sceneBlock.o_off, SEEK_SET);
- i = sceneBlock.o_len;
+ _sceneryArchive2.seek(sceneBlock._overlayOffset, SEEK_SET);
+ i = sceneBlock._overlayLength;
break;
case kOvlBase:
- _sceneryArchive2.seek(sceneBlock.ob_off, SEEK_SET);
- i = sceneBlock.ob_len;
+ _sceneryArchive2.seek(sceneBlock._baseOffset, SEEK_SET);
+ i = sceneBlock._baseLength;
break;
default:
error("Bad overlayType: %d", overlayType);
diff --git a/engines/hugo/game.h b/engines/hugo/game.h
index b1c5f407b3..ed49ee8cbe 100644
--- a/engines/hugo/game.h
+++ b/engines/hugo/game.h
@@ -45,7 +45,7 @@ namespace Hugo {
enum {LOOK_NAME = 1, TAKE_NAME}; // Index of name used in showing takeables and in confirming take
// Definitions of 'generic' commands: Max # depends on size of gencmd in
-// the object_t record since each requires 1 bit. Currently up to 16
+// the Object record since each requires 1 bit. Currently up to 16
enum {LOOK = 1, TAKE = 2, DROP = 4, LOOK_S = 8};
enum TEXTCOLORS {
@@ -55,25 +55,25 @@ enum TEXTCOLORS {
_TLIGHTRED, _TLIGHTMAGENTA, _TLIGHTYELLOW, _TBRIGHTWHITE
};
-enum uif_t {U_FONT5, U_FONT6, U_FONT8, UIF_IMAGES, NUM_UIF_ITEMS};
+enum Uif {U_FONT5, U_FONT6, U_FONT8, UIF_IMAGES, NUM_UIF_ITEMS};
static const int kFirstFont = U_FONT5;
/**
* Enumerate ways of cycling a sequence of frames
*/
-enum cycle_t {kCycleInvisible, kCycleAlmostInvisible, kCycleNotCycling, kCycleForward, kCycleBackward};
+enum Cycle {kCycleInvisible, kCycleAlmostInvisible, kCycleNotCycling, kCycleForward, kCycleBackward};
/**
* Enumerate sequence index matching direction of travel
*/
enum {SEQ_RIGHT, SEQ_LEFT, SEQ_DOWN, SEQ_UP};
-enum font_t {LARGE_ROMAN, MED_ROMAN, NUM_GDI_FONTS, INIT_FONTS, DEL_FONTS};
+enum Font {LARGE_ROMAN, MED_ROMAN, NUM_GDI_FONTS, INIT_FONTS, DEL_FONTS};
/**
* Enumerate the different path types for an object
*/
-enum path_t {
+enum Path {
kPathUser, // User has control of object via cursor keys
kPathAuto, // Computer has control, controlled by action lists
kPathQuiet, // Computer has control and no commands allowed
@@ -83,55 +83,55 @@ enum path_t {
kPathWander2 // Same as WANDER, except keeps cycling when stationary
};
-struct hugo_boot_t { // Common HUGO boot file
- char checksum; // Checksum for boot structure (not exit text)
- char registered; // TRUE if registered version, else FALSE
- char pbswitch[8]; // Playback switch string
- char distrib[32]; // Distributor branding string
- uint16 exit_len; // Length of exit text (next in file)
+struct hugoBoot { // Common HUGO boot file
+ char _checksum; // Checksum for boot structure (not exit text)
+ char _registered; // TRUE if registered version, else FALSE
+ char _pbswitch[8]; // Playback switch string
+ char _distrib[32]; // Distributor branding string
+ uint16 _exitLen; // Length of exit text (next in file)
} PACKED_STRUCT;
/**
* Game specific type definitions
*/
-typedef byte *image_pt; // ptr to an object image (sprite)
-typedef byte *sound_pt; // ptr to sound (or music) data
+typedef byte *ImagePtr; // ptr to an object image (sprite)
+typedef byte *SoundPtr; // ptr to sound (or music) data
/**
* Structure for initializing maze processing
*/
-struct maze_t {
- bool enabledFl; // TRUE when maze processing enabled
- byte size; // Size of (square) maze matrix
- int x1, y1, x2, y2; // maze hotspot bounding box
- int x3, x4; // north, south x entry coordinates
- byte firstScreenIndex; // index of first screen in maze
+struct Maze {
+ bool _enabledFl; // TRUE when maze processing enabled
+ byte _size; // Size of (square) maze matrix
+ int _x1, _y1, _x2, _y2; // maze hotspot bounding box
+ int _x3, _x4; // north, south x entry coordinates
+ byte _firstScreenIndex; // index of first screen in maze
};
/**
* The following is a linked list of images in an animation sequence
* The image data is in 8-bit DIB format, i.e. 1 byte = 1 pixel
*/
-struct seq_t { // Linked list of images
- byte *imagePtr; // ptr to image
- uint16 bytesPerLine8; // bytes per line (8bits)
- uint16 lines; // lines
- uint16 x1, x2, y1, y2; // Offsets from x,y: data bounding box
- seq_t *nextSeqPtr; // ptr to next record
+struct Seq { // Linked list of images
+ byte *_imagePtr; // ptr to image
+ uint16 _bytesPerLine8; // bytes per line (8bits)
+ uint16 _lines; // lines
+ uint16 _x1, _x2, _y1, _y2; // Offsets from x,y: data bounding box
+ Seq *_nextSeqPtr; // ptr to next record
};
/**
* The following is an array of structures of above sequences
*/
-struct seqList_t {
- uint16 imageNbr; // Number of images in sequence
- seq_t *seqPtr; // Ptr to sequence structure
+struct SeqList {
+ uint16 _imageNbr; // Number of images in sequence
+ Seq *_seqPtr; // Ptr to sequence structure
};
#include "common/pack-start.h" // START STRUCT PACKING
-struct sound_hdr_t { // Sound file lookup entry
- uint16 size; // Size of sound data in bytes
- uint32 offset; // Offset of sound data in file
+struct SoundHdr { // Sound file lookup entry
+ uint16 _size; // Size of sound data in bytes
+ uint32 _offset; // Offset of sound data in file
} PACKED_STRUCT;
#include "common/pack-end.h" // END STRUCT PACKING
@@ -140,38 +140,38 @@ static const int kMaxSeqNumb = 4; // Number of sequences of im
/**
* Following is definition of object attributes
*/
-struct object_t {
- uint16 nounIndex; // String identifying object
- uint16 dataIndex; // String describing the object
- uint16 *stateDataIndex; // Added by Strangerke to handle the LOOK_S state-dependant descriptions
- path_t pathType; // Describe path object follows
- int vxPath, vyPath; // Delta velocities (e.g. for CHASE)
- uint16 actIndex; // Action list to do on collision with hero
- byte seqNumb; // Number of sequences in list
- seq_t *currImagePtr; // Sequence image currently in use
- seqList_t seqList[kMaxSeqNumb]; // Array of sequence structure ptrs and lengths
- cycle_t cycling; // Whether cycling, forward or backward
- byte cycleNumb; // No. of times to cycle
- byte frameInterval; // Interval (in ticks) between frames
- byte frameTimer; // Decrementing timer for above
- int8 radius; // Defines sphere of influence by hero
- byte screenIndex; // Screen in which object resides
- int x, y; // Current coordinates of object
- int oldx, oldy; // Previous coordinates of object
- int8 vx, vy; // Velocity
- byte objValue; // Value of object
- int genericCmd; // Bit mask of 'generic' commands for object
- uint16 cmdIndex; // ptr to list of cmd structures for verbs
- bool carriedFl; // TRUE if object being carried
- byte state; // state referenced in cmd list
- bool verbOnlyFl; // TRUE if verb-only cmds allowed e.g. sit,look
- byte priority; // Whether object fore, background or floating
- int16 viewx, viewy; // Position to view object from (or 0 or -1)
- int16 direction; // Direction to view object from
- byte curSeqNum; // Save which seq number currently in use
- byte curImageNum; // Save which image of sequence currently in use
- int8 oldvx; // Previous vx (used in wandering)
- int8 oldvy; // Previous vy
+struct Object {
+ uint16 _nounIndex; // String identifying object
+ uint16 _dataIndex; // String describing the object
+ uint16 *_stateDataIndex; // Added by Strangerke to handle the LOOK_S state-dependant descriptions
+ Path _pathType; // Describe path object follows
+ int _vxPath, _vyPath; // Delta velocities (e.g. for CHASE)
+ uint16 _actIndex; // Action list to do on collision with hero
+ byte _seqNumb; // Number of sequences in list
+ Seq *_currImagePtr; // Sequence image currently in use
+ SeqList _seqList[kMaxSeqNumb]; // Array of sequence structure ptrs and lengths
+ Cycle _cycling; // Whether cycling, forward or backward
+ byte _cycleNumb; // No. of times to cycle
+ byte _frameInterval; // Interval (in ticks) between frames
+ byte _frameTimer; // Decrementing timer for above
+ int8 _radius; // Defines sphere of influence by hero
+ byte _screenIndex; // Screen in which object resides
+ int _x, _y; // Current coordinates of object
+ int _oldx, _oldy; // Previous coordinates of object
+ int8 _vx, _vy; // Velocity
+ byte _objValue; // Value of object
+ int _genericCmd; // Bit mask of 'generic' commands for object
+ uint16 _cmdIndex; // ptr to list of cmd structures for verbs
+ bool _carriedFl; // TRUE if object being carried
+ byte _state; // state referenced in cmd list
+ bool _verbOnlyFl; // TRUE if verb-only cmds allowed e.g. sit,look
+ byte _priority; // Whether object fore, background or floating
+ int16 _viewx, _viewy; // Position to view object from (or 0 or -1)
+ int16 _direction; // Direction to view object from
+ byte _curSeqNum; // Save which seq number currently in use
+ byte _curImageNum; // Save which image of sequence currently in use
+ int8 _oldvx; // Previous vx (used in wandering)
+ int8 _oldvy; // Previous vy
};
} // End of namespace Hugo
diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp
index df8abf32eb..f2db630198 100644
--- a/engines/hugo/hugo.cpp
+++ b/engines/hugo/hugo.cpp
@@ -106,7 +106,7 @@ GUI::Debugger *HugoEngine::getDebugger() {
return _console;
}
-status_t &HugoEngine::getGameStatus() {
+Status &HugoEngine::getGameStatus() {
return _status;
}
@@ -249,24 +249,24 @@ Common::Error HugoEngine::run() {
initStatus(); // Initialize game status
initConfig(); // Initialize user's config
- if (!_status.doQuitFl) {
+ if (!_status._doQuitFl) {
initialize();
resetConfig(); // Reset user's config
initMachine();
// Start the state machine
- _status.viewState = kViewIntroInit;
+ _status._viewState = kViewIntroInit;
int16 loadSlot = Common::ConfigManager::instance().getInt("save_slot");
if (loadSlot >= 0) {
- _status.skipIntroFl = true;
+ _status._skipIntroFl = true;
_file->restoreGame(loadSlot);
} else {
_file->saveGame(0, "New Game");
}
}
- while (!_status.doQuitFl) {
+ while (!_status._doQuitFl) {
_screen->drawBoundaries();
g_system->updateScreen();
runMachine();
@@ -289,20 +289,20 @@ Common::Error HugoEngine::run() {
_mouse->setRightButton();
break;
case Common::EVENT_QUIT:
- _status.doQuitFl = true;
+ _status._doQuitFl = true;
break;
default:
break;
}
}
- if (_status.helpFl) {
- _status.helpFl = false;
+ if (_status._helpFl) {
+ _status._helpFl = false;
_file->instructions();
}
_mouse->mouseHandler(); // Mouse activity - adds to display list
_screen->displayList(kDisplayDisplay); // Blit the display list to screen
- _status.doQuitFl |= shouldQuit(); // update game quit flag
+ _status._doQuitFl |= shouldQuit(); // update game quit flag
}
return Common::kNoError;
}
@@ -323,10 +323,10 @@ void HugoEngine::initMachine() {
* Hugo game state machine - called during onIdle
*/
void HugoEngine::runMachine() {
- status_t &gameStatus = getGameStatus();
+ Status &gameStatus = getGameStatus();
// Don't process if gameover
- if (gameStatus.gameOverFl)
+ if (gameStatus._gameOverFl)
return;
_curTime = g_system->getMillis();
@@ -338,19 +338,19 @@ void HugoEngine::runMachine() {
_lastTime = _curTime;
- switch (gameStatus.viewState) {
+ switch (gameStatus._viewState) {
case kViewIdle: // Not processing state machine
_screen->hideCursor();
_intro->preNewGame(); // Any processing before New Game selected
break;
case kViewIntroInit: // Initialization before intro begins
_intro->introInit();
- gameStatus.viewState = kViewIntro;
+ gameStatus._viewState = kViewIntro;
break;
case kViewIntro: // Do any game-dependant preamble
if (_intro->introPlay()) { // Process intro screen
_scheduler->newScreen(0); // Initialize first screen
- gameStatus.viewState = kViewPlay;
+ gameStatus._viewState = kViewPlay;
}
break;
case kViewPlay: // Playing game
@@ -368,8 +368,8 @@ void HugoEngine::runMachine() {
_inventory->runInventory(); // Process Inventory state machine
break;
case kViewExit: // Game over or user exited
- gameStatus.viewState = kViewIdle;
- _status.doQuitFl = true;
+ gameStatus._viewState = kViewIdle;
+ _status._doQuitFl = true;
break;
}
}
@@ -427,7 +427,7 @@ bool HugoEngine::loadHugoDat() {
_scheduler->loadActListArr(in);
_scheduler->loadAlNewscrIndex(in);
_hero = &_object->_objects[kHeroIndex]; // This always points to hero
- _screen_p = &(_object->_objects[kHeroIndex].screenIndex); // Current screen is hero's
+ _screenPtr = &(_object->_objects[kHeroIndex]._screenIndex); // Current screen is hero's
_heroImage = kHeroIndex; // Current in use hero image
for (int varnt = 0; varnt < _numVariant; varnt++) {
@@ -527,33 +527,33 @@ void HugoEngine::initPlaylist(bool playlist[kMaxTunes]) {
*/
void HugoEngine::initStatus() {
debugC(1, kDebugEngine, "initStatus");
- _status.storyModeFl = false; // Not in story mode
- _status.gameOverFl = false; // Hero not knobbled yet
- _status.lookFl = false; // Toolbar "look" button
- _status.recallFl = false; // Toolbar "recall" button
- _status.newScreenFl = false; // Screen not just loaded
- _status.godModeFl = false; // No special cheats allowed
- _status.showBoundariesFl = false; // Boundaries hidden by default
- _status.doQuitFl = false;
- _status.skipIntroFl = false;
- _status.helpFl = false;
+ _status._storyModeFl = false; // Not in story mode
+ _status._gameOverFl = false; // Hero not knobbled yet
+ _status._lookFl = false; // Toolbar "look" button
+ _status._recallFl = false; // Toolbar "recall" button
+ _status._newScreenFl = false; // Screen not just loaded
+ _status._godModeFl = false; // No special cheats allowed
+ _status._showBoundariesFl = false; // Boundaries hidden by default
+ _status._doQuitFl = false;
+ _status._skipIntroFl = false;
+ _status._helpFl = false;
// Initialize every start of new game
- _status.tick = 0; // Tick count
- _status.viewState = kViewIdle; // View state
+ _status._tick = 0; // Tick count
+ _status._viewState = kViewIdle; // View state
// Strangerke - Suppress as related to playback
-// _status.recordFl = false; // Not record mode
-// _status.playbackFl = false; // Not playback mode
+// _status._recordFl = false; // Not record mode
+// _status._playbackFl = false; // Not playback mode
// Strangerke - Not used ?
-// _status.mmtime = false; // Multimedia timer support
-// _status.helpFl = false; // Not calling WinHelp()
-// _status.demoFl = false; // Not demo mode
-// _status.path[0] = 0; // Path to write files
-// _status.screenWidth = 0; // Desktop screen width
-// _status.saveTick = 0; // Time of last save
-// _status.saveSlot = 0; // Slot to save/restore game
-// _status.textBoxFl = false; // Not processing a text box
+// _status._mmtime = false; // Multimedia timer support
+// _status._helpFl = false; // Not calling WinHelp()
+// _status._demoFl = false; // Not demo mode
+// _status._path[0] = 0; // Path to write files
+// _status._screenWidth = 0; // Desktop screen width
+// _status._saveTick = 0; // Time of last save
+// _status._saveSlot = 0; // Slot to save/restore game
+// _status._textBoxFl = false; // Not processing a text box
}
/**
@@ -562,10 +562,10 @@ void HugoEngine::initStatus() {
void HugoEngine::initConfig() {
debugC(1, kDebugEngine, "initConfig()");
- _config.musicFl = true; // Music state initially on
- _config.soundFl = true; // Sound state initially on
- _config.turboFl = false; // Turbo state initially off
- initPlaylist(_config.playlist); // Initialize default tune playlist
+ _config._musicFl = true; // Music state initially on
+ _config._soundFl = true; // Sound state initially on
+ _config._turboFl = false; // Turbo state initially off
+ initPlaylist(_config._playlist); // Initialize default tune playlist
_file->readBootFile(); // Read startup structure
}
@@ -577,7 +577,7 @@ void HugoEngine::resetConfig() {
// Find first tune and play it
for (int16 i = 0; i < kMaxTunes; i++) {
- if (_config.playlist[i]) {
+ if (_config._playlist[i]) {
_sound->playMusic(i);
break;
}
@@ -587,7 +587,7 @@ void HugoEngine::resetConfig() {
void HugoEngine::initialize() {
debugC(1, kDebugEngine, "initialize");
- _maze.enabledFl = false;
+ _maze._enabledFl = false;
_line[0] = '\0';
_sound->initSound();
@@ -639,10 +639,10 @@ void HugoEngine::readScreenFiles(const int screenNum) {
memcpy(_screen->getBackBuffer(), _screen->getFrontBuffer(), sizeof(_screen->getFrontBuffer())); // Make a copy
// Workaround for graphic glitches in DOS versions. Cleaning the overlays fix the problem
- memset(_object->_objBound, '\0', sizeof(overlay_t));
- memset(_object->_boundary, '\0', sizeof(overlay_t));
- memset(_object->_overlay, '\0', sizeof(overlay_t));
- memset(_object->_ovlBase, '\0', sizeof(overlay_t));
+ memset(_object->_objBound, '\0', sizeof(Overlay));
+ memset(_object->_boundary, '\0', sizeof(Overlay));
+ memset(_object->_overlay, '\0', sizeof(Overlay));
+ memset(_object->_ovlBase, '\0', sizeof(Overlay));
_file->readOverlay(screenNum, _object->_boundary, kOvlBoundary); // Boundary file
_file->readOverlay(screenNum, _object->_overlay, kOvlOverlay); // Overlay file
@@ -660,7 +660,7 @@ void HugoEngine::readScreenFiles(const int screenNum) {
void HugoEngine::setNewScreen(const int screenNum) {
debugC(1, kDebugEngine, "setNewScreen(%d)", screenNum);
- *_screen_p = screenNum; // HERO object
+ *_screenPtr = screenNum; // HERO object
_object->setCarriedScreen(screenNum); // Carried objects
}
@@ -679,10 +679,10 @@ void HugoEngine::calcMaxScore() {
void HugoEngine::endGame() {
debugC(1, kDebugEngine, "endGame");
- if (_boot.registered != kRegRegistered)
+ if (_boot._registered != kRegRegistered)
Utils::notifyBox(_text->getTextEngine(kEsAdvertise));
Utils::notifyBox(Common::String::format("%s\n%s", _episode, getCopyrightString()));
- _status.viewState = kViewExit;
+ _status._viewState = kViewExit;
}
bool HugoEngine::canLoadGameStateCurrently() {
@@ -690,11 +690,11 @@ bool HugoEngine::canLoadGameStateCurrently() {
}
bool HugoEngine::canSaveGameStateCurrently() {
- return (_status.viewState == kViewPlay);
+ return (_status._viewState == kViewPlay);
}
int8 HugoEngine::getTPS() const {
- return ((_config.turboFl) ? kTurboTps : _normalTPS);
+ return ((_config._turboFl) ? kTurboTps : _normalTPS);
}
void HugoEngine::syncSoundSettings() {
diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h
index 125819a39b..9f495a9037 100644
--- a/engines/hugo/hugo.h
+++ b/engines/hugo/hugo.h
@@ -80,18 +80,18 @@ static const int kMaxPath = 256; // Max length of a full path
static const int kHeroMaxWidth = 24; // Maximum width of hero
static const int kHeroMinWidth = 16; // Minimum width of hero
-typedef char command_t[kMaxLineSize + 8]; // Command line (+spare for prompt,cursor)
+typedef char Command[kMaxLineSize + 8]; // Command line (+spare for prompt,cursor)
-struct config_t { // User's config (saved)
- bool musicFl; // State of Music button/menu item
- bool soundFl; // State of Sound button/menu item
- bool turboFl; // State of Turbo button/menu item
- bool playlist[kMaxTunes]; // Tune playlist
+struct Config { // User's config (saved)
+ bool _musicFl; // State of Music button/menu item
+ bool _soundFl; // State of Sound button/menu item
+ bool _turboFl; // State of Turbo button/menu item
+ bool _playlist[kMaxTunes]; // Tune playlist
};
-typedef byte icondib_t[kXPix * kInvDy]; // Icon bar dib
-typedef byte viewdib_t[(long)kXPix * kYPix]; // Viewport dib
-typedef byte overlay_t[kOvlSize]; // Overlay file
+typedef byte Icondib[kXPix * kInvDy]; // Icon bar dib
+typedef byte Viewdib[(long)kXPix * kYPix]; // Viewport dib
+typedef byte Overlay[kOvlSize]; // Overlay file
enum GameType {
kGameTypeNone = 0,
@@ -131,12 +131,12 @@ enum HugoRegistered {
/**
* Inventory icon bar states
*/
-enum istate_t {kInventoryOff, kInventoryUp, kInventoryDown, kInventoryActive};
+enum Istate {kInventoryOff, kInventoryUp, kInventoryDown, kInventoryActive};
/**
* Game view state machine
*/
-enum vstate_t {kViewIdle, kViewIntroInit, kViewIntro, kViewPlay, kViewInvent, kViewExit};
+enum Vstate {kViewIdle, kViewIntroInit, kViewIntro, kViewPlay, kViewInvent, kViewExit};
/**
* Enumerate whether object is foreground, background or 'floating'
@@ -152,12 +152,12 @@ enum {kPriorityForeground, kPriorityBackground, kPriorityFloating, kPriorityOver
/**
* Display list functions
*/
-enum dupdate_t {kDisplayInit, kDisplayAdd, kDisplayDisplay, kDisplayRestore};
+enum Dupdate {kDisplayInit, kDisplayAdd, kDisplayDisplay, kDisplayRestore};
/**
* Priority for sound effect
*/
-enum priority_t {kSoundPriorityLow, kSoundPriorityMedium, kSoundPriorityHigh};
+enum Priority {kSoundPriorityLow, kSoundPriorityMedium, kSoundPriorityHigh};
enum HugoGameFeatures {
GF_PACKED = (1 << 0) // Database
@@ -170,47 +170,31 @@ enum seqTextEngine {
struct HugoGameDescription;
-struct status_t { // Game status (not saved)
- bool storyModeFl; // Game is telling story - no commands
- bool gameOverFl; // Game is over - hero knobbled
- bool lookFl; // Toolbar "look" button pressed
- bool recallFl; // Toolbar "recall" button pressed
- bool newScreenFl; // New screen just loaded in dib_a
- bool godModeFl; // Allow DEBUG features in live version
- bool showBoundariesFl; // Flag used to show and hide boundaries,
+struct Status { // Game status (not saved)
+ bool _storyModeFl; // Game is telling story - no commands
+ bool _gameOverFl; // Game is over - hero knobbled
+ bool _lookFl; // Toolbar "look" button pressed
+ bool _recallFl; // Toolbar "recall" button pressed
+ bool _newScreenFl; // New screen just loaded in dib_a
+ bool _godModeFl; // Allow DEBUG features in live version
+ bool _showBoundariesFl; // Flag used to show and hide boundaries,
// used by the console
- bool doQuitFl;
- bool skipIntroFl;
- bool helpFl;
- uint32 tick; // Current time in ticks
- vstate_t viewState; // View state machine
- int16 song; // Current song
-
-// Strangerke - Suppress as related to playback
-// bool playbackFl; // Game is in playback mode
-// bool recordFl; // Game is in record mode
-// Strangerke - Not used ?
-// bool helpFl; // Calling WinHelp (don't disable music)
-// bool mmtimeFl; // Multimedia timer supported
-// bool demoFl; // Game is in demo mode
-// bool textBoxFl; // Game is (halted) in text box
-// int16 screenWidth; // Desktop screen width
-// int16 saveSlot; // Current slot to save/restore game
-// int16 cx, cy; // Cursor position (dib coords)
-// uint32 saveTick; // Time of last save in ticks
-//
-// typedef char fpath_t[kMaxPath]; // File path
-// fpath_t path; // Alternate path for saved files
+ bool _doQuitFl;
+ bool _skipIntroFl;
+ bool _helpFl;
+ uint32 _tick; // Current time in ticks
+ Vstate _viewState; // View state machine
+ int16 _song; // Current song
};
/**
* Structure to define an EXIT or other collision-activated hotspot
*/
-struct hotspot_t {
- int screenIndex; // Screen in which hotspot appears
- int x1, y1, x2, y2; // Bounding box of hotspot
- uint16 actIndex; // Actions to carry out if a 'hit'
- int16 viewx, viewy, direction; // Used in auto-route mode
+struct Hotspot {
+ int _screenIndex; // Screen in which hotspot appears
+ int _x1, _y1, _x2, _y2; // Bounding box of hotspot
+ uint16 _actIndex; // Actions to carry out if a 'hit'
+ int16 _viewx, _viewy, _direction; // Used in auto-route mode
};
class FileManager;
@@ -241,19 +225,19 @@ public:
uint16 _numStates;
int8 _normalTPS; // Number of ticks (frames) per second.
// 8 for Win versions, 9 for DOS versions
- object_t *_hero;
- byte *_screen_p;
+ Object *_hero;
+ byte *_screenPtr;
byte _heroImage;
byte *_screenStates;
- command_t _line; // Line of user text input
- config_t _config; // User's config
+ Command _line; // Line of user text input
+ Config _config; // User's config
int16 *_defltTunes;
uint16 _look;
uint16 _take;
uint16 _drop;
- maze_t _maze; // Maze control structure
- hugo_boot_t _boot; // Boot info structure
+ Maze _maze; // Maze control structure
+ hugoBoot _boot; // Boot info structure
GUI::Debugger *getDebugger();
@@ -262,8 +246,8 @@ public:
const char *_episode;
Common::String _picDir;
- command_t _statusLine;
- command_t _scoreLine;
+ Command _statusLine;
+ Command _scoreLine;
const HugoGameDescription *_gameDescription;
uint32 getFeatures() const;
@@ -295,7 +279,7 @@ public:
void shutdown();
void syncSoundSettings();
- status_t &getGameStatus();
+ Status &getGameStatus();
int getScore() const;
void setScore(const int newScore);
void adjustScore(const int adjustment);
@@ -330,7 +314,7 @@ protected:
private:
static const int kTurboTps = 16; // This many in turbo mode
- status_t _status; // Game status structure
+ Status _status; // Game status structure
uint32 _lastTime;
uint32 _curTime;
diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp
index 72f718fe8e..f2ae06eb39 100644
--- a/engines/hugo/intro.cpp
+++ b/engines/hugo/intro.cpp
@@ -86,22 +86,22 @@ void intro_v1d::preNewGame() {
void intro_v1d::introInit() {
_introState = 0;
- introTicks = 0;
- surf.w = 320;
- surf.h = 200;
- surf.pixels = _vm->_screen->getFrontBuffer();
- surf.pitch = 320;
- surf.format = Graphics::PixelFormat::createFormatCLUT8();
+ _introTicks = 0;
+ _surf.w = 320;
+ _surf.h = 200;
+ _surf.pixels = _vm->_screen->getFrontBuffer();
+ _surf.pitch = 320;
+ _surf.format = Graphics::PixelFormat::createFormatCLUT8();
_vm->_screen->displayList(kDisplayInit);
}
bool intro_v1d::introPlay() {
byte introSize = getIntroSize();
- if (_vm->getGameStatus().skipIntroFl)
+ if (_vm->getGameStatus()._skipIntroFl)
return true;
- if (introTicks < introSize) {
+ if (_introTicks < introSize) {
switch (_introState++) {
case 0:
_vm->_screen->drawRectangle(true, 0, 0, 319, 199, _TMAGENTA);
@@ -113,32 +113,32 @@ bool intro_v1d::introPlay() {
_vm->_screen->drawShape(250,92,_TLIGHTMAGENTA,_TMAGENTA);
// TROMAN, size 10-5
- if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8)))
+ if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8)))
error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8");
char buffer[80];
- if (_vm->_boot.registered == kRegRegistered)
+ if (_vm->_boot._registered == kRegRegistered)
strcpy(buffer, "Registered Version");
- else if (_vm->_boot.registered == kRegShareware)
+ else if (_vm->_boot._registered == kRegShareware)
strcpy(buffer, "Shareware Version");
- else if (_vm->_boot.registered == kRegFreeware)
+ else if (_vm->_boot._registered == kRegFreeware)
strcpy(buffer, "Freeware Version");
else
- error("Unknown registration flag in hugo.bsf: %d", _vm->_boot.registered);
+ error("Unknown registration flag in hugo.bsf: %d", _vm->_boot._registered);
- font.drawString(&surf, buffer, 0, 163, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
- font.drawString(&surf, _vm->getCopyrightString(), 0, 176, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 163, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, _vm->getCopyrightString(), 0, 176, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
- if ((*_vm->_boot.distrib != '\0') && (scumm_stricmp(_vm->_boot.distrib, "David P. Gray"))) {
- sprintf(buffer, "Distributed by %s.", _vm->_boot.distrib);
- font.drawString(&surf, buffer, 0, 75, 320, _TMAGENTA, Graphics::kTextAlignCenter);
+ if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) {
+ sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib);
+ _font.drawString(&_surf, buffer, 0, 75, 320, _TMAGENTA, Graphics::kTextAlignCenter);
}
// SCRIPT, size 24-16
strcpy(buffer, "Hugo's");
- if (font.loadFromFON("SCRIPT.FON")) {
- font.drawString(&surf, buffer, 0, 20, 320, _TMAGENTA, Graphics::kTextAlignCenter);
+ if (_font.loadFromFON("SCRIPT.FON")) {
+ _font.drawString(&_surf, buffer, 0, 20, 320, _TMAGENTA, Graphics::kTextAlignCenter);
} else {
// Workaround: SCRIPT.FON doesn't load properly at the moment
_vm->_screen->loadFont(2);
@@ -146,78 +146,78 @@ bool intro_v1d::introPlay() {
}
// TROMAN, size 30-24
- if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 24)))
+ if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 24)))
error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 24");
strcpy(buffer, "House of Horrors !");
- font.drawString(&surf, buffer, 0, 50, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 50, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
break;
case 2:
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
// TROMAN, size 16-9
- if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14)))
+ if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14)))
error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 14");
strcpy(buffer, "S t a r r i n g :");
- font.drawString(&surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
break;
case 3:
// TROMAN, size 20-9
- if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18)))
+ if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18)))
error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 18");
strcpy(buffer, "Hugo !");
- font.drawString(&surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
break;
case 4:
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
// TROMAN, size 16-9
- if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14)))
+ if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14)))
error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 14");
strcpy(buffer, "P r o d u c e d b y :");
- font.drawString(&surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
break;
case 5:
// TROMAN size 16-9
strcpy(buffer, "David P Gray !");
- font.drawString(&surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
break;
case 6:
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
// TROMAN, size 16-9
strcpy(buffer, "D i r e c t e d b y :");
- font.drawString(&surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
break;
case 7:
// TROMAN, size 16-9
strcpy(buffer, "David P Gray !");
- font.drawString(&surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
break;
case 8:
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
// TROMAN, size 16-9
strcpy(buffer, "M u s i c b y :");
- font.drawString(&surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter);
break;
case 9:
// TROMAN, size 16-9
strcpy(buffer, "David P Gray !");
- font.drawString(&surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
break;
case 10:
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
// TROMAN, size 20-14
- if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18)))
+ if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18)))
error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 18");
strcpy(buffer, "E n j o y !");
- font.drawString(&surf, buffer, 0, 100, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 100, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter);
break;
}
@@ -226,7 +226,7 @@ bool intro_v1d::introPlay() {
g_system->delayMillis(1000);
}
- return (++introTicks >= introSize);
+ return (++_introTicks >= introSize);
}
intro_v2d::intro_v2d(HugoEngine *vm) : IntroHandler(vm) {
@@ -241,29 +241,29 @@ void intro_v2d::preNewGame() {
void intro_v2d::introInit() {
_vm->_screen->displayList(kDisplayInit);
_vm->_file->readBackground(_vm->_numScreens - 1); // display splash screen
- surf.w = 320;
- surf.h = 200;
- surf.pixels = _vm->_screen->getFrontBuffer();
- surf.pitch = 320;
- surf.format = Graphics::PixelFormat::createFormatCLUT8();
+ _surf.w = 320;
+ _surf.h = 200;
+ _surf.pixels = _vm->_screen->getFrontBuffer();
+ _surf.pitch = 320;
+ _surf.format = Graphics::PixelFormat::createFormatCLUT8();
char buffer[128];
// TROMAN, size 10-5
- if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8)))
+ if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8)))
error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8");
- if (_vm->_boot.registered)
+ if (_vm->_boot._registered)
sprintf(buffer, "%s Registered Version", _vm->getCopyrightString());
else
sprintf(buffer, "%s Shareware Version", _vm->getCopyrightString());
- font.drawString(&surf, buffer, 0, 186, 320, _TLIGHTRED, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 186, 320, _TLIGHTRED, Graphics::kTextAlignCenter);
- if ((*_vm->_boot.distrib != '\0') && (scumm_stricmp(_vm->_boot.distrib, "David P. Gray"))) {
+ if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) {
// TROMAN, size 10-5
- sprintf(buffer, "Distributed by %s.", _vm->_boot.distrib);
- font.drawString(&surf, buffer, 0, 1, 320, _TLIGHTRED, Graphics::kTextAlignCenter);
+ sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib);
+ _font.drawString(&_surf, buffer, 0, 1, 320, _TLIGHTRED, Graphics::kTextAlignCenter);
}
_vm->_screen->displayBackground();
@@ -287,27 +287,27 @@ void intro_v3d::preNewGame() {
void intro_v3d::introInit() {
_vm->_screen->displayList(kDisplayInit);
_vm->_file->readBackground(_vm->_numScreens - 1); // display splash screen
- surf.w = 320;
- surf.h = 200;
- surf.pixels = _vm->_screen->getFrontBuffer();
- surf.pitch = 320;
- surf.format = Graphics::PixelFormat::createFormatCLUT8();
+ _surf.w = 320;
+ _surf.h = 200;
+ _surf.pixels = _vm->_screen->getFrontBuffer();
+ _surf.pitch = 320;
+ _surf.format = Graphics::PixelFormat::createFormatCLUT8();
char buffer[128];
- if (_vm->_boot.registered)
+ if (_vm->_boot._registered)
sprintf(buffer, "%s Registered Version", _vm->getCopyrightString());
else
sprintf(buffer,"%s Shareware Version", _vm->getCopyrightString());
// TROMAN, size 10-5
- if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8)))
+ if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8)))
error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8");
- font.drawString(&surf, buffer, 0, 190, 320, _TBROWN, Graphics::kTextAlignCenter);
+ _font.drawString(&_surf, buffer, 0, 190, 320, _TBROWN, Graphics::kTextAlignCenter);
- if ((*_vm->_boot.distrib != '\0') && (scumm_stricmp(_vm->_boot.distrib, "David P. Gray"))) {
- sprintf(buffer, "Distributed by %s.", _vm->_boot.distrib);
- font.drawString(&surf, buffer, 0, 0, 320, _TBROWN, Graphics::kTextAlignCenter);
+ if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) {
+ sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib);
+ _font.drawString(&_surf, buffer, 0, 0, 320, _TBROWN, Graphics::kTextAlignCenter);
}
_vm->_screen->displayBackground();
@@ -316,7 +316,7 @@ void intro_v3d::introInit() {
_vm->_file->readBackground(22); // display screen MAP_3d
_vm->_screen->displayBackground();
- introTicks = 0;
+ _introTicks = 0;
_vm->_sound->_DOSSongPtr = _vm->_sound->_DOSIntroSong;
}
@@ -325,15 +325,15 @@ void intro_v3d::introInit() {
* Called every tick. Returns TRUE when complete
*/
bool intro_v3d::introPlay() {
- if (_vm->getGameStatus().skipIntroFl)
+ if (_vm->getGameStatus()._skipIntroFl)
return true;
- if (introTicks < getIntroSize()) {
- font.drawString(&surf, ".", _introX[introTicks], _introY[introTicks] - kDibOffY, 320, _TBRIGHTWHITE);
+ if (_introTicks < getIntroSize()) {
+ _font.drawString(&_surf, ".", _introX[_introTicks], _introY[_introTicks] - kDibOffY, 320, _TBRIGHTWHITE);
_vm->_screen->displayBackground();
// Text boxes at various times
- switch (introTicks) {
+ switch (_introTicks) {
case 4:
Utils::notifyBox(_vm->_text->getTextIntro(kIntro1));
break;
@@ -346,7 +346,7 @@ bool intro_v3d::introPlay() {
}
}
- return (++introTicks >= getIntroSize());
+ return (++_introTicks >= getIntroSize());
}
intro_v1w::intro_v1w(HugoEngine *vm) : IntroHandler(vm) {
@@ -356,7 +356,7 @@ intro_v1w::~intro_v1w() {
}
void intro_v1w::preNewGame() {
- _vm->getGameStatus().viewState = kViewIntroInit;
+ _vm->getGameStatus()._viewState = kViewIntroInit;
}
void intro_v1w::introInit() {
@@ -407,7 +407,7 @@ void intro_v3w::introInit() {
g_system->delayMillis(3000);
_vm->_file->readBackground(22); // display screen MAP_3w
_vm->_screen->displayBackground();
- introTicks = 0;
+ _introTicks = 0;
_vm->_screen->loadFont(0);
}
@@ -416,16 +416,16 @@ void intro_v3w::introInit() {
* Called every tick. Returns TRUE when complete
*/
bool intro_v3w::introPlay() {
- if (_vm->getGameStatus().skipIntroFl)
+ if (_vm->getGameStatus()._skipIntroFl)
return true;
- if (introTicks < getIntroSize()) {
+ if (_introTicks < getIntroSize()) {
// Scale viewport x_intro,y_intro to screen (offsetting y)
- _vm->_screen->writeStr(_introX[introTicks], _introY[introTicks] - kDibOffY, "x", _TBRIGHTWHITE);
+ _vm->_screen->writeStr(_introX[_introTicks], _introY[_introTicks] - kDibOffY, "x", _TBRIGHTWHITE);
_vm->_screen->displayBackground();
// Text boxes at various times
- switch (introTicks) {
+ switch (_introTicks) {
case 4:
Utils::notifyBox(_vm->_text->getTextIntro(kIntro1));
break;
@@ -438,6 +438,6 @@ bool intro_v3w::introPlay() {
}
}
- return (++introTicks >= getIntroSize());
+ return (++_introTicks >= getIntroSize());
}
} // End of namespace Hugo
diff --git a/engines/hugo/intro.h b/engines/hugo/intro.h
index 1bb039216a..d5a5a4e4b4 100644
--- a/engines/hugo/intro.h
+++ b/engines/hugo/intro.h
@@ -42,8 +42,8 @@ enum seqTextIntro {
class IntroHandler {
public:
IntroHandler(HugoEngine *vm);
- Graphics::Surface surf;
- Graphics::WinFont font;
+ Graphics::Surface _surf;
+ Graphics::WinFont _font;
virtual ~IntroHandler();
@@ -62,7 +62,7 @@ protected:
byte *_introX;
byte *_introY;
byte _introXSize;
- int16 introTicks; // Count calls to introPlay()
+ int16 _introTicks; // Count calls to introPlay()
};
class intro_v1w : public IntroHandler {
diff --git a/engines/hugo/inventory.cpp b/engines/hugo/inventory.cpp
index 410c4e715c..c2495beadb 100644
--- a/engines/hugo/inventory.cpp
+++ b/engines/hugo/inventory.cpp
@@ -56,7 +56,7 @@ void InventoryHandler::setInventoryObjId(int16 objId) {
_inventoryObjId = objId;
}
-void InventoryHandler::setInventoryState(istate_t state) {
+void InventoryHandler::setInventoryState(Istate state) {
_inventoryState = state;
}
@@ -68,7 +68,7 @@ int16 InventoryHandler::getInventoryObjId() const {
return _inventoryObjId;
}
-istate_t InventoryHandler::getInventoryState() const {
+Istate InventoryHandler::getInventoryState() const {
return _inventoryState;
}
@@ -137,8 +137,8 @@ void InventoryHandler::constructInventory(const int16 imageTotNumb, int displayN
* Process required action for inventory
* Returns objId under cursor (or -1) for INV_GET
*/
-int16 InventoryHandler::processInventory(const invact_t action, ...) {
- debugC(1, kDebugInventory, "processInventory(invact_t action, ...)");
+int16 InventoryHandler::processInventory(const InvAct action, ...) {
+ debugC(1, kDebugInventory, "processInventory(InvAct action, ...)");
int16 imageNumb; // Total number of inventory items
int displayNumb; // Total number displayed/carried
@@ -208,7 +208,7 @@ int16 InventoryHandler::processInventory(const invact_t action, ...) {
* Process inventory state machine
*/
void InventoryHandler::runInventory() {
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
debugC(1, kDebugInventory, "runInventory");
@@ -231,7 +231,7 @@ void InventoryHandler::runInventory() {
_vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getFrontBuffer(), 0, 0, kXPix);
_vm->_object->updateImages(); // Add objects back into display list for restore
_inventoryState = kInventoryOff;
- gameStatus.viewState = kViewPlay;
+ gameStatus._viewState = kViewPlay;
}
break;
case kInventoryDown: // Icon bar moving down
diff --git a/engines/hugo/inventory.h b/engines/hugo/inventory.h
index 666cc37b51..5b55c3ec94 100644
--- a/engines/hugo/inventory.h
+++ b/engines/hugo/inventory.h
@@ -34,22 +34,22 @@ namespace Hugo {
/**
* Actions for Process_inventory()
*/
-enum invact_t {kInventoryActionInit, kInventoryActionLeft, kInventoryActionRight, kInventoryActionGet};
+enum InvAct {kInventoryActionInit, kInventoryActionLeft, kInventoryActionRight, kInventoryActionGet};
class InventoryHandler {
public:
InventoryHandler(HugoEngine *vm);
void setInventoryObjId(int16 objId);
- void setInventoryState(istate_t state);
+ void setInventoryState(Istate state);
void freeInvent();
int16 getInventoryObjId() const;
- istate_t getInventoryState() const;
+ Istate getInventoryState() const;
int16 findIconId(int16 objId);
void loadInvent(Common::SeekableReadStream &in);
- int16 processInventory(const invact_t action, ...);
+ int16 processInventory(const InvAct action, ...);
void runInventory();
private:
@@ -59,7 +59,7 @@ private:
int16 _firstIconId; // Index of first icon to display
int16 *_invent;
- istate_t _inventoryState; // Inventory icon bar state
+ Istate _inventoryState; // Inventory icon bar state
int16 _inventoryHeight; // Inventory icon bar height
int16 _inventoryObjId; // Inventory object selected, or -1
byte _maxInvent;
diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp
index d2d5b59dae..a95170696c 100644
--- a/engines/hugo/mouse.cpp
+++ b/engines/hugo/mouse.cpp
@@ -98,17 +98,17 @@ int MouseHandler::getMouseY() const {
}
int16 MouseHandler::getDirection(const int16 hotspotId) const {
- return _hotspots[hotspotId].direction;
+ return _hotspots[hotspotId]._direction;
}
int16 MouseHandler::getHotspotActIndex(const int16 hotspotId) const {
- return _hotspots[hotspotId].actIndex;
+ return _hotspots[hotspotId]._actIndex;
}
/**
* Shadow-blit supplied string into dib_a at cx,cy and add to display list
*/
-void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy, const uif_t fontId, const int16 color) {
+void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy, const Uif fontId, const int16 color) {
debugC(1, kDebugMouse, "cursorText(%s, %d, %d, %d, %d)", buffer, cx, cy, fontId, color);
_vm->_screen->loadFont(fontId);
@@ -137,9 +137,9 @@ void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy
int16 MouseHandler::findExit(const int16 cx, const int16 cy, byte screenId) {
debugC(2, kDebugMouse, "findExit(%d, %d, %d)", cx, cy, screenId);
- for (int i = 0; _hotspots[i].screenIndex >= 0; i++) {
- if (_hotspots[i].screenIndex == screenId) {
- if (cx >= _hotspots[i].x1 && cx <= _hotspots[i].x2 && cy >= _hotspots[i].y1 && cy <= _hotspots[i].y2)
+ for (int i = 0; _hotspots[i]._screenIndex >= 0; i++) {
+ if (_hotspots[i]._screenIndex == screenId) {
+ if (cx >= _hotspots[i]._x1 && cx <= _hotspots[i]._x2 && cy >= _hotspots[i]._y1 && cy <= _hotspots[i]._y2)
return i;
}
}
@@ -152,9 +152,9 @@ int16 MouseHandler::findExit(const int16 cx, const int16 cy, byte screenId) {
void MouseHandler::processRightClick(const int16 objId, const int16 cx, const int16 cy) {
debugC(1, kDebugMouse, "ProcessRightClick(%d, %d, %d)", objId, cx, cy);
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
- if (gameStatus.storyModeFl || _vm->_hero->pathType == kPathQuiet) // Make sure user has control
+ if (gameStatus._storyModeFl || _vm->_hero->_pathType == kPathQuiet) // Make sure user has control
return;
int16 inventObjId = _vm->_inventory->getInventoryObjId();
@@ -168,9 +168,9 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in
else
_vm->_object->useObject(objId); // Use status.objid on object
} else { // Clicked over viewport object
- object_t *obj = &_vm->_object->_objects[objId];
+ Object *obj = &_vm->_object->_objects[objId];
int16 x, y;
- switch (obj->viewx) { // Where to walk to
+ switch (obj->_viewx) { // Where to walk to
case -1: // Walk to object position
if (_vm->_object->findObjectSpace(obj, &x, &y))
foundFl = _vm->_route->startRoute(kRouteGet, objId, x, y);
@@ -181,8 +181,8 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in
_vm->_object->useObject(objId); // Pick up or use object
break;
default: // Walk to view point if possible
- if (!_vm->_route->startRoute(kRouteGet, objId, obj->viewx, obj->viewy)) {
- if (_vm->_hero->cycling == kCycleInvisible) // If invisible do
+ if (!_vm->_route->startRoute(kRouteGet, objId, obj->_viewx, obj->_viewy)) {
+ if (_vm->_hero->_cycling == kCycleInvisible) // If invisible do
_vm->_object->useObject(objId); // immediate use
else
Utils::notifyBox(_vm->_text->getTextMouse(kMsNoWayText)); // Can't get there
@@ -203,11 +203,11 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int
debugC(1, kDebugMouse, "ProcessLeftClick(%d, %d, %d)", objId, cx, cy);
int16 i, x, y;
- object_t *obj;
+ Object *obj;
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
- if (gameStatus.storyModeFl || _vm->_hero->pathType == kPathQuiet) // Make sure user has control
+ if (gameStatus._storyModeFl || _vm->_hero->_pathType == kPathQuiet) // Make sure user has control
return;
switch (objId) {
@@ -223,20 +223,20 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int
_vm->_screen->displayList(kDisplayAdd, 0, kDibOffY, kXPix, kInvDy);
break;
case kExitHotspot: // Walk to exit hotspot
- i = findExit(cx, cy, *_vm->_screen_p);
- x = _hotspots[i].viewx;
- y = _hotspots[i].viewy;
+ i = findExit(cx, cy, *_vm->_screenPtr);
+ x = _hotspots[i]._viewx;
+ y = _hotspots[i]._viewy;
if (x >= 0) { // Hotspot refers to an exit
// Special case of immediate exit
if (_jumpExitFl) {
// Get rid of iconbar if necessary
if (_vm->_inventory->getInventoryState() != kInventoryOff)
_vm->_inventory->setInventoryState(kInventoryUp);
- _vm->_scheduler->insertActionList(_hotspots[i].actIndex);
+ _vm->_scheduler->insertActionList(_hotspots[i]._actIndex);
} else { // Set up route to exit spot
- if (_hotspots[i].direction == Common::KEYCODE_RIGHT)
+ if (_hotspots[i]._direction == Common::KEYCODE_RIGHT)
x -= kHeroMaxWidth;
- else if (_hotspots[i].direction == Common::KEYCODE_LEFT)
+ else if (_hotspots[i]._direction == Common::KEYCODE_LEFT)
x += kHeroMaxWidth;
if (!_vm->_route->startRoute(kRouteExit, i, x, y))
Utils::notifyBox(_vm->_text->getTextMouse(kMsNoWayText)); // Can't get there
@@ -254,7 +254,7 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int
_vm->_object->lookObject(obj);
} else {
bool foundFl = false; // TRUE if route found to object
- switch (obj->viewx) { // Clicked over viewport object
+ switch (obj->_viewx) { // Clicked over viewport object
case -1: // Walk to object position
if (_vm->_object->findObjectSpace(obj, &x, &y))
foundFl = _vm->_route->startRoute(kRouteLook, objId, x, y);
@@ -265,8 +265,8 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int
_vm->_object->lookObject(obj);
break;
default: // Walk to view point if possible
- if (!_vm->_route->startRoute(kRouteLook, objId, obj->viewx, obj->viewy)) {
- if (_vm->_hero->cycling == kCycleInvisible) // If invisible do
+ if (!_vm->_route->startRoute(kRouteLook, objId, obj->_viewx, obj->_viewy)) {
+ if (_vm->_hero->_cycling == kCycleInvisible) // If invisible do
_vm->_object->lookObject(obj); // immediate decription
else
Utils::notifyBox(_vm->_text->getTextMouse(kMsNoWayText)); // Can't get there
@@ -284,16 +284,16 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int
void MouseHandler::mouseHandler() {
debugC(2, kDebugMouse, "mouseHandler");
- status_t &gameStatus = _vm->getGameStatus();
- istate_t inventState = _vm->_inventory->getInventoryState();
- if ((gameStatus.viewState != kViewPlay) && (inventState != kInventoryActive))
+ Status &gameStatus = _vm->getGameStatus();
+ Istate inventState = _vm->_inventory->getInventoryState();
+ if ((gameStatus._viewState != kViewPlay) && (inventState != kInventoryActive))
return;
int16 cx = getMouseX();
int16 cy = getMouseY();
-// gameStatus.cx = cx; // Save cursor coords
-// gameStatus.cy = cy;
+// gameStatus._cx = cx; // Save cursor coords
+// gameStatus._cy = cy;
// Don't process if outside client area
if ((cx < 0) || (cx > kXPix) || (cy < kDibOffY) || (cy > kViewSizeY + kDibOffY))
@@ -309,14 +309,14 @@ void MouseHandler::mouseHandler() {
}
}
- if (!gameStatus.gameOverFl) {
+ if (!gameStatus._gameOverFl) {
if (objId == -1) // No match, check rest of view
objId = _vm->_object->findObject(cx, cy);
if (objId >= 0) { // Got a match
// Display object name next to cursor (unless CURSOR_NOCHAR)
// Note test for swapped hero name
- const char *name = _vm->_text->getNoun(_vm->_object->_objects[(objId == kHeroIndex) ? _vm->_heroImage : objId].nounIndex, kCursorNameIndex);
+ const char *name = _vm->_text->getNoun(_vm->_object->_objects[(objId == kHeroIndex) ? _vm->_heroImage : objId]._nounIndex, kCursorNameIndex);
if (name[0] != kCursorNochar)
cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE);
@@ -327,8 +327,8 @@ void MouseHandler::mouseHandler() {
// Process cursor over an exit hotspot
if (objId == -1) {
- int i = findExit(cx, cy, *_vm->_screen_p);
- if (i != -1 && _hotspots[i].viewx >= 0) {
+ int i = findExit(cx, cy, *_vm->_screenPtr);
+ if (i != -1 && _hotspots[i]._viewx >= 0) {
objId = kExitHotspot;
cursorText(_vm->_text->getTextMouse(kMsExit), cx, cy, U_FONT8, _TBRIGHTWHITE);
}
@@ -343,29 +343,29 @@ void MouseHandler::mouseHandler() {
resetRightButton();
}
-void MouseHandler::readHotspot(Common::ReadStream &in, hotspot_t &hotspot) {
- hotspot.screenIndex = in.readSint16BE();
- hotspot.x1 = in.readSint16BE();
- hotspot.y1 = in.readSint16BE();
- hotspot.x2 = in.readSint16BE();
- hotspot.y2 = in.readSint16BE();
- hotspot.actIndex = in.readUint16BE();
- hotspot.viewx = in.readSint16BE();
- hotspot.viewy = in.readSint16BE();
- hotspot.direction = in.readSint16BE();
+void MouseHandler::readHotspot(Common::ReadStream &in, Hotspot &hotspot) {
+ hotspot._screenIndex = in.readSint16BE();
+ hotspot._x1 = in.readSint16BE();
+ hotspot._y1 = in.readSint16BE();
+ hotspot._x2 = in.readSint16BE();
+ hotspot._y2 = in.readSint16BE();
+ hotspot._actIndex = in.readUint16BE();
+ hotspot._viewx = in.readSint16BE();
+ hotspot._viewy = in.readSint16BE();
+ hotspot._direction = in.readSint16BE();
}
/**
* Load hotspots data from hugo.dat
*/
void MouseHandler::loadHotspots(Common::ReadStream &in) {
- hotspot_t *wrkHotspots = 0;
- hotspot_t tmp;
+ Hotspot *wrkHotspots = 0;
+ Hotspot tmp;
memset(&tmp, 0, sizeof(tmp));
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
int numRows = in.readUint16BE();
if (varnt == _vm->_gameVariant)
- _hotspots = wrkHotspots = (hotspot_t *)malloc(sizeof(hotspot_t) * numRows);
+ _hotspots = wrkHotspots = (Hotspot *)malloc(sizeof(Hotspot) * numRows);
for (int i = 0; i < numRows; i++)
readHotspot(in, (varnt == _vm->_gameVariant) ? wrkHotspots[i] : tmp);
@@ -376,10 +376,10 @@ void MouseHandler::loadHotspots(Common::ReadStream &in) {
* Display hotspot boundaries for the current screen
*/
void MouseHandler::drawHotspots() const {
- for (int i = 0; _hotspots[i].screenIndex >= 0; i++) {
- hotspot_t *hotspot = &_hotspots[i];
- if (hotspot->screenIndex == _vm->_hero->screenIndex)
- _vm->_screen->drawRectangle(false, hotspot->x1, hotspot->y1, hotspot->x2, hotspot->y2, _TLIGHTRED);
+ for (int i = 0; _hotspots[i]._screenIndex >= 0; i++) {
+ Hotspot *hotspot = &_hotspots[i];
+ if (hotspot->_screenIndex == _vm->_hero->_screenIndex)
+ _vm->_screen->drawRectangle(false, hotspot->_x1, hotspot->_y1, hotspot->_x2, hotspot->_y2, _TLIGHTRED);
}
}
} // End of namespace Hugo
diff --git a/engines/hugo/mouse.h b/engines/hugo/mouse.h
index 35f9e4e87e..e20716f72c 100644
--- a/engines/hugo/mouse.h
+++ b/engines/hugo/mouse.h
@@ -70,17 +70,17 @@ private:
kMsExit = 1
};
- hotspot_t *_hotspots;
+ Hotspot *_hotspots;
bool _leftButtonFl; // Left mouse button pressed
bool _rightButtonFl; // Right button pressed
int _mouseX;
int _mouseY;
bool _jumpExitFl; // Allowed to jump to a screen exit
- void cursorText(const char *buffer, const int16 cx, const int16 cy, const uif_t fontId, const int16 color);
+ void cursorText(const char *buffer, const int16 cx, const int16 cy, const Uif fontId, const int16 color);
void processRightClick(const int16 objId, const int16 cx, const int16 cy);
void processLeftClick(const int16 objId, const int16 cx, const int16 cy);
- void readHotspot(Common::ReadStream &in, hotspot_t &hotspot);
+ void readHotspot(Common::ReadStream &in, Hotspot &hotspot);
};
} // End of namespace Hugo
diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp
index bc99abf410..7b4783e4d8 100644
--- a/engines/hugo/object.cpp
+++ b/engines/hugo/object.cpp
@@ -48,10 +48,10 @@ ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0), _uses(0) {
_numObj = 0;
_objCount = 0;
_usesSize = 0;
- memset(_objBound, '\0', sizeof(overlay_t));
- memset(_boundary, '\0', sizeof(overlay_t));
- memset(_overlay, '\0', sizeof(overlay_t));
- memset(_ovlBase, '\0', sizeof(overlay_t));
+ memset(_objBound, '\0', sizeof(Overlay));
+ memset(_boundary, '\0', sizeof(Overlay));
+ memset(_overlay, '\0', sizeof(Overlay));
+ memset(_ovlBase, '\0', sizeof(Overlay));
}
ObjectHandler::~ObjectHandler() {
@@ -74,55 +74,55 @@ byte ObjectHandler::getFirstOverlay(uint16 index) const {
}
bool ObjectHandler::isCarried(int objIndex) const {
- return _objects[objIndex].carriedFl;
+ return _objects[objIndex]._carriedFl;
}
void ObjectHandler::setCarry(int objIndex, bool val) {
- _objects[objIndex].carriedFl = val;
+ _objects[objIndex]._carriedFl = val;
}
void ObjectHandler::setVelocity(int objIndex, int8 vx, int8 vy) {
- _objects[objIndex].vx = vx;
- _objects[objIndex].vy = vy;
+ _objects[objIndex]._vx = vx;
+ _objects[objIndex]._vy = vy;
}
-void ObjectHandler::setPath(int objIndex, path_t pathType, int16 vxPath, int16 vyPath) {
- _objects[objIndex].pathType = pathType;
- _objects[objIndex].vxPath = vxPath;
- _objects[objIndex].vyPath = vyPath;
+void ObjectHandler::setPath(int objIndex, Path pathType, int16 vxPath, int16 vyPath) {
+ _objects[objIndex]._pathType = pathType;
+ _objects[objIndex]._vxPath = vxPath;
+ _objects[objIndex]._vyPath = vyPath;
}
/**
* Save sequence number and image number in given object
*/
-void ObjectHandler::saveSeq(object_t *obj) {
+void ObjectHandler::saveSeq(Object *obj) {
debugC(1, kDebugObject, "saveSeq");
bool found = false;
- for (int i = 0; !found && (i < obj->seqNumb); i++) {
- seq_t *q = obj->seqList[i].seqPtr;
- for (int j = 0; !found && (j < obj->seqList[i].imageNbr); j++) {
- if (obj->currImagePtr == q) {
+ for (int i = 0; !found && (i < obj->_seqNumb); i++) {
+ Seq *q = obj->_seqList[i]._seqPtr;
+ for (int j = 0; !found && (j < obj->_seqList[i]._imageNbr); j++) {
+ if (obj->_currImagePtr == q) {
found = true;
- obj->curSeqNum = i;
- obj->curImageNum = j;
+ obj->_curSeqNum = i;
+ obj->_curImageNum = j;
} else {
- q = q->nextSeqPtr;
+ q = q->_nextSeqPtr;
}
}
}
}
/**
- * Set up cur_seq_p from stored sequence and image number in object
+ * Set up cur_seqPtr from stored sequence and image number in object
*/
-void ObjectHandler::restoreSeq(object_t *obj) {
+void ObjectHandler::restoreSeq(Object *obj) {
debugC(1, kDebugObject, "restoreSeq");
- seq_t *q = obj->seqList[obj->curSeqNum].seqPtr;
- for (int j = 0; j < obj->curImageNum; j++)
- q = q->nextSeqPtr;
- obj->currImagePtr = q;
+ Seq *q = obj->_seqList[obj->_curSeqNum]._seqPtr;
+ for (int j = 0; j < obj->_curImageNum; j++)
+ q = q->_nextSeqPtr;
+ obj->_currImagePtr = q;
}
/**
@@ -134,36 +134,36 @@ void ObjectHandler::useObject(int16 objId) {
const char *verb; // Background verb to use directly
int16 inventObjId = _vm->_inventory->getInventoryObjId();
- object_t *obj = &_objects[objId]; // Ptr to object
+ Object *obj = &_objects[objId]; // Ptr to object
if (inventObjId == -1) {
// Get or use objid directly
- if ((obj->genericCmd & TAKE) || obj->objValue) // Get collectible item
- sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_take, 0), _vm->_text->getNoun(obj->nounIndex, 0));
- else if (obj->cmdIndex != 0) // Use non-collectible item if able
- sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(obj->cmdIndex), 0), _vm->_text->getNoun(obj->nounIndex, 0));
- else if ((verb = _vm->_parser->useBG(_vm->_text->getNoun(obj->nounIndex, 0))) != 0)
- sprintf(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->nounIndex, 0));
+ if ((obj->_genericCmd & TAKE) || obj->_objValue) // Get collectible item
+ sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_take, 0), _vm->_text->getNoun(obj->_nounIndex, 0));
+ else if (obj->_cmdIndex != 0) // Use non-collectible item if able
+ sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(obj->_cmdIndex), 0), _vm->_text->getNoun(obj->_nounIndex, 0));
+ else if ((verb = _vm->_parser->useBG(_vm->_text->getNoun(obj->_nounIndex, 0))) != 0)
+ sprintf(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->_nounIndex, 0));
else
return; // Can't use object directly
} else {
// Use status.objid on objid
// Default to first cmd verb
- sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(_objects[inventObjId].cmdIndex), 0),
- _vm->_text->getNoun(_objects[inventObjId].nounIndex, 0),
- _vm->_text->getNoun(obj->nounIndex, 0));
+ sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(_objects[inventObjId]._cmdIndex), 0),
+ _vm->_text->getNoun(_objects[inventObjId]._nounIndex, 0),
+ _vm->_text->getNoun(obj->_nounIndex, 0));
// Check valid use of objects and override verb if necessary
- for (uses_t *use = _uses; use->objId != _numObj; use++) {
- if (inventObjId == use->objId) {
+ for (Uses *use = _uses; use->_objId != _numObj; use++) {
+ if (inventObjId == use->_objId) {
// Look for secondary object, if found use matching verb
bool foundFl = false;
- for (target_t *target = use->targets; target->nounIndex != 0; target++)
- if (target->nounIndex == obj->nounIndex) {
+ for (Target *target = use->_targets; target->_nounIndex != 0; target++)
+ if (target->_nounIndex == obj->_nounIndex) {
foundFl = true;
- sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->verbIndex, 0),
- _vm->_text->getNoun(_objects[inventObjId].nounIndex, 0),
- _vm->_text->getNoun(obj->nounIndex, 0));
+ sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->_verbIndex, 0),
+ _vm->_text->getNoun(_objects[inventObjId]._nounIndex, 0),
+ _vm->_text->getNoun(obj->_nounIndex, 0));
}
// No valid use of objects found, print failure string
@@ -171,7 +171,7 @@ void ObjectHandler::useObject(int16 objId) {
// Deselect dragged icon if inventory not active
if (_vm->_inventory->getInventoryState() != kInventoryActive)
_vm->_screen->resetInventoryObjId();
- Utils::notifyBox(_vm->_text->getTextData(use->dataIndex));
+ Utils::notifyBox(_vm->_text->getTextData(use->_dataIndex));
return;
}
}
@@ -195,30 +195,30 @@ int16 ObjectHandler::findObject(uint16 x, uint16 y) {
int16 objIndex = -1; // Index of found object
uint16 y2Max = 0; // Greatest y2
- object_t *obj = _objects;
+ Object *obj = _objects;
// Check objects on screen
for (int i = 0; i < _numObj; i++, obj++) {
// Object must be in current screen and "useful"
- if (obj->screenIndex == *_vm->_screen_p && (obj->genericCmd || obj->objValue || obj->cmdIndex)) {
- seq_t *curImage = obj->currImagePtr;
+ if (obj->_screenIndex == *_vm->_screenPtr && (obj->_genericCmd || obj->_objValue || obj->_cmdIndex)) {
+ Seq *curImage = obj->_currImagePtr;
// Object must have a visible image...
- if (curImage != 0 && obj->cycling != kCycleInvisible) {
+ if (curImage != 0 && obj->_cycling != kCycleInvisible) {
// If cursor inside object
- if (x >= (uint16)obj->x && x <= obj->x + curImage->x2 && y >= (uint16)obj->y && y <= obj->y + curImage->y2) {
+ if (x >= (uint16)obj->_x && x <= obj->_x + curImage->_x2 && y >= (uint16)obj->_y && y <= obj->_y + curImage->_y2) {
// If object is closest so far
- if (obj->y + curImage->y2 > y2Max) {
- y2Max = obj->y + curImage->y2;
+ if (obj->_y + curImage->_y2 > y2Max) {
+ y2Max = obj->_y + curImage->_y2;
objIndex = i; // Found an object!
}
}
} else {
// ...or a dummy object that has a hotspot rectangle
- if (curImage == 0 && obj->vxPath != 0 && !obj->carriedFl) {
+ if (curImage == 0 && obj->_vxPath != 0 && !obj->_carriedFl) {
// If cursor inside special rectangle
- if ((int16)x >= obj->oldx && (int16)x < obj->oldx + obj->vxPath && (int16)y >= obj->oldy && (int16)y < obj->oldy + obj->vyPath) {
+ if ((int16)x >= obj->_oldx && (int16)x < obj->_oldx + obj->_vxPath && (int16)y >= obj->_oldy && (int16)y < obj->_oldy + obj->_vyPath) {
// If object is closest so far
- if (obj->oldy + obj->vyPath - 1 > (int16)y2Max) {
- y2Max = obj->oldy + obj->vyPath - 1;
+ if (obj->_oldy + obj->_vyPath - 1 > (int16)y2Max) {
+ y2Max = obj->_oldy + obj->_vyPath - 1;
objIndex = i; // Found an object!
}
}
@@ -233,14 +233,14 @@ int16 ObjectHandler::findObject(uint16 x, uint16 y) {
* Issue "Look at <object>" command
* Note special case of swapped hero image
*/
-void ObjectHandler::lookObject(object_t *obj) {
+void ObjectHandler::lookObject(Object *obj) {
debugC(1, kDebugObject, "lookObject");
if (obj == _vm->_hero)
// Hero swapped - look at other
obj = &_objects[_vm->_heroImage];
- _vm->_parser->command("%s %s", _vm->_text->getVerb(_vm->_look, 0), _vm->_text->getNoun(obj->nounIndex, 0));
+ _vm->_parser->command("%s %s", _vm->_text->getVerb(_vm->_look, 0), _vm->_text->getNoun(obj->_nounIndex, 0));
}
/**
@@ -249,26 +249,26 @@ void ObjectHandler::lookObject(object_t *obj) {
void ObjectHandler::freeObjects() {
debugC(1, kDebugObject, "freeObjects");
- if (_vm->_hero != 0 && _vm->_hero->seqList[0].seqPtr != 0) {
+ if (_vm->_hero != 0 && _vm->_hero->_seqList[0]._seqPtr != 0) {
// Free all sequence lists and image data
for (int16 i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i];
- for (int16 j = 0; j < obj->seqNumb; j++) {
- seq_t *seq = obj->seqList[j].seqPtr;
- seq_t *next;
+ Object *obj = &_objects[i];
+ for (int16 j = 0; j < obj->_seqNumb; j++) {
+ Seq *seq = obj->_seqList[j]._seqPtr;
+ Seq *next;
if (seq == 0) // Failure during database load
break;
- if (seq->imagePtr != 0) {
- free(seq->imagePtr);
- seq->imagePtr = 0;
+ if (seq->_imagePtr != 0) {
+ free(seq->_imagePtr);
+ seq->_imagePtr = 0;
}
- seq = seq->nextSeqPtr;
- while (seq != obj->seqList[j].seqPtr) {
- if (seq->imagePtr != 0) {
- free(seq->imagePtr);
- seq->imagePtr = 0;
+ seq = seq->_nextSeqPtr;
+ while (seq != obj->_seqList[j]._seqPtr) {
+ if (seq->_imagePtr != 0) {
+ free(seq->_imagePtr);
+ seq->_imagePtr = 0;
}
- next = seq->nextSeqPtr;
+ next = seq->_nextSeqPtr;
free(seq);
seq = next;
}
@@ -279,13 +279,13 @@ void ObjectHandler::freeObjects() {
if (_uses) {
for (int16 i = 0; i < _usesSize; i++)
- free(_uses[i].targets);
+ free(_uses[i]._targets);
free(_uses);
}
for (int16 i = 0; i < _objCount; i++) {
- free(_objects[i].stateDataIndex);
- _objects[i].stateDataIndex = 0;
+ free(_objects[i]._stateDataIndex);
+ _objects[i]._stateDataIndex = 0;
}
free(_objects);
@@ -300,27 +300,27 @@ void ObjectHandler::freeObjects() {
int ObjectHandler::y2comp(const void *a, const void *b) {
debugC(6, kDebugObject, "y2comp");
- const object_t *p1 = &HugoEngine::get()._object->_objects[*(const byte *)a];
- const object_t *p2 = &HugoEngine::get()._object->_objects[*(const byte *)b];
+ const Object *p1 = &HugoEngine::get()._object->_objects[*(const byte *)a];
+ const Object *p2 = &HugoEngine::get()._object->_objects[*(const byte *)b];
if (p1 == p2)
// Why does qsort try the same indexes?
return 0;
- if (p1->priority == kPriorityBackground)
+ if (p1->_priority == kPriorityBackground)
return -1;
- if (p2->priority == kPriorityBackground)
+ if (p2->_priority == kPriorityBackground)
return 1;
- if (p1->priority == kPriorityForeground)
+ if (p1->_priority == kPriorityForeground)
return 1;
- if (p2->priority == kPriorityForeground)
+ if (p2->_priority == kPriorityForeground)
return -1;
- int ay2 = p1->y + p1->currImagePtr->y2;
- int by2 = p2->y + p2->currImagePtr->y2;
+ int ay2 = p1->_y + p1->_currImagePtr->_y2;
+ int by2 = p2->_y + p2->_currImagePtr->_y2;
return ay2 - by2;
}
@@ -332,7 +332,7 @@ bool ObjectHandler::isCarrying(uint16 wordIndex) {
debugC(1, kDebugObject, "isCarrying(%d)", wordIndex);
for (int i = 0; i < _numObj; i++) {
- if ((wordIndex == _objects[i].nounIndex) && _objects[i].carriedFl)
+ if ((wordIndex == _objects[i]._nounIndex) && _objects[i]._carriedFl)
return true;
}
return false;
@@ -345,11 +345,11 @@ void ObjectHandler::showTakeables() {
debugC(1, kDebugObject, "showTakeables");
for (int j = 0; j < _numObj; j++) {
- object_t *obj = &_objects[j];
- if ((obj->cycling != kCycleInvisible) &&
- (obj->screenIndex == *_vm->_screen_p) &&
- (((TAKE & obj->genericCmd) == TAKE) || obj->objValue)) {
- Utils::notifyBox(Common::String::format("You can also see:\n%s.", _vm->_text->getNoun(obj->nounIndex, LOOK_NAME)));
+ Object *obj = &_objects[j];
+ if ((obj->_cycling != kCycleInvisible) &&
+ (obj->_screenIndex == *_vm->_screenPtr) &&
+ (((TAKE & obj->_genericCmd) == TAKE) || obj->_objValue)) {
+ Utils::notifyBox(Common::String::format("You can also see:\n%s.", _vm->_text->getNoun(obj->_nounIndex, LOOK_NAME)));
}
}
}
@@ -357,22 +357,22 @@ void ObjectHandler::showTakeables() {
/**
* Find a clear space around supplied object that hero can walk to
*/
-bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) {
+bool ObjectHandler::findObjectSpace(Object *obj, int16 *destx, int16 *desty) {
debugC(1, kDebugObject, "findObjectSpace(obj, %d, %d)", *destx, *desty);
- seq_t *curImage = obj->currImagePtr;
- int16 y = obj->y + curImage->y2 - 1;
+ Seq *curImage = obj->_currImagePtr;
+ int16 y = obj->_y + curImage->_y2 - 1;
bool foundFl = true;
// Try left rear corner
- for (int16 x = *destx = obj->x + curImage->x1; x < *destx + kHeroMaxWidth; x++) {
+ for (int16 x = *destx = obj->_x + curImage->_x1; x < *destx + kHeroMaxWidth; x++) {
if (checkBoundary(x, y))
foundFl = false;
}
if (!foundFl) { // Try right rear corner
foundFl = true;
- for (int16 x = *destx = obj->x + curImage->x2 - kHeroMaxWidth + 1; x <= obj->x + (int16)curImage->x2; x++) {
+ for (int16 x = *destx = obj->_x + curImage->_x2 - kHeroMaxWidth + 1; x <= obj->_x + (int16)curImage->_x2; x++) {
if (checkBoundary(x, y))
foundFl = false;
}
@@ -381,7 +381,7 @@ bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) {
if (!foundFl) { // Try left front corner
foundFl = true;
y += 2;
- for (int16 x = *destx = obj->x + curImage->x1; x < *destx + kHeroMaxWidth; x++) {
+ for (int16 x = *destx = obj->_x + curImage->_x1; x < *destx + kHeroMaxWidth; x++) {
if (checkBoundary(x, y))
foundFl = false;
}
@@ -389,7 +389,7 @@ bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) {
if (!foundFl) { // Try right rear corner
foundFl = true;
- for (int16 x = *destx = obj->x + curImage->x2 - kHeroMaxWidth + 1; x <= obj->x + (int16)curImage->x2; x++) {
+ for (int16 x = *destx = obj->_x + curImage->_x2 - kHeroMaxWidth + 1; x <= obj->_x + (int16)curImage->_x2; x++) {
if (checkBoundary(x, y))
foundFl = false;
}
@@ -399,29 +399,29 @@ bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) {
return foundFl;
}
-void ObjectHandler::readUse(Common::ReadStream &in, uses_t &curUse) {
- curUse.objId = in.readSint16BE();
- curUse.dataIndex = in.readUint16BE();
+void ObjectHandler::readUse(Common::ReadStream &in, Uses &curUse) {
+ curUse._objId = in.readSint16BE();
+ curUse._dataIndex = in.readUint16BE();
uint16 numSubElem = in.readUint16BE();
- curUse.targets = (target_t *)malloc(sizeof(target_t) * numSubElem);
+ curUse._targets = (Target *)malloc(sizeof(Target) * numSubElem);
for (int j = 0; j < numSubElem; j++) {
- curUse.targets[j].nounIndex = in.readUint16BE();
- curUse.targets[j].verbIndex = in.readUint16BE();
+ curUse._targets[j]._nounIndex = in.readUint16BE();
+ curUse._targets[j]._verbIndex = in.readUint16BE();
}
}
/**
* Load _uses from Hugo.dat
*/
void ObjectHandler::loadObjectUses(Common::ReadStream &in) {
- uses_t tmpUse;
- tmpUse.targets = 0;
+ Uses tmpUse;
+ tmpUse._targets = 0;
//Read _uses
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
uint16 numElem = in.readUint16BE();
if (varnt == _vm->_gameVariant) {
_usesSize = numElem;
- _uses = (uses_t *)malloc(sizeof(uses_t) * numElem);
+ _uses = (Uses *)malloc(sizeof(Uses) * numElem);
}
for (int i = 0; i < numElem; i++) {
@@ -429,83 +429,83 @@ void ObjectHandler::loadObjectUses(Common::ReadStream &in) {
readUse(in, _uses[i]);
else {
readUse(in, tmpUse);
- free(tmpUse.targets);
- tmpUse.targets = 0;
+ free(tmpUse._targets);
+ tmpUse._targets = 0;
}
}
}
}
-void ObjectHandler::readObject(Common::ReadStream &in, object_t &curObject) {
- curObject.nounIndex = in.readUint16BE();
- curObject.dataIndex = in.readUint16BE();
+void ObjectHandler::readObject(Common::ReadStream &in, Object &curObject) {
+ curObject._nounIndex = in.readUint16BE();
+ curObject._dataIndex = in.readUint16BE();
uint16 numSubElem = in.readUint16BE();
if (numSubElem == 0)
- curObject.stateDataIndex = 0;
+ curObject._stateDataIndex = 0;
else
- curObject.stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem);
+ curObject._stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem);
for (int j = 0; j < numSubElem; j++)
- curObject.stateDataIndex[j] = in.readUint16BE();
-
- curObject.pathType = (path_t) in.readSint16BE();
- curObject.vxPath = in.readSint16BE();
- curObject.vyPath = in.readSint16BE();
- curObject.actIndex = in.readUint16BE();
- curObject.seqNumb = in.readByte();
- curObject.currImagePtr = 0;
-
- if (curObject.seqNumb == 0) {
- curObject.seqList[0].imageNbr = 0;
- curObject.seqList[0].seqPtr = 0;
+ curObject._stateDataIndex[j] = in.readUint16BE();
+
+ curObject._pathType = (Path) in.readSint16BE();
+ curObject._vxPath = in.readSint16BE();
+ curObject._vyPath = in.readSint16BE();
+ curObject._actIndex = in.readUint16BE();
+ curObject._seqNumb = in.readByte();
+ curObject._currImagePtr = 0;
+
+ if (curObject._seqNumb == 0) {
+ curObject._seqList[0]._imageNbr = 0;
+ curObject._seqList[0]._seqPtr = 0;
}
- for (int j = 0; j < curObject.seqNumb; j++) {
- curObject.seqList[j].imageNbr = in.readUint16BE();
- curObject.seqList[j].seqPtr = 0;
+ for (int j = 0; j < curObject._seqNumb; j++) {
+ curObject._seqList[j]._imageNbr = in.readUint16BE();
+ curObject._seqList[j]._seqPtr = 0;
}
- curObject.cycling = (cycle_t)in.readByte();
- curObject.cycleNumb = in.readByte();
- curObject.frameInterval = in.readByte();
- curObject.frameTimer = in.readByte();
- curObject.radius = in.readByte();
- curObject.screenIndex = in.readByte();
- curObject.x = in.readSint16BE();
- curObject.y = in.readSint16BE();
- curObject.oldx = in.readSint16BE();
- curObject.oldy = in.readSint16BE();
- curObject.vx = in.readByte();
- curObject.vy = in.readByte();
- curObject.objValue = in.readByte();
- curObject.genericCmd = in.readSint16BE();
- curObject.cmdIndex = in.readUint16BE();
- curObject.carriedFl = (in.readByte() != 0);
- curObject.state = in.readByte();
- curObject.verbOnlyFl = (in.readByte() != 0);
- curObject.priority = in.readByte();
- curObject.viewx = in.readSint16BE();
- curObject.viewy = in.readSint16BE();
- curObject.direction = in.readSint16BE();
- curObject.curSeqNum = in.readByte();
- curObject.curImageNum = in.readByte();
- curObject.oldvx = in.readByte();
- curObject.oldvy = in.readByte();
+ curObject._cycling = (Cycle)in.readByte();
+ curObject._cycleNumb = in.readByte();
+ curObject._frameInterval = in.readByte();
+ curObject._frameTimer = in.readByte();
+ curObject._radius = in.readByte();
+ curObject._screenIndex = in.readByte();
+ curObject._x = in.readSint16BE();
+ curObject._y = in.readSint16BE();
+ curObject._oldx = in.readSint16BE();
+ curObject._oldy = in.readSint16BE();
+ curObject._vx = in.readByte();
+ curObject._vy = in.readByte();
+ curObject._objValue = in.readByte();
+ curObject._genericCmd = in.readSint16BE();
+ curObject._cmdIndex = in.readUint16BE();
+ curObject._carriedFl = (in.readByte() != 0);
+ curObject._state = in.readByte();
+ curObject._verbOnlyFl = (in.readByte() != 0);
+ curObject._priority = in.readByte();
+ curObject._viewx = in.readSint16BE();
+ curObject._viewy = in.readSint16BE();
+ curObject._direction = in.readSint16BE();
+ curObject._curSeqNum = in.readByte();
+ curObject._curImageNum = in.readByte();
+ curObject._oldvx = in.readByte();
+ curObject._oldvy = in.readByte();
}
/**
* Load ObjectArr from Hugo.dat
*/
void ObjectHandler::loadObjectArr(Common::ReadStream &in) {
debugC(6, kDebugObject, "loadObject(&in)");
- object_t tmpObject;
- tmpObject.stateDataIndex = 0;
+ Object tmpObject;
+ tmpObject._stateDataIndex = 0;
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
uint16 numElem = in.readUint16BE();
if (varnt == _vm->_gameVariant) {
_objCount = numElem;
- _objects = (object_t *)malloc(sizeof(object_t) * numElem);
+ _objects = (Object *)malloc(sizeof(Object) * numElem);
}
for (int i = 0; i < numElem; i++) {
@@ -514,8 +514,8 @@ void ObjectHandler::loadObjectArr(Common::ReadStream &in) {
else {
// Skip over uneeded objects.
readObject(in, tmpObject);
- free(tmpObject.stateDataIndex);
- tmpObject.stateDataIndex = 0;
+ free(tmpObject._stateDataIndex);
+ tmpObject._stateDataIndex = 0;
}
}
}
@@ -528,7 +528,7 @@ void ObjectHandler::loadObjectArr(Common::ReadStream &in) {
void ObjectHandler::setCarriedScreen(int screenNum) {
for (int i = kHeroIndex + 1; i < _numObj; i++) {// Any others
if (isCarried(i)) // being carried
- _objects[i].screenIndex = screenNum;
+ _objects[i]._screenIndex = screenNum;
}
}
@@ -559,33 +559,33 @@ void ObjectHandler::restoreAllSeq() {
*/
void ObjectHandler::saveObjects(Common::WriteStream *out) {
for (int i = 0; i < _numObj; i++) {
- // Save where curr_seq_p is pointing to
+ // Save where curr_seqPtr is pointing to
saveSeq(&_objects[i]);
- out->writeByte(_objects[i].pathType);
- out->writeSint16BE(_objects[i].vxPath);
- out->writeSint16BE(_objects[i].vyPath);
- out->writeByte(_objects[i].cycling);
- out->writeByte(_objects[i].cycleNumb);
- out->writeByte(_objects[i].frameTimer);
- out->writeByte(_objects[i].screenIndex);
- out->writeSint16BE(_objects[i].x);
- out->writeSint16BE(_objects[i].y);
- out->writeSint16BE(_objects[i].oldx);
- out->writeSint16BE(_objects[i].oldy);
- out->writeSByte(_objects[i].vx);
- out->writeSByte(_objects[i].vy);
- out->writeByte(_objects[i].objValue);
- out->writeByte((_objects[i].carriedFl) ? 1 : 0);
- out->writeByte(_objects[i].state);
- out->writeByte(_objects[i].priority);
- out->writeSint16BE(_objects[i].viewx);
- out->writeSint16BE(_objects[i].viewy);
- out->writeSint16BE(_objects[i].direction);
- out->writeByte(_objects[i].curSeqNum);
- out->writeByte(_objects[i].curImageNum);
- out->writeSByte(_objects[i].oldvx);
- out->writeSByte(_objects[i].oldvy);
+ out->writeByte(_objects[i]._pathType);
+ out->writeSint16BE(_objects[i]._vxPath);
+ out->writeSint16BE(_objects[i]._vyPath);
+ out->writeByte(_objects[i]._cycling);
+ out->writeByte(_objects[i]._cycleNumb);
+ out->writeByte(_objects[i]._frameTimer);
+ out->writeByte(_objects[i]._screenIndex);
+ out->writeSint16BE(_objects[i]._x);
+ out->writeSint16BE(_objects[i]._y);
+ out->writeSint16BE(_objects[i]._oldx);
+ out->writeSint16BE(_objects[i]._oldy);
+ out->writeSByte(_objects[i]._vx);
+ out->writeSByte(_objects[i]._vy);
+ out->writeByte(_objects[i]._objValue);
+ out->writeByte((_objects[i]._carriedFl) ? 1 : 0);
+ out->writeByte(_objects[i]._state);
+ out->writeByte(_objects[i]._priority);
+ out->writeSint16BE(_objects[i]._viewx);
+ out->writeSint16BE(_objects[i]._viewy);
+ out->writeSint16BE(_objects[i]._direction);
+ out->writeByte(_objects[i]._curSeqNum);
+ out->writeByte(_objects[i]._curImageNum);
+ out->writeSByte(_objects[i]._oldvx);
+ out->writeSByte(_objects[i]._oldvy);
}
}
@@ -594,30 +594,30 @@ void ObjectHandler::saveObjects(Common::WriteStream *out) {
*/
void ObjectHandler::restoreObjects(Common::SeekableReadStream *in) {
for (int i = 0; i < _numObj; i++) {
- _objects[i].pathType = (path_t) in->readByte();
- _objects[i].vxPath = in->readSint16BE();
- _objects[i].vyPath = in->readSint16BE();
- _objects[i].cycling = (cycle_t) in->readByte();
- _objects[i].cycleNumb = in->readByte();
- _objects[i].frameTimer = in->readByte();
- _objects[i].screenIndex = in->readByte();
- _objects[i].x = in->readSint16BE();
- _objects[i].y = in->readSint16BE();
- _objects[i].oldx = in->readSint16BE();
- _objects[i].oldy = in->readSint16BE();
- _objects[i].vx = in->readSByte();
- _objects[i].vy = in->readSByte();
- _objects[i].objValue = in->readByte();
- _objects[i].carriedFl = (in->readByte() == 1);
- _objects[i].state = in->readByte();
- _objects[i].priority = in->readByte();
- _objects[i].viewx = in->readSint16BE();
- _objects[i].viewy = in->readSint16BE();
- _objects[i].direction = in->readSint16BE();
- _objects[i].curSeqNum = in->readByte();
- _objects[i].curImageNum = in->readByte();
- _objects[i].oldvx = in->readSByte();
- _objects[i].oldvy = in->readSByte();
+ _objects[i]._pathType = (Path) in->readByte();
+ _objects[i]._vxPath = in->readSint16BE();
+ _objects[i]._vyPath = in->readSint16BE();
+ _objects[i]._cycling = (Cycle) in->readByte();
+ _objects[i]._cycleNumb = in->readByte();
+ _objects[i]._frameTimer = in->readByte();
+ _objects[i]._screenIndex = in->readByte();
+ _objects[i]._x = in->readSint16BE();
+ _objects[i]._y = in->readSint16BE();
+ _objects[i]._oldx = in->readSint16BE();
+ _objects[i]._oldy = in->readSint16BE();
+ _objects[i]._vx = in->readSByte();
+ _objects[i]._vy = in->readSByte();
+ _objects[i]._objValue = in->readByte();
+ _objects[i]._carriedFl = (in->readByte() == 1);
+ _objects[i]._state = in->readByte();
+ _objects[i]._priority = in->readByte();
+ _objects[i]._viewx = in->readSint16BE();
+ _objects[i]._viewy = in->readSint16BE();
+ _objects[i]._direction = in->readSint16BE();
+ _objects[i]._curSeqNum = in->readByte();
+ _objects[i]._curImageNum = in->readByte();
+ _objects[i]._oldvx = in->readSByte();
+ _objects[i]._oldvy = in->readSByte();
}
}
@@ -627,7 +627,7 @@ void ObjectHandler::restoreObjects(Common::SeekableReadStream *in) {
int ObjectHandler::calcMaxScore() {
int score = 0;
for (int i = 0; i < _numObj; i++)
- score += _objects[i].objValue;
+ score += _objects[i]._objValue;
return score;
}
@@ -782,32 +782,32 @@ void ObjectHandler::clearScreenBoundary(const int x1, const int x2, const int y)
/**
* An object has collided with a boundary. See if any actions are required
*/
-void ObjectHandler::boundaryCollision(object_t *obj) {
+void ObjectHandler::boundaryCollision(Object *obj) {
debugC(1, kDebugEngine, "boundaryCollision");
if (obj == _vm->_hero) {
// Hotspots only relevant to HERO
int x;
- if (obj->vx > 0)
- x = obj->x + obj->currImagePtr->x2;
+ if (obj->_vx > 0)
+ x = obj->_x + obj->_currImagePtr->_x2;
else
- x = obj->x + obj->currImagePtr->x1;
- int y = obj->y + obj->currImagePtr->y2;
+ x = obj->_x + obj->_currImagePtr->_x1;
+ int y = obj->_y + obj->_currImagePtr->_y2;
- int16 index = _vm->_mouse->findExit(x, y, obj->screenIndex);
+ int16 index = _vm->_mouse->findExit(x, y, obj->_screenIndex);
if (index >= 0)
_vm->_scheduler->insertActionList(_vm->_mouse->getHotspotActIndex(index));
} else {
// Check whether an object collided with HERO
- int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - obj->currImagePtr->x1;
- int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - obj->currImagePtr->y2;
+ int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - obj->_currImagePtr->_x1;
+ int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - obj->_currImagePtr->_y2;
// If object's radius is infinity, use a closer value
- int8 radius = obj->radius;
+ int8 radius = obj->_radius;
if (radius < 0)
radius = kStepDx * 2;
if ((abs(dx) <= radius) && (abs(dy) <= radius))
- _vm->_scheduler->insertActionList(obj->actIndex);
+ _vm->_scheduler->insertActionList(obj->_actIndex);
}
}
diff --git a/engines/hugo/object.h b/engines/hugo/object.h
index 84c20db041..fd0d731a98 100644
--- a/engines/hugo/object.h
+++ b/engines/hugo/object.h
@@ -34,15 +34,15 @@
namespace Hugo {
-struct target_t { // Secondary target for action
- uint16 nounIndex; // Secondary object
- uint16 verbIndex; // Action on secondary object
+struct Target { // Secondary target for action
+ uint16 _nounIndex; // Secondary object
+ uint16 _verbIndex; // Action on secondary object
};
-struct uses_t { // Define uses of certain objects
- int16 objId; // Primary object
- uint16 dataIndex; // String if no secondary object matches
- target_t *targets; // List of secondary targets
+struct Uses { // Define uses of certain objects
+ int16 _objId; // Primary object
+ uint16 _dataIndex; // String if no secondary object matches
+ Target *_targets; // List of secondary targets
};
class ObjectHandler {
@@ -50,12 +50,12 @@ public:
ObjectHandler(HugoEngine *vm);
virtual ~ObjectHandler();
- overlay_t _objBound;
- overlay_t _boundary; // Boundary overlay file
- overlay_t _overlay; // First overlay file
- overlay_t _ovlBase; // First overlay base file
+ Overlay _objBound;
+ Overlay _boundary; // Boundary overlay file
+ Overlay _overlay; // First overlay file
+ Overlay _ovlBase; // First overlay base file
- object_t *_objects;
+ Object *_objects;
uint16 _numObj;
byte getBoundaryOverlay(uint16 index) const;
@@ -65,7 +65,7 @@ public:
int deltaX(const int x1, const int x2, const int vx, int y) const;
int deltaY(const int x1, const int x2, const int vy, const int y) const;
- void boundaryCollision(object_t *obj);
+ void boundaryCollision(Object *obj);
void clearBoundary(const int x1, const int x2, const int y);
void clearScreenBoundary(const int x1, const int x2, const int y);
void storeBoundary(const int x1, const int x2, const int y);
@@ -76,7 +76,7 @@ public:
virtual void swapImages(int objIndex1, int objIndex2) = 0;
bool isCarrying(uint16 wordIndex);
- bool findObjectSpace(object_t *obj, int16 *destx, int16 *desty);
+ bool findObjectSpace(Object *obj, int16 *destx, int16 *desty);
int calcMaxScore();
int16 findObject(uint16 x, uint16 y);
@@ -84,14 +84,14 @@ public:
void loadObjectArr(Common::ReadStream &in);
void loadObjectUses(Common::ReadStream &in);
void loadNumObj(Common::ReadStream &in);
- void lookObject(object_t *obj);
+ void lookObject(Object *obj);
void readObjectImages();
- void readObject(Common::ReadStream &in, object_t &curObject);
- void readUse(Common::ReadStream &in, uses_t &curUse);
+ void readObject(Common::ReadStream &in, Object &curObject);
+ void readUse(Common::ReadStream &in, Uses &curUse);
void restoreAllSeq();
void restoreObjects(Common::SeekableReadStream *in);
void saveObjects(Common::WriteStream *out);
- void saveSeq(object_t *obj);
+ void saveSeq(Object *obj);
void setCarriedScreen(int screenNum);
void showTakeables();
void useObject(int16 objId);
@@ -101,7 +101,7 @@ public:
bool isCarried(int objIndex) const;
void setCarry(int objIndex, bool val);
void setVelocity(int objIndex, int8 vx, int8 vy);
- void setPath(int objIndex, path_t pathType, int16 vxPath, int16 vyPath);
+ void setPath(int objIndex, Path pathType, int16 vxPath, int16 vyPath);
protected:
HugoEngine *_vm;
@@ -110,11 +110,11 @@ protected:
static const int kEdge2 = kEdge * 2; // Push object further back on edge collision
static const int kMaxObjNumb = 128; // Used in Update_images()
- uint16 _objCount;
- uses_t *_uses;
- uint16 _usesSize;
+ uint16 _objCount;
+ Uses *_uses;
+ uint16 _usesSize;
- void restoreSeq(object_t *obj);
+ void restoreSeq(Object *obj);
inline bool checkBoundary(int16 x, int16 y);
template<typename T>
diff --git a/engines/hugo/object_v1d.cpp b/engines/hugo/object_v1d.cpp
index 831dc88dea..7f88e9e5b8 100644
--- a/engines/hugo/object_v1d.cpp
+++ b/engines/hugo/object_v1d.cpp
@@ -59,43 +59,43 @@ void ObjectHandler_v1d::updateImages() {
debugC(5, kDebugObject, "updateImages");
// Initialize the index array to visible objects in current screen
- int num_objs = 0;
+ int objNumb = 0;
byte objindex[kMaxObjNumb]; // Array of indeces to objects
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i];
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling >= kCycleAlmostInvisible))
- objindex[num_objs++] = i;
+ Object *obj = &_objects[i];
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling >= kCycleAlmostInvisible))
+ objindex[objNumb++] = i;
}
// Sort the objects into increasing y+y2 (painter's algorithm)
- qsort(objindex, num_objs, sizeof(objindex[0]), y2comp);
+ qsort(objindex, objNumb, sizeof(objindex[0]), y2comp);
// Add each visible object to display list
- for (int i = 0; i < num_objs; i++) {
- object_t *obj = &_objects[objindex[i]];
+ for (int i = 0; i < objNumb; i++) {
+ Object *obj = &_objects[objindex[i]];
// Count down inter-frame timer
- if (obj->frameTimer)
- obj->frameTimer--;
+ if (obj->_frameTimer)
+ obj->_frameTimer--;
- if (obj->cycling > kCycleAlmostInvisible) { // Only if visible
- switch (obj->cycling) {
+ if (obj->_cycling > kCycleAlmostInvisible) { // Only if visible
+ switch (obj->_cycling) {
case kCycleNotCycling:
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, false);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, false);
break;
case kCycleForward:
- if (obj->frameTimer) // Not time to see next frame yet
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, false);
+ if (obj->_frameTimer) // Not time to see next frame yet
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, false);
else
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, false);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, false);
break;
case kCycleBackward: {
- seq_t *seqPtr = obj->currImagePtr;
- if (!obj->frameTimer) { // Show next frame
- while (seqPtr->nextSeqPtr != obj->currImagePtr)
- seqPtr = seqPtr->nextSeqPtr;
+ Seq *seqPtr = obj->_currImagePtr;
+ if (!obj->_frameTimer) { // Show next frame
+ while (seqPtr->_nextSeqPtr != obj->_currImagePtr)
+ seqPtr = seqPtr->_nextSeqPtr;
}
- _vm->_screen->displayFrame(obj->x, obj->y, seqPtr, false);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, seqPtr, false);
break;
}
default:
@@ -107,30 +107,30 @@ void ObjectHandler_v1d::updateImages() {
_vm->_scheduler->waitForRefresh();
// Cycle any animating objects
- for (int i = 0; i < num_objs; i++) {
- object_t *obj = &_objects[objindex[i]];
- if (obj->cycling != kCycleInvisible) {
+ for (int i = 0; i < objNumb; i++) {
+ Object *obj = &_objects[objindex[i]];
+ if (obj->_cycling != kCycleInvisible) {
// Only if it's visible
- if (obj->cycling == kCycleAlmostInvisible)
- obj->cycling = kCycleInvisible;
+ if (obj->_cycling == kCycleAlmostInvisible)
+ obj->_cycling = kCycleInvisible;
// Now Rotate to next picture in sequence
- switch (obj->cycling) {
+ switch (obj->_cycling) {
case kCycleNotCycling:
break;
case kCycleForward:
- if (!obj->frameTimer) {
+ if (!obj->_frameTimer) {
// Time to step to next frame
- obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
+ obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr;
// Find out if this is last frame of sequence
// If so, reset frame_timer and decrement n_cycle
- if (obj->frameInterval || obj->cycleNumb) {
- obj->frameTimer = obj->frameInterval;
- for (int j = 0; j < obj->seqNumb; j++) {
- if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) {
- if (obj->cycleNumb) { // Decr cycleNumb if Non-continous
- if (!--obj->cycleNumb)
- obj->cycling = kCycleNotCycling;
+ if (obj->_frameInterval || obj->_cycleNumb) {
+ obj->_frameTimer = obj->_frameInterval;
+ for (int j = 0; j < obj->_seqNumb; j++) {
+ if (obj->_currImagePtr->_nextSeqPtr == obj->_seqList[j]._seqPtr) {
+ if (obj->_cycleNumb) { // Decr cycleNumb if Non-continous
+ if (!--obj->_cycleNumb)
+ obj->_cycling = kCycleNotCycling;
}
}
}
@@ -138,20 +138,20 @@ void ObjectHandler_v1d::updateImages() {
}
break;
case kCycleBackward: {
- if (!obj->frameTimer) {
+ if (!obj->_frameTimer) {
// Time to step to prev frame
- seq_t *seqPtr = obj->currImagePtr;
- while (obj->currImagePtr->nextSeqPtr != seqPtr)
- obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
+ Seq *seqPtr = obj->_currImagePtr;
+ while (obj->_currImagePtr->_nextSeqPtr != seqPtr)
+ obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr;
// Find out if this is first frame of sequence
// If so, reset frame_timer and decrement n_cycle
- if (obj->frameInterval || obj->cycleNumb) {
- obj->frameTimer = obj->frameInterval;
- for (int j = 0; j < obj->seqNumb; j++) {
- if (obj->currImagePtr == obj->seqList[j].seqPtr) {
- if (obj->cycleNumb){ // Decr cycleNumb if Non-continous
- if (!--obj->cycleNumb)
- obj->cycling = kCycleNotCycling;
+ if (obj->_frameInterval || obj->_cycleNumb) {
+ obj->_frameTimer = obj->_frameInterval;
+ for (int j = 0; j < obj->_seqNumb; j++) {
+ if (obj->_currImagePtr == obj->_seqList[j]._seqPtr) {
+ if (obj->_cycleNumb){ // Decr cycleNumb if Non-continous
+ if (!--obj->_cycleNumb)
+ obj->_cycling = kCycleNotCycling;
}
}
}
@@ -162,8 +162,8 @@ void ObjectHandler_v1d::updateImages() {
default:
break;
}
- obj->oldx = obj->x;
- obj->oldy = obj->y;
+ obj->_oldx = obj->_x;
+ obj->_oldy = obj->_y;
}
}
}
@@ -183,162 +183,162 @@ void ObjectHandler_v1d::moveObjects() {
// and store all (visible) object baselines into the boundary file.
// Don't store foreground or background objects
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
- if (obj->screenIndex == *_vm->_screen_p) {
- switch (obj->pathType) {
+ Object *obj = &_objects[i]; // Get pointer to object
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
+ if (obj->_screenIndex == *_vm->_screenPtr) {
+ switch (obj->_pathType) {
case kPathChase: {
// Allowable motion wrt boundary
- int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1;
- int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1;
+ int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - currImage->_x1;
+ int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - currImage->_y2 - 1;
if (abs(dx) <= 1)
- obj->vx = 0;
+ obj->_vx = 0;
else
- obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath);
+ obj->_vx = (dx > 0) ? MIN(dx, obj->_vxPath) : MAX(dx, -obj->_vxPath);
if (abs(dy) <= 1)
- obj->vy = 0;
+ obj->_vy = 0;
else
- obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath);
+ obj->_vy = (dy > 0) ? MIN(dy, obj->_vyPath) : MAX(dy, -obj->_vyPath);
// Set first image in sequence (if multi-seq object)
- if (obj->seqNumb == 4) {
- if (!obj->vx) { // Got 4 directions
- if (obj->vx != obj->oldvx) {// vx just stopped
+ if (obj->_seqNumb == 4) {
+ if (!obj->_vx) { // Got 4 directions
+ if (obj->_vx != obj->_oldvx) {// vx just stopped
if (dy > 0)
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
}
- } else if (obj->vx != obj->oldvx) {
+ } else if (obj->_vx != obj->_oldvx) {
if (dx > 0)
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
}
- if (obj->vx || obj->vy) {
- if (obj->seqNumb > 1)
- obj->cycling = kCycleForward;
+ if (obj->_vx || obj->_vy) {
+ if (obj->_seqNumb > 1)
+ obj->_cycling = kCycleForward;
} else {
- obj->cycling = kCycleNotCycling;
+ obj->_cycling = kCycleNotCycling;
boundaryCollision(obj); // Must have got hero!
}
- obj->oldvx = obj->vx;
- obj->oldvy = obj->vy;
- currImage = obj->currImagePtr; // Get (new) ptr to current image
+ obj->_oldvx = obj->_vx;
+ obj->_oldvy = obj->_vy;
+ currImage = obj->_currImagePtr; // Get (new) ptr to current image
break;
}
case kPathWander:
if (!_vm->_rnd->getRandomNumber(3 * _vm->_normalTPS)) { // Kick on random interval
- obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath;
- obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath;
+ obj->_vx = _vm->_rnd->getRandomNumber(obj->_vxPath << 1) - obj->_vxPath;
+ obj->_vy = _vm->_rnd->getRandomNumber(obj->_vyPath << 1) - obj->_vyPath;
// Set first image in sequence (if multi-seq object)
- if (obj->seqNumb > 1) {
- if (!obj->vx && (obj->seqNumb > 2)) {
- if (obj->vx != obj->oldvx) { // vx just stopped
- if (obj->vy > 0)
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ if (obj->_seqNumb > 1) {
+ if (!obj->_vx && (obj->_seqNumb > 2)) {
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
+ if (obj->_vy > 0)
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
}
- } else if (obj->vx != obj->oldvx) {
- if (obj->vx > 0)
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ } else if (obj->_vx != obj->_oldvx) {
+ if (obj->_vx > 0)
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
- if (obj->vx || obj->vy)
- obj->cycling = kCycleForward;
+ if (obj->_vx || obj->_vy)
+ obj->_cycling = kCycleForward;
else
- obj->cycling = kCycleNotCycling;
+ obj->_cycling = kCycleNotCycling;
}
- obj->oldvx = obj->vx;
- obj->oldvy = obj->vy;
- currImage = obj->currImagePtr; // Get (new) ptr to current image
+ obj->_oldvx = obj->_vx;
+ obj->_oldvy = obj->_vy;
+ currImage = obj->_currImagePtr; // Get (new) ptr to current image
}
break;
default:
; // Really, nothing
}
// Store boundaries
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
- storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
+ storeBoundary(obj->_x + currImage->_x1, obj->_x + currImage->_x2, obj->_y + currImage->_y2);
}
}
// Move objects, allowing for boundaries
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) {
+ Object *obj = &_objects[i]; // Get pointer to object
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_vx || obj->_vy)) {
// Only process if it's moving
// Do object movement. Delta_x,y return allowed movement in x,y
// to move as close to a boundary as possible without crossing it.
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
// object coordinates
- int x1 = obj->x + currImage->x1; // Left edge of object
- int x2 = obj->x + currImage->x2; // Right edge
- int y1 = obj->y + currImage->y1; // Top edge
- int y2 = obj->y + currImage->y2; // Bottom edge
+ int x1 = obj->_x + currImage->_x1; // Left edge of object
+ int x2 = obj->_x + currImage->_x2; // Right edge
+ int y1 = obj->_y + currImage->_y1; // Top edge
+ int y2 = obj->_y + currImage->_y2; // Bottom edge
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
clearBoundary(x1, x2, y2); // Clear our own boundary
// Allowable motion wrt boundary
- int dx = deltaX(x1, x2, obj->vx, y2);
- if (dx != obj->vx) {
+ int dx = deltaX(x1, x2, obj->_vx, y2);
+ if (dx != obj->_vx) {
// An object boundary collision!
boundaryCollision(obj);
- obj->vx = 0;
+ obj->_vx = 0;
}
- int dy = deltaY(x1, x2, obj->vy, y2);
- if (dy != obj->vy) {
+ int dy = deltaY(x1, x2, obj->_vy, y2);
+ if (dy != obj->_vy) {
// An object boundary collision!
boundaryCollision(obj);
- obj->vy = 0;
+ obj->_vy = 0;
}
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
storeBoundary(x1, x2, y2); // Re-store our own boundary
- obj->x += dx; // Update object position
- obj->y += dy;
+ obj->_x += dx; // Update object position
+ obj->_y += dy;
// Don't let object go outside screen
if (x1 < kEdge)
- obj->x = kEdge2;
+ obj->_x = kEdge2;
if (x2 > (kXPix - kEdge))
- obj->x = kXPix - kEdge2 - (x2 - x1);
+ obj->_x = kXPix - kEdge2 - (x2 - x1);
if (y1 < kEdge)
- obj->y = kEdge2;
+ obj->_y = kEdge2;
if (y2 > (kYPix - kEdge))
- obj->y = kYPix - kEdge2 - (y2 - y1);
+ obj->_y = kYPix - kEdge2 - (y2 - y1);
- if ((obj->vx == 0) && (obj->vy == 0))
- obj->cycling = kCycleNotCycling;
+ if ((obj->_vx == 0) && (obj->_vy == 0))
+ obj->_cycling = kCycleNotCycling;
}
}
// Clear all object baselines from the boundary file.
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
- clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
+ Object *obj = &_objects[i]; // Get pointer to object
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
+ clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2);
}
// If maze mode is enabled, do special maze processing
- if (_vm->_maze.enabledFl) {
- seq_t *currImage = _vm->_hero->currImagePtr;// Get ptr to current image
+ if (_vm->_maze._enabledFl) {
+ Seq *currImage = _vm->_hero->_currImagePtr;// Get ptr to current image
// hero coordinates
- int x1 = _vm->_hero->x + currImage->x1; // Left edge of object
- int x2 = _vm->_hero->x + currImage->x2; // Right edge
- int y1 = _vm->_hero->y + currImage->y1; // Top edge
- int y2 = _vm->_hero->y + currImage->y2; // Bottom edge
+ int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object
+ int x2 = _vm->_hero->_x + currImage->_x2; // Right edge
+ int y1 = _vm->_hero->_y + currImage->_y1; // Top edge
+ int y2 = _vm->_hero->_y + currImage->_y2; // Bottom edge
_vm->_scheduler->processMaze(x1, x2, y1, y2);
}
@@ -352,24 +352,24 @@ void ObjectHandler_v1d::moveObjects() {
void ObjectHandler_v1d::swapImages(int objIndex1, int objIndex2) {
debugC(1, kDebugObject, "swapImages(%d, %d)", objIndex1, objIndex2);
- seqList_t tmpSeqList[kMaxSeqNumb];
- int seqListSize = sizeof(seqList_t) * kMaxSeqNumb;
+ SeqList tmpSeqList[kMaxSeqNumb];
+ int seqListSize = sizeof(SeqList) * kMaxSeqNumb;
- memmove(tmpSeqList, _objects[objIndex1].seqList, seqListSize);
- memmove(_objects[objIndex1].seqList, _objects[objIndex2].seqList, seqListSize);
- memmove(_objects[objIndex2].seqList, tmpSeqList, seqListSize);
- _objects[objIndex1].currImagePtr = _objects[objIndex1].seqList[0].seqPtr;
- _objects[objIndex2].currImagePtr = _objects[objIndex2].seqList[0].seqPtr;
+ memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize);
+ memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize);
+ memmove(_objects[objIndex2]._seqList, tmpSeqList, seqListSize);
+ _objects[objIndex1]._currImagePtr = _objects[objIndex1]._seqList[0]._seqPtr;
+ _objects[objIndex2]._currImagePtr = _objects[objIndex2]._seqList[0]._seqPtr;
_vm->_heroImage = (_vm->_heroImage == kHeroIndex) ? objIndex2 : kHeroIndex;
}
void ObjectHandler_v1d::homeIn(int objIndex1, const int objIndex2, const int8 objDx, const int8 objDy) {
// object obj1 will home in on object obj2
- object_t *obj1 = &_objects[objIndex1];
- object_t *obj2 = &_objects[objIndex2];
- obj1->pathType = kPathAuto;
- int dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1;
- int dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1;
+ Object *obj1 = &_objects[objIndex1];
+ Object *obj2 = &_objects[objIndex2];
+ obj1->_pathType = kPathAuto;
+ int dx = obj1->_x + obj1->_currImagePtr->_x1 - obj2->_x - obj2->_currImagePtr->_x1;
+ int dy = obj1->_y + obj1->_currImagePtr->_y1 - obj2->_y - obj2->_currImagePtr->_y1;
if (dx == 0) // Don't EVER divide by zero!
dx = 1;
@@ -377,11 +377,11 @@ void ObjectHandler_v1d::homeIn(int objIndex1, const int objIndex2, const int8 ob
dy = 1;
if (abs(dx) > abs(dy)) {
- obj1->vx = objDx * -sign<int8>(dx);
- obj1->vy = abs((objDy * dy) / dx) * -sign<int8>(dy);
+ obj1->_vx = objDx * -sign<int8>(dx);
+ obj1->_vy = abs((objDy * dy) / dx) * -sign<int8>(dy);
} else {
- obj1->vy = objDy * sign<int8>(dy);
- obj1->vx = abs((objDx * dx) / dy) * sign<int8>(dx);
+ obj1->_vy = objDy * sign<int8>(dy);
+ obj1->_vx = abs((objDx * dx) / dy) * sign<int8>(dx);
}
}
} // End of namespace Hugo
diff --git a/engines/hugo/object_v1w.cpp b/engines/hugo/object_v1w.cpp
index 4388ef5520..61b0f2e48a 100644
--- a/engines/hugo/object_v1w.cpp
+++ b/engines/hugo/object_v1w.cpp
@@ -59,43 +59,43 @@ void ObjectHandler_v1w::updateImages() {
debugC(5, kDebugObject, "updateImages");
// Initialize the index array to visible objects in current screen
- int num_objs = 0;
+ int objNumb = 0;
byte objindex[kMaxObjNumb]; // Array of indeces to objects
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i];
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling >= kCycleAlmostInvisible))
- objindex[num_objs++] = i;
+ Object *obj = &_objects[i];
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling >= kCycleAlmostInvisible))
+ objindex[objNumb++] = i;
}
// Sort the objects into increasing y+y2 (painter's algorithm)
- qsort(objindex, num_objs, sizeof(objindex[0]), y2comp);
+ qsort(objindex, objNumb, sizeof(objindex[0]), y2comp);
// Add each visible object to display list
- for (int i = 0; i < num_objs; i++) {
- object_t *obj = &_objects[objindex[i]];
+ for (int i = 0; i < objNumb; i++) {
+ Object *obj = &_objects[objindex[i]];
// Count down inter-frame timer
- if (obj->frameTimer)
- obj->frameTimer--;
+ if (obj->_frameTimer)
+ obj->_frameTimer--;
- if (obj->cycling > kCycleAlmostInvisible) { // Only if visible
- switch (obj->cycling) {
+ if (obj->_cycling > kCycleAlmostInvisible) { // Only if visible
+ switch (obj->_cycling) {
case kCycleNotCycling:
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == kPriorityOverOverlay);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, obj->_priority == kPriorityOverOverlay);
break;
case kCycleForward:
- if (obj->frameTimer) // Not time to see next frame yet
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == kPriorityOverOverlay);
+ if (obj->_frameTimer) // Not time to see next frame yet
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, obj->_priority == kPriorityOverOverlay);
else
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, obj->priority == kPriorityOverOverlay);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, obj->_priority == kPriorityOverOverlay);
break;
case kCycleBackward: {
- seq_t *seqPtr = obj->currImagePtr;
- if (!obj->frameTimer) { // Show next frame
- while (seqPtr->nextSeqPtr != obj->currImagePtr)
- seqPtr = seqPtr->nextSeqPtr;
+ Seq *seqPtr = obj->_currImagePtr;
+ if (!obj->_frameTimer) { // Show next frame
+ while (seqPtr->_nextSeqPtr != obj->_currImagePtr)
+ seqPtr = seqPtr->_nextSeqPtr;
}
- _vm->_screen->displayFrame(obj->x, obj->y, seqPtr, obj->priority == kPriorityOverOverlay);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, seqPtr, obj->_priority == kPriorityOverOverlay);
break;
}
default:
@@ -105,30 +105,30 @@ void ObjectHandler_v1w::updateImages() {
}
// Cycle any animating objects
- for (int i = 0; i < num_objs; i++) {
- object_t *obj = &_objects[objindex[i]];
- if (obj->cycling != kCycleInvisible) {
+ for (int i = 0; i < objNumb; i++) {
+ Object *obj = &_objects[objindex[i]];
+ if (obj->_cycling != kCycleInvisible) {
// Only if it's visible
- if (obj->cycling == kCycleAlmostInvisible)
- obj->cycling = kCycleInvisible;
+ if (obj->_cycling == kCycleAlmostInvisible)
+ obj->_cycling = kCycleInvisible;
// Now Rotate to next picture in sequence
- switch (obj->cycling) {
+ switch (obj->_cycling) {
case kCycleNotCycling:
break;
case kCycleForward:
- if (!obj->frameTimer) {
+ if (!obj->_frameTimer) {
// Time to step to next frame
- obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
+ obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr;
// Find out if this is last frame of sequence
// If so, reset frame_timer and decrement n_cycle
- if (obj->frameInterval || obj->cycleNumb) {
- obj->frameTimer = obj->frameInterval;
- for (int j = 0; j < obj->seqNumb; j++) {
- if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) {
- if (obj->cycleNumb) { // Decr cycleNumb if Non-continous
- if (!--obj->cycleNumb)
- obj->cycling = kCycleNotCycling;
+ if (obj->_frameInterval || obj->_cycleNumb) {
+ obj->_frameTimer = obj->_frameInterval;
+ for (int j = 0; j < obj->_seqNumb; j++) {
+ if (obj->_currImagePtr->_nextSeqPtr == obj->_seqList[j]._seqPtr) {
+ if (obj->_cycleNumb) { // Decr cycleNumb if Non-continous
+ if (!--obj->_cycleNumb)
+ obj->_cycling = kCycleNotCycling;
}
}
}
@@ -136,20 +136,20 @@ void ObjectHandler_v1w::updateImages() {
}
break;
case kCycleBackward: {
- if (!obj->frameTimer) {
+ if (!obj->_frameTimer) {
// Time to step to prev frame
- seq_t *seqPtr = obj->currImagePtr;
- while (obj->currImagePtr->nextSeqPtr != seqPtr)
- obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
+ Seq *seqPtr = obj->_currImagePtr;
+ while (obj->_currImagePtr->_nextSeqPtr != seqPtr)
+ obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr;
// Find out if this is first frame of sequence
// If so, reset frame_timer and decrement n_cycle
- if (obj->frameInterval || obj->cycleNumb) {
- obj->frameTimer = obj->frameInterval;
- for (int j = 0; j < obj->seqNumb; j++) {
- if (obj->currImagePtr == obj->seqList[j].seqPtr) {
- if (obj->cycleNumb){ // Decr cycleNumb if Non-continous
- if (!--obj->cycleNumb)
- obj->cycling = kCycleNotCycling;
+ if (obj->_frameInterval || obj->_cycleNumb) {
+ obj->_frameTimer = obj->_frameInterval;
+ for (int j = 0; j < obj->_seqNumb; j++) {
+ if (obj->_currImagePtr == obj->_seqList[j]._seqPtr) {
+ if (obj->_cycleNumb){ // Decr cycleNumb if Non-continous
+ if (!--obj->_cycleNumb)
+ obj->_cycling = kCycleNotCycling;
}
}
}
@@ -160,8 +160,8 @@ void ObjectHandler_v1w::updateImages() {
default:
break;
}
- obj->oldx = obj->x;
- obj->oldy = obj->y;
+ obj->_oldx = obj->_x;
+ obj->_oldy = obj->_y;
}
}
}
@@ -180,175 +180,175 @@ void ObjectHandler_v1w::moveObjects() {
// and store all (visible) object baselines into the boundary file.
// Don't store foreground or background objects
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
- if (obj->screenIndex == *_vm->_screen_p) {
- switch (obj->pathType) {
+ Object *obj = &_objects[i]; // Get pointer to object
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
+ if (obj->_screenIndex == *_vm->_screenPtr) {
+ switch (obj->_pathType) {
case kPathChase:
case kPathChase2: {
- int8 radius = obj->radius; // Default to object's radius
+ int8 radius = obj->_radius; // Default to object's radius
if (radius < 0) // If radius infinity, use closer value
radius = kStepDx;
// Allowable motion wrt boundary
- int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1;
- int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1;
+ int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - currImage->_x1;
+ int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - currImage->_y2 - 1;
if (abs(dx) <= radius)
- obj->vx = 0;
+ obj->_vx = 0;
else
- obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath);
+ obj->_vx = (dx > 0) ? MIN(dx, obj->_vxPath) : MAX(dx, -obj->_vxPath);
if (abs(dy) <= radius)
- obj->vy = 0;
+ obj->_vy = 0;
else
- obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath);
+ obj->_vy = (dy > 0) ? MIN(dy, obj->_vyPath) : MAX(dy, -obj->_vyPath);
// Set first image in sequence (if multi-seq object)
- switch (obj->seqNumb) {
+ switch (obj->_seqNumb) {
case 4:
- if (!obj->vx) { // Got 4 directions
- if (obj->vx != obj->oldvx) { // vx just stopped
+ if (!obj->_vx) { // Got 4 directions
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
if (dy >= 0)
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
}
- } else if (obj->vx != obj->oldvx) {
+ } else if (obj->_vx != obj->_oldvx) {
if (dx > 0)
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
break;
case 3:
case 2:
- if (obj->vx != obj->oldvx) { // vx just stopped
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
if (dx > 0) // Left & right only
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
break;
}
- if (obj->vx || obj->vy) {
- obj->cycling = kCycleForward;
+ if (obj->_vx || obj->_vy) {
+ obj->_cycling = kCycleForward;
} else {
- obj->cycling = kCycleNotCycling;
+ obj->_cycling = kCycleNotCycling;
boundaryCollision(obj); // Must have got hero!
}
- obj->oldvx = obj->vx;
- obj->oldvy = obj->vy;
- currImage = obj->currImagePtr; // Get (new) ptr to current image
+ obj->_oldvx = obj->_vx;
+ obj->_oldvy = obj->_vy;
+ currImage = obj->_currImagePtr; // Get (new) ptr to current image
break;
}
case kPathWander2:
case kPathWander:
if (!_vm->_rnd->getRandomNumber(3 * _vm->_normalTPS)) { // Kick on random interval
- obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath;
- obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath;
+ obj->_vx = _vm->_rnd->getRandomNumber(obj->_vxPath << 1) - obj->_vxPath;
+ obj->_vy = _vm->_rnd->getRandomNumber(obj->_vyPath << 1) - obj->_vyPath;
// Set first image in sequence (if multi-seq object)
- if (obj->seqNumb > 1) {
- if (!obj->vx && (obj->seqNumb >= 4)) {
- if (obj->vx != obj->oldvx) { // vx just stopped
- if (obj->vy > 0)
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ if (obj->_seqNumb > 1) {
+ if (!obj->_vx && (obj->_seqNumb >= 4)) {
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
+ if (obj->_vy > 0)
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
}
- } else if (obj->vx != obj->oldvx) {
- if (obj->vx > 0)
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ } else if (obj->_vx != obj->_oldvx) {
+ if (obj->_vx > 0)
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
}
- obj->oldvx = obj->vx;
- obj->oldvy = obj->vy;
- currImage = obj->currImagePtr; // Get (new) ptr to current image
+ obj->_oldvx = obj->_vx;
+ obj->_oldvy = obj->_vy;
+ currImage = obj->_currImagePtr; // Get (new) ptr to current image
}
- if (obj->vx || obj->vy)
- obj->cycling = kCycleForward;
+ if (obj->_vx || obj->_vy)
+ obj->_cycling = kCycleForward;
break;
default:
; // Really, nothing
}
// Store boundaries
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
- storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
+ storeBoundary(obj->_x + currImage->_x1, obj->_x + currImage->_x2, obj->_y + currImage->_y2);
}
}
// Move objects, allowing for boundaries
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) {
+ Object *obj = &_objects[i]; // Get pointer to object
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_vx || obj->_vy)) {
// Only process if it's moving
// Do object movement. Delta_x,y return allowed movement in x,y
// to move as close to a boundary as possible without crossing it.
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
// object coordinates
- int x1 = obj->x + currImage->x1; // Left edge of object
- int x2 = obj->x + currImage->x2; // Right edge
- int y1 = obj->y + currImage->y1; // Top edge
- int y2 = obj->y + currImage->y2; // Bottom edge
+ int x1 = obj->_x + currImage->_x1; // Left edge of object
+ int x2 = obj->_x + currImage->_x2; // Right edge
+ int y1 = obj->_y + currImage->_y1; // Top edge
+ int y2 = obj->_y + currImage->_y2; // Bottom edge
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
clearBoundary(x1, x2, y2); // Clear our own boundary
// Allowable motion wrt boundary
- int dx = deltaX(x1, x2, obj->vx, y2);
- if (dx != obj->vx) {
+ int dx = deltaX(x1, x2, obj->_vx, y2);
+ if (dx != obj->_vx) {
// An object boundary collision!
boundaryCollision(obj);
- obj->vx = 0;
+ obj->_vx = 0;
}
- int dy = deltaY(x1, x2, obj->vy, y2);
- if (dy != obj->vy) {
+ int dy = deltaY(x1, x2, obj->_vy, y2);
+ if (dy != obj->_vy) {
// An object boundary collision!
boundaryCollision(obj);
- obj->vy = 0;
+ obj->_vy = 0;
}
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
storeBoundary(x1, x2, y2); // Re-store our own boundary
- obj->x += dx; // Update object position
- obj->y += dy;
+ obj->_x += dx; // Update object position
+ obj->_y += dy;
// Don't let object go outside screen
if (x1 < kEdge)
- obj->x = kEdge2;
+ obj->_x = kEdge2;
if (x2 > (kXPix - kEdge))
- obj->x = kXPix - kEdge2 - (x2 - x1);
+ obj->_x = kXPix - kEdge2 - (x2 - x1);
if (y1 < kEdge)
- obj->y = kEdge2;
+ obj->_y = kEdge2;
if (y2 > (kYPix - kEdge))
- obj->y = kYPix - kEdge2 - (y2 - y1);
+ obj->_y = kYPix - kEdge2 - (y2 - y1);
- if ((obj->vx == 0) && (obj->vy == 0) && (obj->pathType != kPathWander2) && (obj->pathType != kPathChase2))
- obj->cycling = kCycleNotCycling;
+ if ((obj->_vx == 0) && (obj->_vy == 0) && (obj->_pathType != kPathWander2) && (obj->_pathType != kPathChase2))
+ obj->_cycling = kCycleNotCycling;
}
}
// Clear all object baselines from the boundary file.
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
- clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
+ Object *obj = &_objects[i]; // Get pointer to object
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
+ clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2);
}
// If maze mode is enabled, do special maze processing
- if (_vm->_maze.enabledFl) {
- seq_t *currImage = _vm->_hero->currImagePtr; // Get ptr to current image
+ if (_vm->_maze._enabledFl) {
+ Seq *currImage = _vm->_hero->_currImagePtr; // Get ptr to current image
// hero coordinates
- int x1 = _vm->_hero->x + currImage->x1; // Left edge of object
- int x2 = _vm->_hero->x + currImage->x2; // Right edge
- int y1 = _vm->_hero->y + currImage->y1; // Top edge
- int y2 = _vm->_hero->y + currImage->y2; // Bottom edge
+ int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object
+ int x2 = _vm->_hero->_x + currImage->_x2; // Right edge
+ int y1 = _vm->_hero->_y + currImage->_y1; // Top edge
+ int y2 = _vm->_hero->_y + currImage->_y2; // Bottom edge
_vm->_scheduler->processMaze(x1, x2, y1, y2);
}
@@ -364,18 +364,18 @@ void ObjectHandler_v1w::swapImages(int objIndex1, int objIndex2) {
saveSeq(&_objects[objIndex1]);
- seqList_t tmpSeqList[kMaxSeqNumb];
- int seqListSize = sizeof(seqList_t) * kMaxSeqNumb;
+ SeqList tmpSeqList[kMaxSeqNumb];
+ int seqListSize = sizeof(SeqList) * kMaxSeqNumb;
- memmove(tmpSeqList, _objects[objIndex1].seqList, seqListSize);
- memmove(_objects[objIndex1].seqList, _objects[objIndex2].seqList, seqListSize);
- memmove(_objects[objIndex2].seqList, tmpSeqList, seqListSize);
+ memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize);
+ memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize);
+ memmove(_objects[objIndex2]._seqList, tmpSeqList, seqListSize);
restoreSeq(&_objects[objIndex1]);
- _objects[objIndex2].currImagePtr = _objects[objIndex2].seqList[0].seqPtr;
+ _objects[objIndex2]._currImagePtr = _objects[objIndex2]._seqList[0]._seqPtr;
_vm->_heroImage = (_vm->_heroImage == kHeroIndex) ? objIndex2 : kHeroIndex;
// Make sure baseline stays constant
- _objects[objIndex1].y += _objects[objIndex2].currImagePtr->y2 - _objects[objIndex1].currImagePtr->y2;
+ _objects[objIndex1]._y += _objects[objIndex2]._currImagePtr->_y2 - _objects[objIndex1]._currImagePtr->_y2;
}
} // End of namespace Hugo
diff --git a/engines/hugo/object_v2d.cpp b/engines/hugo/object_v2d.cpp
index 4a22fab2c0..7cb6c20dd0 100644
--- a/engines/hugo/object_v2d.cpp
+++ b/engines/hugo/object_v2d.cpp
@@ -59,43 +59,43 @@ void ObjectHandler_v2d::updateImages() {
debugC(5, kDebugObject, "updateImages");
// Initialize the index array to visible objects in current screen
- int num_objs = 0;
+ int objNumb = 0;
byte objindex[kMaxObjNumb]; // Array of indeces to objects
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i];
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling >= kCycleAlmostInvisible))
- objindex[num_objs++] = i;
+ Object *obj = &_objects[i];
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling >= kCycleAlmostInvisible))
+ objindex[objNumb++] = i;
}
// Sort the objects into increasing y+y2 (painter's algorithm)
- qsort(objindex, num_objs, sizeof(objindex[0]), y2comp);
+ qsort(objindex, objNumb, sizeof(objindex[0]), y2comp);
// Add each visible object to display list
- for (int i = 0; i < num_objs; i++) {
- object_t *obj = &_objects[objindex[i]];
+ for (int i = 0; i < objNumb; i++) {
+ Object *obj = &_objects[objindex[i]];
// Count down inter-frame timer
- if (obj->frameTimer)
- obj->frameTimer--;
+ if (obj->_frameTimer)
+ obj->_frameTimer--;
- if (obj->cycling > kCycleAlmostInvisible) { // Only if visible
- switch (obj->cycling) {
+ if (obj->_cycling > kCycleAlmostInvisible) { // Only if visible
+ switch (obj->_cycling) {
case kCycleNotCycling:
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == kPriorityOverOverlay);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, obj->_priority == kPriorityOverOverlay);
break;
case kCycleForward:
- if (obj->frameTimer) // Not time to see next frame yet
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == kPriorityOverOverlay);
+ if (obj->_frameTimer) // Not time to see next frame yet
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, obj->_priority == kPriorityOverOverlay);
else
- _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, obj->priority == kPriorityOverOverlay);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, obj->_priority == kPriorityOverOverlay);
break;
case kCycleBackward: {
- seq_t *seqPtr = obj->currImagePtr;
- if (!obj->frameTimer) { // Show next frame
- while (seqPtr->nextSeqPtr != obj->currImagePtr)
- seqPtr = seqPtr->nextSeqPtr;
+ Seq *seqPtr = obj->_currImagePtr;
+ if (!obj->_frameTimer) { // Show next frame
+ while (seqPtr->_nextSeqPtr != obj->_currImagePtr)
+ seqPtr = seqPtr->_nextSeqPtr;
}
- _vm->_screen->displayFrame(obj->x, obj->y, seqPtr, obj->priority == kPriorityOverOverlay);
+ _vm->_screen->displayFrame(obj->_x, obj->_y, seqPtr, obj->_priority == kPriorityOverOverlay);
break;
}
default:
@@ -107,30 +107,30 @@ void ObjectHandler_v2d::updateImages() {
_vm->_scheduler->waitForRefresh();
// Cycle any animating objects
- for (int i = 0; i < num_objs; i++) {
- object_t *obj = &_objects[objindex[i]];
- if (obj->cycling != kCycleInvisible) {
+ for (int i = 0; i < objNumb; i++) {
+ Object *obj = &_objects[objindex[i]];
+ if (obj->_cycling != kCycleInvisible) {
// Only if it's visible
- if (obj->cycling == kCycleAlmostInvisible)
- obj->cycling = kCycleInvisible;
+ if (obj->_cycling == kCycleAlmostInvisible)
+ obj->_cycling = kCycleInvisible;
// Now Rotate to next picture in sequence
- switch (obj->cycling) {
+ switch (obj->_cycling) {
case kCycleNotCycling:
break;
case kCycleForward:
- if (!obj->frameTimer) {
+ if (!obj->_frameTimer) {
// Time to step to next frame
- obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
+ obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr;
// Find out if this is last frame of sequence
// If so, reset frame_timer and decrement n_cycle
- if (obj->frameInterval || obj->cycleNumb) {
- obj->frameTimer = obj->frameInterval;
- for (int j = 0; j < obj->seqNumb; j++) {
- if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) {
- if (obj->cycleNumb) { // Decr cycleNumb if Non-continous
- if (!--obj->cycleNumb)
- obj->cycling = kCycleNotCycling;
+ if (obj->_frameInterval || obj->_cycleNumb) {
+ obj->_frameTimer = obj->_frameInterval;
+ for (int j = 0; j < obj->_seqNumb; j++) {
+ if (obj->_currImagePtr->_nextSeqPtr == obj->_seqList[j]._seqPtr) {
+ if (obj->_cycleNumb) { // Decr cycleNumb if Non-continous
+ if (!--obj->_cycleNumb)
+ obj->_cycling = kCycleNotCycling;
}
}
}
@@ -138,20 +138,20 @@ void ObjectHandler_v2d::updateImages() {
}
break;
case kCycleBackward: {
- if (!obj->frameTimer) {
+ if (!obj->_frameTimer) {
// Time to step to prev frame
- seq_t *seqPtr = obj->currImagePtr;
- while (obj->currImagePtr->nextSeqPtr != seqPtr)
- obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
+ Seq *seqPtr = obj->_currImagePtr;
+ while (obj->_currImagePtr->_nextSeqPtr != seqPtr)
+ obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr;
// Find out if this is first frame of sequence
// If so, reset frame_timer and decrement n_cycle
- if (obj->frameInterval || obj->cycleNumb) {
- obj->frameTimer = obj->frameInterval;
- for (int j = 0; j < obj->seqNumb; j++) {
- if (obj->currImagePtr == obj->seqList[j].seqPtr) {
- if (obj->cycleNumb){ // Decr cycleNumb if Non-continous
- if (!--obj->cycleNumb)
- obj->cycling = kCycleNotCycling;
+ if (obj->_frameInterval || obj->_cycleNumb) {
+ obj->_frameTimer = obj->_frameInterval;
+ for (int j = 0; j < obj->_seqNumb; j++) {
+ if (obj->_currImagePtr == obj->_seqList[j]._seqPtr) {
+ if (obj->_cycleNumb){ // Decr cycleNumb if Non-continous
+ if (!--obj->_cycleNumb)
+ obj->_cycling = kCycleNotCycling;
}
}
}
@@ -162,8 +162,8 @@ void ObjectHandler_v2d::updateImages() {
default:
break;
}
- obj->oldx = obj->x;
- obj->oldy = obj->y;
+ obj->_oldx = obj->_x;
+ obj->_oldy = obj->_y;
}
}
}
@@ -183,175 +183,175 @@ void ObjectHandler_v2d::moveObjects() {
// and store all (visible) object baselines into the boundary file.
// Don't store foreground or background objects
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
- if (obj->screenIndex == *_vm->_screen_p) {
- switch (obj->pathType) {
+ Object *obj = &_objects[i]; // Get pointer to object
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
+ if (obj->_screenIndex == *_vm->_screenPtr) {
+ switch (obj->_pathType) {
case kPathChase:
case kPathChase2: {
- int8 radius = obj->radius; // Default to object's radius
+ int8 radius = obj->_radius; // Default to object's radius
if (radius < 0) // If radius infinity, use closer value
radius = kStepDx;
// Allowable motion wrt boundary
- int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1;
- int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1;
+ int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - currImage->_x1;
+ int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - currImage->_y2 - 1;
if (abs(dx) <= radius)
- obj->vx = 0;
+ obj->_vx = 0;
else
- obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath);
+ obj->_vx = (dx > 0) ? MIN(dx, obj->_vxPath) : MAX(dx, -obj->_vxPath);
if (abs(dy) <= radius)
- obj->vy = 0;
+ obj->_vy = 0;
else
- obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath);
+ obj->_vy = (dy > 0) ? MIN(dy, obj->_vyPath) : MAX(dy, -obj->_vyPath);
// Set first image in sequence (if multi-seq object)
- switch (obj->seqNumb) {
+ switch (obj->_seqNumb) {
case 4:
- if (!obj->vx) { // Got 4 directions
- if (obj->vx != obj->oldvx) { // vx just stopped
+ if (!obj->_vx) { // Got 4 directions
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
if (dy > 0)
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
}
- } else if (obj->vx != obj->oldvx) {
+ } else if (obj->_vx != obj->_oldvx) {
if (dx > 0)
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
break;
case 3:
case 2:
- if (obj->vx != obj->oldvx) { // vx just stopped
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
if (dx > 0) // Left & right only
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
break;
}
- if (obj->vx || obj->vy) {
- obj->cycling = kCycleForward;
+ if (obj->_vx || obj->_vy) {
+ obj->_cycling = kCycleForward;
} else {
- obj->cycling = kCycleNotCycling;
+ obj->_cycling = kCycleNotCycling;
boundaryCollision(obj); // Must have got hero!
}
- obj->oldvx = obj->vx;
- obj->oldvy = obj->vy;
- currImage = obj->currImagePtr; // Get (new) ptr to current image
+ obj->_oldvx = obj->_vx;
+ obj->_oldvy = obj->_vy;
+ currImage = obj->_currImagePtr; // Get (new) ptr to current image
break;
}
case kPathWander2:
case kPathWander:
if (!_vm->_rnd->getRandomNumber(3 * _vm->_normalTPS)) { // Kick on random interval
- obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath;
- obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath;
+ obj->_vx = _vm->_rnd->getRandomNumber(obj->_vxPath << 1) - obj->_vxPath;
+ obj->_vy = _vm->_rnd->getRandomNumber(obj->_vyPath << 1) - obj->_vyPath;
// Set first image in sequence (if multi-seq object)
- if (obj->seqNumb > 1) {
- if (!obj->vx && (obj->seqNumb >= 4)) {
- if (obj->vx != obj->oldvx) { // vx just stopped
- if (obj->vy > 0)
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ if (obj->_seqNumb > 1) {
+ if (!obj->_vx && (obj->_seqNumb >= 4)) {
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
+ if (obj->_vy > 0)
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
}
- } else if (obj->vx != obj->oldvx) {
- if (obj->vx > 0)
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ } else if (obj->_vx != obj->_oldvx) {
+ if (obj->_vx > 0)
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
}
- obj->oldvx = obj->vx;
- obj->oldvy = obj->vy;
- currImage = obj->currImagePtr; // Get (new) ptr to current image
+ obj->_oldvx = obj->_vx;
+ obj->_oldvy = obj->_vy;
+ currImage = obj->_currImagePtr; // Get (new) ptr to current image
}
- if (obj->vx || obj->vy)
- obj->cycling = kCycleForward;
+ if (obj->_vx || obj->_vy)
+ obj->_cycling = kCycleForward;
break;
default:
; // Really, nothing
}
// Store boundaries
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
- storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
+ storeBoundary(obj->_x + currImage->_x1, obj->_x + currImage->_x2, obj->_y + currImage->_y2);
}
}
// Move objects, allowing for boundaries
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) {
+ Object *obj = &_objects[i]; // Get pointer to object
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_vx || obj->_vy)) {
// Only process if it's moving
// Do object movement. Delta_x,y return allowed movement in x,y
// to move as close to a boundary as possible without crossing it.
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
// object coordinates
- int x1 = obj->x + currImage->x1; // Left edge of object
- int x2 = obj->x + currImage->x2; // Right edge
- int y1 = obj->y + currImage->y1; // Top edge
- int y2 = obj->y + currImage->y2; // Bottom edge
+ int x1 = obj->_x + currImage->_x1; // Left edge of object
+ int x2 = obj->_x + currImage->_x2; // Right edge
+ int y1 = obj->_y + currImage->_y1; // Top edge
+ int y2 = obj->_y + currImage->_y2; // Bottom edge
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
clearBoundary(x1, x2, y2); // Clear our own boundary
// Allowable motion wrt boundary
- int dx = deltaX(x1, x2, obj->vx, y2);
- if (dx != obj->vx) {
+ int dx = deltaX(x1, x2, obj->_vx, y2);
+ if (dx != obj->_vx) {
// An object boundary collision!
boundaryCollision(obj);
- obj->vx = 0;
+ obj->_vx = 0;
}
- int dy = deltaY(x1, x2, obj->vy, y2);
- if (dy != obj->vy) {
+ int dy = deltaY(x1, x2, obj->_vy, y2);
+ if (dy != obj->_vy) {
// An object boundary collision!
boundaryCollision(obj);
- obj->vy = 0;
+ obj->_vy = 0;
}
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
storeBoundary(x1, x2, y2); // Re-store our own boundary
- obj->x += dx; // Update object position
- obj->y += dy;
+ obj->_x += dx; // Update object position
+ obj->_y += dy;
// Don't let object go outside screen
if (x1 < kEdge)
- obj->x = kEdge2;
+ obj->_x = kEdge2;
if (x2 > (kXPix - kEdge))
- obj->x = kXPix - kEdge2 - (x2 - x1);
+ obj->_x = kXPix - kEdge2 - (x2 - x1);
if (y1 < kEdge)
- obj->y = kEdge2;
+ obj->_y = kEdge2;
if (y2 > (kYPix - kEdge))
- obj->y = kYPix - kEdge2 - (y2 - y1);
+ obj->_y = kYPix - kEdge2 - (y2 - y1);
- if ((obj->vx == 0) && (obj->vy == 0) && (obj->pathType != kPathWander2) && (obj->pathType != kPathChase2))
- obj->cycling = kCycleNotCycling;
+ if ((obj->_vx == 0) && (obj->_vy == 0) && (obj->_pathType != kPathWander2) && (obj->_pathType != kPathChase2))
+ obj->_cycling = kCycleNotCycling;
}
}
// Clear all object baselines from the boundary file.
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
- clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
+ Object *obj = &_objects[i]; // Get pointer to object
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
+ clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2);
}
// If maze mode is enabled, do special maze processing
- if (_vm->_maze.enabledFl) {
- seq_t *currImage = _vm->_hero->currImagePtr; // Get ptr to current image
+ if (_vm->_maze._enabledFl) {
+ Seq *currImage = _vm->_hero->_currImagePtr; // Get ptr to current image
// hero coordinates
- int x1 = _vm->_hero->x + currImage->x1; // Left edge of object
- int x2 = _vm->_hero->x + currImage->x2; // Right edge
- int y1 = _vm->_hero->y + currImage->y1; // Top edge
- int y2 = _vm->_hero->y + currImage->y2; // Bottom edge
+ int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object
+ int x2 = _vm->_hero->_x + currImage->_x2; // Right edge
+ int y1 = _vm->_hero->_y + currImage->_y1; // Top edge
+ int y2 = _vm->_hero->_y + currImage->_y2; // Bottom edge
_vm->_scheduler->processMaze(x1, x2, y1, y2);
}
@@ -359,11 +359,11 @@ void ObjectHandler_v2d::moveObjects() {
void ObjectHandler_v2d::homeIn(const int objIndex1, const int objIndex2, const int8 objDx, const int8 objDy) {
// object obj1 will home in on object obj2
- object_t *obj1 = &_objects[objIndex1];
- object_t *obj2 = &_objects[objIndex2];
- obj1->pathType = kPathAuto;
- int dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1;
- int dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1;
+ Object *obj1 = &_objects[objIndex1];
+ Object *obj2 = &_objects[objIndex2];
+ obj1->_pathType = kPathAuto;
+ int dx = obj1->_x + obj1->_currImagePtr->_x1 - obj2->_x - obj2->_currImagePtr->_x1;
+ int dy = obj1->_y + obj1->_currImagePtr->_y1 - obj2->_y - obj2->_currImagePtr->_y1;
if (dx == 0) // Don't EVER divide by zero!
dx = 1;
@@ -371,11 +371,11 @@ void ObjectHandler_v2d::homeIn(const int objIndex1, const int objIndex2, const i
dy = 1;
if (abs(dx) > abs(dy)) {
- obj1->vx = objDx * -sign<int8>(dx);
- obj1->vy = abs((objDy * dy) / dx) * -sign<int8>(dy);
+ obj1->_vx = objDx * -sign<int8>(dx);
+ obj1->_vy = abs((objDy * dy) / dx) * -sign<int8>(dy);
} else {
- obj1->vy = objDy * -sign<int8>(dy);
- obj1->vx = abs((objDx * dx) / dy) * -sign<int8>(dx);
+ obj1->_vy = objDy * -sign<int8>(dy);
+ obj1->_vx = abs((objDx * dx) / dy) * -sign<int8>(dx);
}
}
} // End of namespace Hugo
diff --git a/engines/hugo/object_v3d.cpp b/engines/hugo/object_v3d.cpp
index cde7f5fd62..7bb4b95b4a 100644
--- a/engines/hugo/object_v3d.cpp
+++ b/engines/hugo/object_v3d.cpp
@@ -64,176 +64,176 @@ void ObjectHandler_v3d::moveObjects() {
// and store all (visible) object baselines into the boundary file.
// Don't store foreground or background objects
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
- if (obj->screenIndex == *_vm->_screen_p) {
- switch (obj->pathType) {
+ Object *obj = &_objects[i]; // Get pointer to object
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
+ if (obj->_screenIndex == *_vm->_screenPtr) {
+ switch (obj->_pathType) {
case kPathChase:
case kPathChase2: {
- int8 radius = obj->radius; // Default to object's radius
+ int8 radius = obj->_radius; // Default to object's radius
if (radius < 0) // If radius infinity, use closer value
radius = kStepDx;
// Allowable motion wrt boundary
- int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1;
- int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1;
+ int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - currImage->_x1;
+ int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - currImage->_y2 - 1;
if (abs(dx) <= radius)
- obj->vx = 0;
+ obj->_vx = 0;
else
- obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath);
+ obj->_vx = (dx > 0) ? MIN(dx, obj->_vxPath) : MAX(dx, -obj->_vxPath);
if (abs(dy) <= radius)
- obj->vy = 0;
+ obj->_vy = 0;
else
- obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath);
+ obj->_vy = (dy > 0) ? MIN(dy, obj->_vyPath) : MAX(dy, -obj->_vyPath);
// Set first image in sequence (if multi-seq object)
- switch (obj->seqNumb) {
+ switch (obj->_seqNumb) {
case 4:
- if (!obj->vx) { // Got 4 directions
- if (obj->vx != obj->oldvx) { // vx just stopped
+ if (!obj->_vx) { // Got 4 directions
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
if (dy >= 0)
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
}
- } else if (obj->vx != obj->oldvx) {
+ } else if (obj->_vx != obj->_oldvx) {
if (dx > 0)
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
break;
case 3:
case 2:
- if (obj->vx != obj->oldvx) { // vx just stopped
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
if (dx > 0) // Left & right only
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
break;
}
- if (obj->vx || obj->vy) {
- obj->cycling = kCycleForward;
+ if (obj->_vx || obj->_vy) {
+ obj->_cycling = kCycleForward;
} else {
- obj->cycling = kCycleNotCycling;
+ obj->_cycling = kCycleNotCycling;
boundaryCollision(obj); // Must have got hero!
}
- obj->oldvx = obj->vx;
- obj->oldvy = obj->vy;
- currImage = obj->currImagePtr; // Get (new) ptr to current image
+ obj->_oldvx = obj->_vx;
+ obj->_oldvy = obj->_vy;
+ currImage = obj->_currImagePtr; // Get (new) ptr to current image
break;
}
case kPathWander2:
case kPathWander:
if (!_vm->_rnd->getRandomNumber(3 * _vm->_normalTPS)) { // Kick on random interval
- obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath;
- obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath;
+ obj->_vx = _vm->_rnd->getRandomNumber(obj->_vxPath << 1) - obj->_vxPath;
+ obj->_vy = _vm->_rnd->getRandomNumber(obj->_vyPath << 1) - obj->_vyPath;
// Set first image in sequence (if multi-seq object)
- if (obj->seqNumb > 1) {
- if (!obj->vx && (obj->seqNumb >= 4)) {
- if (obj->vx != obj->oldvx) { // vx just stopped
- if (obj->vy > 0)
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ if (obj->_seqNumb > 1) {
+ if (!obj->_vx && (obj->_seqNumb >= 4)) {
+ if (obj->_vx != obj->_oldvx) { // vx just stopped
+ if (obj->_vy > 0)
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
}
- } else if (obj->vx != obj->oldvx) {
- if (obj->vx > 0)
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ } else if (obj->_vx != obj->_oldvx) {
+ if (obj->_vx > 0)
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
else
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
}
}
- obj->oldvx = obj->vx;
- obj->oldvy = obj->vy;
- currImage = obj->currImagePtr; // Get (new) ptr to current image
+ obj->_oldvx = obj->_vx;
+ obj->_oldvy = obj->_vy;
+ currImage = obj->_currImagePtr; // Get (new) ptr to current image
}
- if (obj->vx || obj->vy)
- obj->cycling = kCycleForward;
+ if (obj->_vx || obj->_vy)
+ obj->_cycling = kCycleForward;
break;
default:
; // Really, nothing
}
// Store boundaries
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
- storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
+ storeBoundary(obj->_x + currImage->_x1, obj->_x + currImage->_x2, obj->_y + currImage->_y2);
}
}
// Move objects, allowing for boundaries
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) {
+ Object *obj = &_objects[i]; // Get pointer to object
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_vx || obj->_vy)) {
// Only process if it's moving
// Do object movement. Delta_x,y return allowed movement in x,y
// to move as close to a boundary as possible without crossing it.
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
// object coordinates
- int x1 = obj->x + currImage->x1; // Left edge of object
- int x2 = obj->x + currImage->x2; // Right edge
- int y1 = obj->y + currImage->y1; // Top edge
- int y2 = obj->y + currImage->y2; // Bottom edge
+ int x1 = obj->_x + currImage->_x1; // Left edge of object
+ int x2 = obj->_x + currImage->_x2; // Right edge
+ int y1 = obj->_y + currImage->_y1; // Top edge
+ int y2 = obj->_y + currImage->_y2; // Bottom edge
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
clearBoundary(x1, x2, y2); // Clear our own boundary
// Allowable motion wrt boundary
- int dx = deltaX(x1, x2, obj->vx, y2);
- if (dx != obj->vx) {
+ int dx = deltaX(x1, x2, obj->_vx, y2);
+ if (dx != obj->_vx) {
// An object boundary collision!
boundaryCollision(obj);
- obj->vx = 0;
+ obj->_vx = 0;
}
- int dy = deltaY(x1, x2, obj->vy, y2);
- if (dy != obj->vy) {
+ int dy = deltaY(x1, x2, obj->_vy, y2);
+ if (dy != obj->_vy) {
// An object boundary collision!
boundaryCollision(obj);
- obj->vy = 0;
+ obj->_vy = 0;
}
- if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
+ if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
storeBoundary(x1, x2, y2); // Re-store our own boundary
- obj->x += dx; // Update object position
- obj->y += dy;
+ obj->_x += dx; // Update object position
+ obj->_y += dy;
// Don't let object go outside screen
if (x1 < kEdge)
- obj->x = kEdge2;
+ obj->_x = kEdge2;
if (x2 > (kXPix - kEdge))
- obj->x = kXPix - kEdge2 - (x2 - x1);
+ obj->_x = kXPix - kEdge2 - (x2 - x1);
if (y1 < kEdge)
- obj->y = kEdge2;
+ obj->_y = kEdge2;
if (y2 > (kYPix - kEdge))
- obj->y = kYPix - kEdge2 - (y2 - y1);
+ obj->_y = kYPix - kEdge2 - (y2 - y1);
- if ((obj->vx == 0) && (obj->vy == 0) && (obj->pathType != kPathWander2) && (obj->pathType != kPathChase2))
- obj->cycling = kCycleNotCycling;
+ if ((obj->_vx == 0) && (obj->_vy == 0) && (obj->_pathType != kPathWander2) && (obj->_pathType != kPathChase2))
+ obj->_cycling = kCycleNotCycling;
}
}
// Clear all object baselines from the boundary file.
for (int i = 0; i < _numObj; i++) {
- object_t *obj = &_objects[i]; // Get pointer to object
- seq_t *currImage = obj->currImagePtr; // Get ptr to current image
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating))
- clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
+ Object *obj = &_objects[i]; // Get pointer to object
+ Seq *currImage = obj->_currImagePtr; // Get ptr to current image
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating))
+ clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2);
}
// If maze mode is enabled, do special maze processing
- if (_vm->_maze.enabledFl) {
- seq_t *currImage = _vm->_hero->currImagePtr;// Get ptr to current image
+ if (_vm->_maze._enabledFl) {
+ Seq *currImage = _vm->_hero->_currImagePtr;// Get ptr to current image
// hero coordinates
- int x1 = _vm->_hero->x + currImage->x1; // Left edge of object
- int x2 = _vm->_hero->x + currImage->x2; // Right edge
- int y1 = _vm->_hero->y + currImage->y1; // Top edge
- int y2 = _vm->_hero->y + currImage->y2; // Bottom edge
+ int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object
+ int x2 = _vm->_hero->_x + currImage->_x2; // Right edge
+ int y1 = _vm->_hero->_y + currImage->_y1; // Top edge
+ int y2 = _vm->_hero->_y + currImage->_y2; // Bottom edge
_vm->_scheduler->processMaze(x1, x2, y1, y2);
}
@@ -249,18 +249,18 @@ void ObjectHandler_v3d::swapImages(int objIndex1, int objIndex2) {
saveSeq(&_objects[objIndex1]);
- seqList_t tmpSeqList[kMaxSeqNumb];
- int seqListSize = sizeof(seqList_t) * kMaxSeqNumb;
+ SeqList tmpSeqList[kMaxSeqNumb];
+ int seqListSize = sizeof(SeqList) * kMaxSeqNumb;
- memmove(tmpSeqList, _objects[objIndex1].seqList, seqListSize);
- memmove(_objects[objIndex1].seqList, _objects[objIndex2].seqList, seqListSize);
- memmove(_objects[objIndex2].seqList, tmpSeqList, seqListSize);
+ memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize);
+ memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize);
+ memmove(_objects[objIndex2]._seqList, tmpSeqList, seqListSize);
restoreSeq(&_objects[objIndex1]);
- _objects[objIndex2].currImagePtr = _objects[objIndex2].seqList[0].seqPtr;
+ _objects[objIndex2]._currImagePtr = _objects[objIndex2]._seqList[0]._seqPtr;
_vm->_heroImage = (_vm->_heroImage == kHeroIndex) ? objIndex2 : kHeroIndex;
// Make sure baseline stays constant
- _objects[objIndex1].y += _objects[objIndex2].currImagePtr->y2 - _objects[objIndex1].currImagePtr->y2;
+ _objects[objIndex1]._y += _objects[objIndex2]._currImagePtr->_y2 - _objects[objIndex1]._currImagePtr->_y2;
}
} // End of namespace Hugo
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index 4eaed6fecf..d18cc2181c 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -58,21 +58,21 @@ Parser::~Parser() {
}
uint16 Parser::getCmdDefaultVerbIdx(const uint16 index) const {
- return _cmdList[index][0].verbIndex;
+ return _cmdList[index][0]._verbIndex;
}
/**
* Read a cmd structure from Hugo.dat
*/
void Parser::readCmd(Common::ReadStream &in, cmd &curCmd) {
- curCmd.verbIndex = in.readUint16BE();
- curCmd.reqIndex = in.readUint16BE();
- curCmd.textDataNoCarryIndex = in.readUint16BE();
- curCmd.reqState = in.readByte();
- curCmd.newState = in.readByte();
- curCmd.textDataWrongIndex = in.readUint16BE();
- curCmd.textDataDoneIndex = in.readUint16BE();
- curCmd.actIndex = in.readUint16BE();
+ curCmd._verbIndex = in.readUint16BE();
+ curCmd._reqIndex = in.readUint16BE();
+ curCmd._textDataNoCarryIndex = in.readUint16BE();
+ curCmd._reqState = in.readByte();
+ curCmd._newState = in.readByte();
+ curCmd._textDataWrongIndex = in.readUint16BE();
+ curCmd._textDataDoneIndex = in.readUint16BE();
+ curCmd._actIndex = in.readUint16BE();
}
/**
@@ -99,20 +99,20 @@ void Parser::loadCmdList(Common::ReadStream &in) {
}
-void Parser::readBG(Common::ReadStream &in, background_t &curBG) {
- curBG.verbIndex = in.readUint16BE();
- curBG.nounIndex = in.readUint16BE();
- curBG.commentIndex = in.readSint16BE();
- curBG.matchFl = (in.readByte() != 0);
- curBG.roomState = in.readByte();
- curBG.bonusIndex = in.readByte();
+void Parser::readBG(Common::ReadStream &in, Background &curBG) {
+ curBG._verbIndex = in.readUint16BE();
+ curBG._nounIndex = in.readUint16BE();
+ curBG._commentIndex = in.readSint16BE();
+ curBG._matchFl = (in.readByte() != 0);
+ curBG._roomState = in.readByte();
+ curBG._bonusIndex = in.readByte();
}
/**
* Read _backgrounObjects from Hugo.dat
*/
void Parser::loadBackgroundObjects(Common::ReadStream &in) {
- background_t tmpBG;
+ Background tmpBG;
memset(&tmpBG, 0, sizeof(tmpBG));
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
@@ -120,13 +120,13 @@ void Parser::loadBackgroundObjects(Common::ReadStream &in) {
if (varnt == _vm->_gameVariant) {
_backgroundObjectsSize = numElem;
- _backgroundObjects = (background_t **)malloc(sizeof(background_t *) * numElem);
+ _backgroundObjects = (Background **)malloc(sizeof(Background *) * numElem);
}
for (int i = 0; i < numElem; i++) {
uint16 numSubElem = in.readUint16BE();
if (varnt == _vm->_gameVariant)
- _backgroundObjects[i] = (background_t *)malloc(sizeof(background_t) * numSubElem);
+ _backgroundObjects[i] = (Background *)malloc(sizeof(Background) * numSubElem);
for (int j = 0; j < numSubElem; j++)
readBG(in, (varnt == _vm->_gameVariant) ? _backgroundObjects[i][j] : tmpBG);
@@ -138,15 +138,15 @@ void Parser::loadBackgroundObjects(Common::ReadStream &in) {
* Read _catchallList from Hugo.dat
*/
void Parser::loadCatchallList(Common::ReadStream &in) {
- background_t *wrkCatchallList = 0;
- background_t tmpBG;
+ Background *wrkCatchallList = 0;
+ Background tmpBG;
memset(&tmpBG, 0, sizeof(tmpBG));
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
uint16 numElem = in.readUint16BE();
if (varnt == _vm->_gameVariant)
- _catchallList = wrkCatchallList = (background_t *)malloc(sizeof(background_t) * numElem);
+ _catchallList = wrkCatchallList = (Background *)malloc(sizeof(Background) * numElem);
for (int i = 0; i < numElem; i++)
readBG(in, (varnt == _vm->_gameVariant) ? wrkCatchallList[i] : tmpBG);
@@ -164,12 +164,12 @@ void Parser::loadArrayReqs(Common::SeekableReadStream &in) {
const char *Parser::useBG(const char *name) {
debugC(1, kDebugEngine, "useBG(%s)", name);
- objectList_t p = _backgroundObjects[*_vm->_screen_p];
- for (int i = 0; p[i].verbIndex != 0; i++) {
- if ((name == _vm->_text->getNoun(p[i].nounIndex, 0) &&
- p[i].verbIndex != _vm->_look) &&
- ((p[i].roomState == kStateDontCare) || (p[i].roomState == _vm->_screenStates[*_vm->_screen_p])))
- return _vm->_text->getVerb(p[i].verbIndex, 0);
+ ObjectList p = _backgroundObjects[*_vm->_screenPtr];
+ for (int i = 0; p[i]._verbIndex != 0; i++) {
+ if ((name == _vm->_text->getNoun(p[i]._nounIndex, 0) &&
+ p[i]._verbIndex != _vm->_look) &&
+ ((p[i]._roomState == kStateDontCare) || (p[i]._roomState == _vm->_screenStates[*_vm->_screenPtr])))
+ return _vm->_text->getVerb(p[i]._verbIndex, 0);
}
return 0;
@@ -198,7 +198,7 @@ void Parser::freeParser() {
}
void Parser::switchTurbo() {
- _vm->_config.turboFl = !_vm->_config.turboFl;
+ _vm->_config._turboFl = !_vm->_config._turboFl;
}
/**
@@ -208,7 +208,7 @@ void Parser::switchTurbo() {
void Parser::charHandler() {
debugC(4, kDebugParser, "charHandler");
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
// Check for one or more characters in ring buffer
while (_getIndex != _putIndex) {
@@ -222,7 +222,7 @@ void Parser::charHandler() {
_cmdLine[--_cmdLineIndex] = '\0';
break;
case Common::KEYCODE_RETURN: // EOL, pass line to line handler
- if (_cmdLineIndex && (_vm->_hero->pathType != kPathQuiet)) {
+ if (_cmdLineIndex && (_vm->_hero->_pathType != kPathQuiet)) {
// Remove inventory bar if active
if (_vm->_inventory->getInventoryState() == kInventoryActive)
_vm->_inventory->setInventoryState(kInventoryUp);
@@ -248,27 +248,27 @@ void Parser::charHandler() {
_cmdLineCursor = (_cmdLineCursor == '_') ? ' ' : '_';
// See if recall button pressed
- if (gameStatus.recallFl) {
+ if (gameStatus._recallFl) {
// Copy previous line to current cmdline
- gameStatus.recallFl = false;
+ gameStatus._recallFl = false;
strcpy(_cmdLine, _vm->_line);
_cmdLineIndex = strlen(_cmdLine);
}
sprintf(_vm->_statusLine, ">%s%c", _cmdLine, _cmdLineCursor);
- sprintf(_vm->_scoreLine, "F1-Help %s Score: %d of %d Sound %s", (_vm->_config.turboFl) ? "T" : " ", _vm->getScore(), _vm->getMaxScore(), (_vm->_config.soundFl) ? "On" : "Off");
+ sprintf(_vm->_scoreLine, "F1-Help %s Score: %d of %d Sound %s", (_vm->_config._turboFl) ? "T" : " ", _vm->getScore(), _vm->getMaxScore(), (_vm->_config._soundFl) ? "On" : "Off");
// See if "look" button pressed
- if (gameStatus.lookFl) {
+ if (gameStatus._lookFl) {
command("look around");
- gameStatus.lookFl = false;
+ gameStatus._lookFl = false;
}
}
void Parser::keyHandler(Common::Event event) {
debugC(1, kDebugParser, "keyHandler(%d)", event.kbd.keycode);
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
uint16 nChar = event.kbd.keycode;
if (event.kbd.flags & (Common::KBD_ALT | Common::KBD_SCRL))
@@ -288,8 +288,8 @@ void Parser::keyHandler(Common::Event event) {
_vm->_file->restoreGame(0);
break;
case Common::KEYCODE_s:
- if (gameStatus.viewState == kViewPlay) {
- if (gameStatus.gameOverFl)
+ if (gameStatus._viewState == kViewPlay) {
+ if (gameStatus._gameOverFl)
_vm->gameOverMsg();
else
_vm->_file->saveGame(-1, Common::String());
@@ -304,8 +304,8 @@ void Parser::keyHandler(Common::Event event) {
// Process key down event - called from OnKeyDown()
switch (nChar) { // Set various toggle states
case Common::KEYCODE_ESCAPE: // Escape key, may want to QUIT
- if (gameStatus.viewState == kViewIntro)
- gameStatus.skipIntroFl = true;
+ if (gameStatus._viewState == kViewIntro)
+ gameStatus._skipIntroFl = true;
else {
if (_vm->_inventory->getInventoryState() == kInventoryActive) // Remove inventory, if displayed
_vm->_inventory->setInventoryState(kInventoryUp);
@@ -333,7 +333,7 @@ void Parser::keyHandler(Common::Event event) {
break;
case Common::KEYCODE_F1: // User Help (DOS)
if (_checkDoubleF1Fl)
- gameStatus.helpFl = true;
+ gameStatus._helpFl = true;
else
_vm->_screen->userHelp();
_checkDoubleF1Fl = !_checkDoubleF1Fl;
@@ -343,11 +343,11 @@ void Parser::keyHandler(Common::Event event) {
_vm->_sound->toggleMusic();
break;
case Common::KEYCODE_F3: // Repeat last line
- gameStatus.recallFl = true;
+ gameStatus._recallFl = true;
break;
case Common::KEYCODE_F4: // Save game
- if (gameStatus.viewState == kViewPlay) {
- if (gameStatus.gameOverFl)
+ if (gameStatus._viewState == kViewPlay) {
+ if (gameStatus._gameOverFl)
_vm->gameOverMsg();
else
_vm->_file->saveGame(-1, Common::String());
@@ -366,7 +366,7 @@ void Parser::keyHandler(Common::Event event) {
warning("STUB: F9 (DOS) - BossKey");
break;
default: // Any other key
- if (!gameStatus.storyModeFl) { // Keyboard disabled
+ if (!gameStatus._storyModeFl) { // Keyboard disabled
// Add printable keys to ring buffer
uint16 bnext = _putIndex + 1;
if (bnext >= sizeof(_ringBuffer))
@@ -452,7 +452,7 @@ void Parser::showDosInventory() const {
for (int i = 0; i < _vm->_object->_numObj; i++) { // Find widths of 2 columns
if (_vm->_object->isCarried(i)) {
- uint16 len = strlen(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2));
+ uint16 len = strlen(_vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2));
if (index++ & 1) // Right hand column
len2 = (len > len2) ? len : len2;
else
@@ -473,9 +473,9 @@ void Parser::showDosInventory() const {
for (int i = 0; i < _vm->_object->_numObj; i++) { // Assign strings
if (_vm->_object->isCarried(i)) {
if (index++ & 1)
- buffer += Common::String(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2)) + "\n";
+ buffer += Common::String(_vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2)) + "\n";
else
- buffer += Common::String(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2)) + Common::String(blanks, len1 - strlen(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2)));
+ buffer += Common::String(_vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2)) + Common::String(blanks, len1 - strlen(_vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2)));
}
}
if (index & 1)
diff --git a/engines/hugo/parser.h b/engines/hugo/parser.h
index f8b9d9f13b..e72c46f591 100644
--- a/engines/hugo/parser.h
+++ b/engines/hugo/parser.h
@@ -48,14 +48,14 @@ enum seqTextParser {
* The following determines how a verb is acted on, for an object
*/
struct cmd {
- uint16 verbIndex; // the verb
- uint16 reqIndex; // ptr to list of required objects
- uint16 textDataNoCarryIndex; // ptr to string if any of above not carried
- byte reqState; // required state for verb to be done
- byte newState; // new states if verb done
- uint16 textDataWrongIndex; // ptr to string if wrong state
- uint16 textDataDoneIndex; // ptr to string if verb done
- uint16 actIndex; // Ptr to action list if verb done
+ uint16 _verbIndex; // the verb
+ uint16 _reqIndex; // ptr to list of required objects
+ uint16 _textDataNoCarryIndex; // ptr to string if any of above not carried
+ byte _reqState; // required state for verb to be done
+ byte _newState; // new states if verb done
+ uint16 _textDataWrongIndex; // ptr to string if wrong state
+ uint16 _textDataDoneIndex; // ptr to string if verb done
+ uint16 _actIndex; // Ptr to action list if verb done
};
/**
@@ -64,16 +64,16 @@ struct cmd {
* interesting ever happens with them. Rather than just be dumb and say
* "don't understand" we produce an interesting msg to keep user sane.
*/
-struct background_t {
- uint16 verbIndex;
- uint16 nounIndex;
- int commentIndex; // Index of comment produced on match
- bool matchFl; // TRUE if noun must match when present
- byte roomState; // "State" of room. Comments might differ.
- byte bonusIndex; // Index of bonus score (0 = no bonus)
+struct Background {
+ uint16 _verbIndex;
+ uint16 _nounIndex;
+ int _commentIndex; // Index of comment produced on match
+ bool _matchFl; // TRUE if noun must match when present
+ byte _roomState; // "State" of room. Comments might differ.
+ byte _bonusIndex; // Index of bonus score (0 = no bonus)
};
-typedef background_t *objectList_t;
+typedef Background *ObjectList;
class Parser {
public:
@@ -97,7 +97,7 @@ public:
virtual void lineHandler() = 0;
virtual void showInventory() const = 0;
- virtual void takeObject(object_t *obj) = 0;
+ virtual void takeObject(Object *obj) = 0;
protected:
HugoEngine *_vm;
@@ -105,18 +105,18 @@ protected:
int16 _cmdLineIndex; // Index into line
uint32 _cmdLineTick; // For flashing cursor
char _cmdLineCursor;
- command_t _cmdLine; // Build command line
+ Command _cmdLine; // Build command line
uint16 _backgroundObjectsSize;
uint16 _cmdListSize;
uint16 **_arrayReqs;
- background_t **_backgroundObjects;
- background_t *_catchallList;
+ Background **_backgroundObjects;
+ Background *_catchallList;
cmd **_cmdList;
const char *findNoun() const;
const char *findVerb() const;
- void readBG(Common::ReadStream &in, background_t &curBG);
+ void readBG(Common::ReadStream &in, Background &curBG);
void readCmd(Common::ReadStream &in, cmd &curCmd);
void showDosInventory() const;
@@ -136,17 +136,17 @@ public:
virtual void lineHandler();
virtual void showInventory() const;
- virtual void takeObject(object_t *obj);
+ virtual void takeObject(Object *obj);
protected:
- virtual void dropObject(object_t *obj);
+ virtual void dropObject(Object *obj);
const char *findNextNoun(const char *noun) const;
- bool isBackgroundWord_v1(const char *noun, const char *verb, objectList_t obj) const;
- bool isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, objectList_t obj) const;
- bool isGenericVerb_v1(const char *word, object_t *obj);
- bool isNear_v1(const char *verb, const char *noun, object_t *obj, char *comment) const;
- bool isObjectVerb_v1(const char *word, object_t *obj);
+ bool isBackgroundWord_v1(const char *noun, const char *verb, ObjectList obj) const;
+ bool isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, ObjectList obj) const;
+ bool isGenericVerb_v1(const char *word, Object *obj);
+ bool isNear_v1(const char *verb, const char *noun, Object *obj, char *comment) const;
+ bool isObjectVerb_v1(const char *word, Object *obj);
};
class Parser_v2d : public Parser_v1d {
@@ -164,13 +164,13 @@ public:
virtual void lineHandler();
protected:
- void dropObject(object_t *obj);
- bool isBackgroundWord_v3(objectList_t obj) const;
- bool isCatchallVerb_v3(objectList_t obj) const;
- bool isGenericVerb_v3(object_t *obj, char *comment);
- bool isNear_v3(object_t *obj, const char *verb, char *comment) const;
- bool isObjectVerb_v3(object_t *obj, char *comment);
- void takeObject(object_t *obj);
+ void dropObject(Object *obj);
+ bool isBackgroundWord_v3(ObjectList obj) const;
+ bool isCatchallVerb_v3(ObjectList obj) const;
+ bool isGenericVerb_v3(Object *obj, char *comment);
+ bool isNear_v3(Object *obj, const char *verb, char *comment) const;
+ bool isObjectVerb_v3(Object *obj, char *comment);
+ void takeObject(Object *obj);
};
class Parser_v1w : public Parser_v3d {
diff --git a/engines/hugo/parser_v1d.cpp b/engines/hugo/parser_v1d.cpp
index ccd428311b..f29b0161f5 100644
--- a/engines/hugo/parser_v1d.cpp
+++ b/engines/hugo/parser_v1d.cpp
@@ -78,35 +78,35 @@ const char *Parser_v1d::findNextNoun(const char *noun) const {
* If object not near, return suitable string; may be similar object closer
* If radius is -1, treat radius as infinity
*/
-bool Parser_v1d::isNear_v1(const char *verb, const char *noun, object_t *obj, char *comment) const {
+bool Parser_v1d::isNear_v1(const char *verb, const char *noun, Object *obj, char *comment) const {
debugC(1, kDebugParser, "isNear(%s, %s, obj, %s)", verb, noun, comment);
- if (!noun && !obj->verbOnlyFl) { // No noun specified & object not context senesitive
+ if (!noun && !obj->_verbOnlyFl) { // No noun specified & object not context senesitive
return false;
- } else if (noun && (noun != _vm->_text->getNoun(obj->nounIndex, 0))) { // Noun specified & not same as object
+ } else if (noun && (noun != _vm->_text->getNoun(obj->_nounIndex, 0))) { // Noun specified & not same as object
return false;
- } else if (obj->carriedFl) { // Object is being carried
+ } else if (obj->_carriedFl) { // Object is being carried
return true;
- } else if (obj->screenIndex != *_vm->_screen_p) { // Not in same screen
- if (obj->objValue)
+ } else if (obj->_screenIndex != *_vm->_screenPtr) { // Not in same screen
+ if (obj->_objValue)
strcpy (comment, _vm->_text->getTextParser(kCmtAny4));
return false;
}
- if (obj->cycling == kCycleInvisible) {
- if (obj->seqNumb) { // There is an image
+ if (obj->_cycling == kCycleInvisible) {
+ if (obj->_seqNumb) { // There is an image
strcpy(comment, _vm->_text->getTextParser(kCmtAny5));
return false;
} else { // No image, assume visible
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm->_hero->x) <= obj->radius) &&
- (abs(obj->y - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) {
+ if ((obj->_radius < 0) ||
+ ((abs(obj->_x - _vm->_hero->_x) <= obj->_radius) &&
+ (abs(obj->_y - _vm->_hero->_y - _vm->_hero->_currImagePtr->_y2) <= obj->_radius))) {
return true;
} else {
// User is either not close enough (stationary, valueless objects)
// or is not carrying it (small, portable objects of value)
if (noun) { // Don't say unless object specified
- if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
+ if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
strcpy(comment, _vm->_text->getTextParser(kCmtAny4));
else
strcpy(comment, _vm->_text->getTextParser(kCmtClose));
@@ -116,15 +116,15 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, object_t *obj, ch
}
}
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm->_hero->x) <= obj->radius) &&
- (abs(obj->y + obj->currImagePtr->y2 - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) {
+ if ((obj->_radius < 0) ||
+ ((abs(obj->_x - _vm->_hero->_x) <= obj->_radius) &&
+ (abs(obj->_y + obj->_currImagePtr->_y2 - _vm->_hero->_y - _vm->_hero->_currImagePtr->_y2) <= obj->_radius))) {
return true;
} else {
// User is either not close enough (stationary, valueless objects)
// or is not carrying it (small, portable objects of value)
if (noun) { // Don't say unless object specified
- if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
+ if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
strcpy(comment, _vm->_text->getTextParser(kCmtAny4));
else
strcpy(comment, _vm->_text->getTextParser(kCmtClose));
@@ -140,31 +140,31 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, object_t *obj, ch
* say_ok needed for special case of take/drop which may be handled not only
* here but also in a cmd_list with a donestr string simultaneously
*/
-bool Parser_v1d::isGenericVerb_v1(const char *word, object_t *obj) {
- debugC(1, kDebugParser, "isGenericVerb(%s, object_t *obj)", word);
+bool Parser_v1d::isGenericVerb_v1(const char *word, Object *obj) {
+ debugC(1, kDebugParser, "isGenericVerb(%s, Object *obj)", word);
- if (!obj->genericCmd)
+ if (!obj->_genericCmd)
return false;
// Following is equivalent to switch, but couldn't do one
if (word == _vm->_text->getVerb(_vm->_look, 0)) {
- if ((LOOK & obj->genericCmd) == LOOK)
- Utils::notifyBox(_vm->_text->getTextData(obj->dataIndex));
+ if ((LOOK & obj->_genericCmd) == LOOK)
+ Utils::notifyBox(_vm->_text->getTextData(obj->_dataIndex));
else
Utils::notifyBox(_vm->_text->getTextParser(kTBUnusual_1d));
} else if (word == _vm->_text->getVerb(_vm->_take, 0)) {
- if (obj->carriedFl)
+ if (obj->_carriedFl)
Utils::notifyBox(_vm->_text->getTextParser(kTBHave));
- else if ((TAKE & obj->genericCmd) == TAKE)
+ else if ((TAKE & obj->_genericCmd) == TAKE)
takeObject(obj);
- else if (!obj->verbOnlyFl) // Make sure not taking object in context!
+ else if (!obj->_verbOnlyFl) // Make sure not taking object in context!
Utils::notifyBox(_vm->_text->getTextParser(kTBNoUse));
else
return false;
} else if (word == _vm->_text->getVerb(_vm->_drop, 0)) {
- if (!obj->carriedFl)
+ if (!obj->_carriedFl)
Utils::notifyBox(_vm->_text->getTextParser(kTBDontHave));
- else if ((DROP & obj->genericCmd) == DROP)
+ else if ((DROP & obj->_genericCmd) == DROP)
dropObject(obj);
else
Utils::notifyBox(_vm->_text->getTextParser(kTBNeed));
@@ -181,46 +181,46 @@ bool Parser_v1d::isGenericVerb_v1(const char *word, object_t *obj) {
* and if it passes, perform the actions in the action list. If the verb
* is catered for, return TRUE
*/
-bool Parser_v1d::isObjectVerb_v1(const char *word, object_t *obj) {
- debugC(1, kDebugParser, "isObjectVerb(%s, object_t *obj)", word);
+bool Parser_v1d::isObjectVerb_v1(const char *word, Object *obj) {
+ debugC(1, kDebugParser, "isObjectVerb(%s, Object *obj)", word);
// First, find matching verb in cmd list
- uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands
+ uint16 cmdIndex = obj->_cmdIndex; // ptr to list of commands
if (!cmdIndex) // No commands for this obj
return false;
int i;
- for (i = 0; _cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
- if (!strcmp(word, _vm->_text->getVerb(_cmdList[cmdIndex][i].verbIndex, 0))) // Is this verb catered for?
+ for (i = 0; _cmdList[cmdIndex][i]._verbIndex != 0; i++) { // For each cmd
+ if (!strcmp(word, _vm->_text->getVerb(_cmdList[cmdIndex][i]._verbIndex, 0))) // Is this verb catered for?
break;
}
- if (_cmdList[cmdIndex][i].verbIndex == 0) // No
+ if (_cmdList[cmdIndex][i]._verbIndex == 0) // No
return false;
// Verb match found, check all required objects are being carried
cmd *cmnd = &_cmdList[cmdIndex][i]; // ptr to struct cmd
- if (cmnd->reqIndex) { // At least 1 thing in list
- uint16 *reqs = _arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
+ if (cmnd->_reqIndex) { // At least 1 thing in list
+ uint16 *reqs = _arrayReqs[cmnd->_reqIndex]; // ptr to list of required objects
for (i = 0; reqs[i]; i++) { // for each obj
if (!_vm->_object->isCarrying(reqs[i])) {
- Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataNoCarryIndex));
+ Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataNoCarryIndex));
return true;
}
}
}
// Required objects are present, now check state is correct
- if ((obj->state != cmnd->reqState) && (cmnd->reqState != kStateDontCare)){
- Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataWrongIndex));
+ if ((obj->_state != cmnd->_reqState) && (cmnd->_reqState != kStateDontCare)){
+ Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataWrongIndex));
return true;
}
// Everything checked. Change the state and carry out any actions
- if (cmnd->reqState != kStateDontCare) // Don't change new state if required state didn't care
- obj->state = cmnd->newState;
- Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataDoneIndex));
- _vm->_scheduler->insertActionList(cmnd->actIndex);
+ if (cmnd->_reqState != kStateDontCare) // Don't change new state if required state didn't care
+ obj->_state = cmnd->_newState;
+ Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataDoneIndex));
+ _vm->_scheduler->insertActionList(cmnd->_actIndex);
// Special case if verb is Take or Drop. Assume additional generic actions
if ((word == _vm->_text->getVerb(_vm->_take, 0)) || (word == _vm->_text->getVerb(_vm->_drop, 0)))
isGenericVerb_v1(word, obj);
@@ -231,15 +231,15 @@ bool Parser_v1d::isObjectVerb_v1(const char *word, object_t *obj) {
* Print text for possible background object. Return TRUE if match found
* Only match if both verb and noun found. Test_ca will match verb-only
*/
-bool Parser_v1d::isBackgroundWord_v1(const char *noun, const char *verb, objectList_t obj) const {
+bool Parser_v1d::isBackgroundWord_v1(const char *noun, const char *verb, ObjectList obj) const {
debugC(1, kDebugParser, "isBackgroundWord(%s, %s, object_list_t obj)", noun, verb);
if (!noun)
return false;
- for (int i = 0; obj[i].verbIndex; i++) {
- if ((verb == _vm->_text->getVerb(obj[i].verbIndex, 0)) && (noun == _vm->_text->getNoun(obj[i].nounIndex, 0))) {
- Utils::notifyBox(_vm->_file->fetchString(obj[i].commentIndex));
+ for (int i = 0; obj[i]._verbIndex; i++) {
+ if ((verb == _vm->_text->getVerb(obj[i]._verbIndex, 0)) && (noun == _vm->_text->getNoun(obj[i]._nounIndex, 0))) {
+ Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex));
return true;
}
}
@@ -249,31 +249,31 @@ bool Parser_v1d::isBackgroundWord_v1(const char *noun, const char *verb, objectL
/**
* Do all things necessary to carry an object
*/
-void Parser_v1d::takeObject(object_t *obj) {
- debugC(1, kDebugParser, "takeObject(object_t *obj)");
+void Parser_v1d::takeObject(Object *obj) {
+ debugC(1, kDebugParser, "takeObject(Object *obj)");
- obj->carriedFl = true;
- if (obj->seqNumb) // Don't change if no image to display
- obj->cycling = kCycleAlmostInvisible;
+ obj->_carriedFl = true;
+ if (obj->_seqNumb) // Don't change if no image to display
+ obj->_cycling = kCycleAlmostInvisible;
- _vm->adjustScore(obj->objValue);
+ _vm->adjustScore(obj->_objValue);
- Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(obj->nounIndex, TAKE_NAME)));
+ Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(obj->_nounIndex, TAKE_NAME)));
}
/**
* Do all necessary things to drop an object
*/
-void Parser_v1d::dropObject(object_t *obj) {
- debugC(1, kDebugParser, "dropObject(object_t *obj)");
-
- obj->carriedFl = false;
- obj->screenIndex = *_vm->_screen_p;
- if (obj->seqNumb) // Don't change if no image to display
- obj->cycling = kCycleNotCycling;
- obj->x = _vm->_hero->x - 1;
- obj->y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1;
- _vm->adjustScore(-obj->objValue);
+void Parser_v1d::dropObject(Object *obj) {
+ debugC(1, kDebugParser, "dropObject(Object *obj)");
+
+ obj->_carriedFl = false;
+ obj->_screenIndex = *_vm->_screenPtr;
+ if (obj->_seqNumb) // Don't change if no image to display
+ obj->_cycling = kCycleNotCycling;
+ obj->_x = _vm->_hero->_x - 1;
+ obj->_y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1;
+ _vm->adjustScore(-obj->_objValue);
Utils::notifyBox(_vm->_text->getTextParser(kTBOk));
}
@@ -281,18 +281,18 @@ void Parser_v1d::dropObject(object_t *obj) {
* Print text for possible background object. Return TRUE if match found
* If test_noun TRUE, must have a noun given
*/
-bool Parser_v1d::isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, objectList_t obj) const {
+bool Parser_v1d::isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, ObjectList obj) const {
debugC(1, kDebugParser, "isCatchallVerb(%d, %s, %s, object_list_t obj)", (testNounFl) ? 1 : 0, noun, verb);
- if (_vm->_maze.enabledFl)
+ if (_vm->_maze._enabledFl)
return false;
if (testNounFl && !noun)
return false;
- for (int i = 0; obj[i].verbIndex; i++) {
- if ((verb == _vm->_text->getVerb(obj[i].verbIndex, 0)) && ((noun == _vm->_text->getNoun(obj[i].nounIndex, 0)) || (obj[i].nounIndex == 0))) {
- Utils::notifyBox(_vm->_file->fetchString(obj[i].commentIndex));
+ for (int i = 0; obj[i]._verbIndex; i++) {
+ if ((verb == _vm->_text->getVerb(obj[i]._verbIndex, 0)) && ((noun == _vm->_text->getNoun(obj[i]._nounIndex, 0)) || (obj[i]._nounIndex == 0))) {
+ Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex));
return true;
}
}
@@ -305,12 +305,12 @@ bool Parser_v1d::isCatchallVerb_v1(bool testNounFl, const char *noun, const char
void Parser_v1d::lineHandler() {
debugC(1, kDebugParser, "lineHandler()");
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
// Toggle God Mode
if (!strncmp(_vm->_line, "PPG", 3)) {
_vm->_sound->playSound(!_vm->_soundTest, kSoundPriorityHigh);
- gameStatus.godModeFl = !gameStatus.godModeFl;
+ gameStatus._godModeFl = !gameStatus._godModeFl;
return;
}
@@ -321,7 +321,7 @@ void Parser_v1d::lineHandler() {
// fetch <object name> Hero carries named object
// fetch all Hero carries all possible objects
// find <object name> Takes hero to screen containing named object
- if (gameStatus.godModeFl) {
+ if (gameStatus._godModeFl) {
// Special code to allow me to go straight to any screen
if (strstr(_vm->_line, "goto")) {
for (int i = 0; i < _vm->_numScreens; i++) {
@@ -335,7 +335,7 @@ void Parser_v1d::lineHandler() {
// Special code to allow me to get objects from anywhere
if (strstr(_vm->_line, "fetch all")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (_vm->_object->_objects[i].genericCmd & TAKE)
+ if (_vm->_object->_objects[i]._genericCmd & TAKE)
takeObject(&_vm->_object->_objects[i]);
}
return;
@@ -343,7 +343,7 @@ void Parser_v1d::lineHandler() {
if (strstr(_vm->_line, "fetch")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) {
+ if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) {
takeObject(&_vm->_object->_objects[i]);
return;
}
@@ -353,8 +353,8 @@ void Parser_v1d::lineHandler() {
// Special code to allow me to goto objects
if (strstr(_vm->_line, "find")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) {
- _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex);
+ if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) {
+ _vm->_scheduler->newScreen(_vm->_object->_objects[i]._screenIndex);
return;
}
}
@@ -369,7 +369,7 @@ void Parser_v1d::lineHandler() {
// SAVE/RESTORE
if (!strcmp("save", _vm->_line)) {
- if (gameStatus.gameOverFl)
+ if (gameStatus._gameOverFl)
_vm->gameOverMsg();
else
_vm->_file->saveGame(-1, Common::String());
@@ -387,7 +387,7 @@ void Parser_v1d::lineHandler() {
if (strspn(_vm->_line, " ") == strlen(_vm->_line)) // Nothing but spaces!
return;
- if (gameStatus.gameOverFl) {
+ if (gameStatus._gameOverFl) {
// No commands allowed!
_vm->gameOverMsg();
return;
@@ -403,14 +403,14 @@ void Parser_v1d::lineHandler() {
noun = findNextNoun(noun); // Find a noun in the line
// Must try at least once for objects allowing verb-context
for (int i = 0; i < _vm->_object->_numObj; i++) {
- object_t *obj = &_vm->_object->_objects[i];
+ Object *obj = &_vm->_object->_objects[i];
if (isNear_v1(verb, noun, obj, farComment)) {
if (isObjectVerb_v1(verb, obj) // Foreground object
|| isGenericVerb_v1(verb, obj))// Common action type
return;
}
}
- if ((*farComment == '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screen_p]))
+ if ((*farComment == '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screenPtr]))
return;
} while (noun);
}
@@ -418,15 +418,15 @@ void Parser_v1d::lineHandler() {
if (*farComment != '\0') // An object matched but not near enough
Utils::notifyBox(farComment);
else if (!isCatchallVerb_v1(true, noun, verb, _catchallList) &&
- !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screen_p]) &&
+ !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screenPtr]) &&
!isCatchallVerb_v1(false, noun, verb, _catchallList))
Utils::notifyBox(_vm->_text->getTextParser(kTBEh_1d));
}
void Parser_v1d::showInventory() const {
- status_t &gameStatus = _vm->getGameStatus();
- if (gameStatus.viewState == kViewPlay) {
- if (gameStatus.gameOverFl)
+ Status &gameStatus = _vm->getGameStatus();
+ if (gameStatus._viewState == kViewPlay) {
+ if (gameStatus._gameOverFl)
_vm->gameOverMsg();
else
showDosInventory();
diff --git a/engines/hugo/parser_v1w.cpp b/engines/hugo/parser_v1w.cpp
index b1657c3bf4..3722ccc0e1 100644
--- a/engines/hugo/parser_v1w.cpp
+++ b/engines/hugo/parser_v1w.cpp
@@ -56,12 +56,12 @@ Parser_v1w::~Parser_v1w() {
void Parser_v1w::lineHandler() {
debugC(1, kDebugParser, "lineHandler()");
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
// Toggle God Mode
if (!strncmp(_vm->_line, "PPG", 3)) {
_vm->_sound->playSound(!_vm->_soundTest, kSoundPriorityHigh);
- gameStatus.godModeFl = !gameStatus.godModeFl;
+ gameStatus._godModeFl = !gameStatus._godModeFl;
return;
}
@@ -72,7 +72,7 @@ void Parser_v1w::lineHandler() {
// fetch <object name> Hero carries named object
// fetch all Hero carries all possible objects
// find <object name> Takes hero to screen containing named object
- if (gameStatus.godModeFl) {
+ if (gameStatus._godModeFl) {
// Special code to allow me to go straight to any screen
if (strstr(_vm->_line, "goto")) {
for (int i = 0; i < _vm->_numScreens; i++) {
@@ -86,7 +86,7 @@ void Parser_v1w::lineHandler() {
// Special code to allow me to get objects from anywhere
if (strstr(_vm->_line, "fetch all")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (_vm->_object->_objects[i].genericCmd & TAKE)
+ if (_vm->_object->_objects[i]._genericCmd & TAKE)
takeObject(&_vm->_object->_objects[i]);
}
return;
@@ -94,7 +94,7 @@ void Parser_v1w::lineHandler() {
if (strstr(_vm->_line, "fetch")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) {
+ if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) {
takeObject(&_vm->_object->_objects[i]);
return;
}
@@ -104,8 +104,8 @@ void Parser_v1w::lineHandler() {
// Special code to allow me to goto objects
if (strstr(_vm->_line, "find")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) {
- _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex);
+ if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) {
+ _vm->_scheduler->newScreen(_vm->_object->_objects[i]._screenIndex);
return;
}
}
@@ -121,12 +121,12 @@ void Parser_v1w::lineHandler() {
}
// SAVE/RESTORE
- if (!strcmp("save", _vm->_line) && gameStatus.viewState == kViewPlay) {
+ if (!strcmp("save", _vm->_line) && gameStatus._viewState == kViewPlay) {
_vm->_file->saveGame(-1, Common::String());
return;
}
- if (!strcmp("restore", _vm->_line) && (gameStatus.viewState == kViewPlay || gameStatus.viewState == kViewIdle)) {
+ if (!strcmp("restore", _vm->_line) && (gameStatus._viewState == kViewPlay || gameStatus._viewState == kViewIdle)) {
_vm->_file->restoreGame(-1);
return;
}
@@ -137,7 +137,7 @@ void Parser_v1w::lineHandler() {
if (strspn(_vm->_line, " ") == strlen(_vm->_line)) // Nothing but spaces!
return;
- if (gameStatus.gameOverFl) {
+ if (gameStatus._gameOverFl) {
// No commands allowed!
_vm->gameOverMsg();
return;
@@ -147,8 +147,8 @@ void Parser_v1w::lineHandler() {
// Test for nearby objects referenced explicitly
for (int i = 0; i < _vm->_object->_numObj; i++) {
- object_t *obj = &_vm->_object->_objects[i];
- if (isWordPresent(_vm->_text->getNounArray(obj->nounIndex))) {
+ Object *obj = &_vm->_object->_objects[i];
+ if (isWordPresent(_vm->_text->getNounArray(obj->_nounIndex))) {
if (isObjectVerb_v3(obj, farComment) || isGenericVerb_v3(obj, farComment))
return;
}
@@ -157,8 +157,8 @@ void Parser_v1w::lineHandler() {
// Test for nearby objects that only require a verb
// Note comment is unused if not near.
for (int i = 0; i < _vm->_object->_numObj; i++) {
- object_t *obj = &_vm->_object->_objects[i];
- if (obj->verbOnlyFl) {
+ Object *obj = &_vm->_object->_objects[i];
+ if (obj->_verbOnlyFl) {
char contextComment[kCompLineSize * 5] = ""; // Unused comment for context objects
if (isObjectVerb_v3(obj, contextComment) || isGenericVerb_v3(obj, contextComment))
return;
@@ -166,9 +166,9 @@ void Parser_v1w::lineHandler() {
}
// No objects match command line, try background and catchall commands
- if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screen_p]))
+ if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screenPtr]))
return;
- if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screen_p]))
+ if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screenPtr]))
return;
if (isBackgroundWord_v3(_catchallList))
@@ -185,7 +185,7 @@ void Parser_v1w::lineHandler() {
// Nothing matches. Report recognition success to user.
const char *verb = findVerb();
const char *noun = findNoun();
- if (verb == _vm->_text->getVerb(_vm->_look, 0) && _vm->_maze.enabledFl) {
+ if (verb == _vm->_text->getVerb(_vm->_look, 0) && _vm->_maze._enabledFl) {
Utils::notifyBox(_vm->_text->getTextParser(kTBMaze));
_vm->_object->showTakeables();
} else if (verb && noun) { // A combination I didn't think of
@@ -200,16 +200,16 @@ void Parser_v1w::lineHandler() {
}
void Parser_v1w::showInventory() const {
- status_t &gameStatus = _vm->getGameStatus();
- istate_t inventState = _vm->_inventory->getInventoryState();
- if (gameStatus.gameOverFl) {
+ Status &gameStatus = _vm->getGameStatus();
+ Istate inventState = _vm->_inventory->getInventoryState();
+ if (gameStatus._gameOverFl) {
_vm->gameOverMsg();
- } else if ((inventState == kInventoryOff) && (gameStatus.viewState == kViewPlay)) {
+ } else if ((inventState == kInventoryOff) && (gameStatus._viewState == kViewPlay)) {
_vm->_inventory->setInventoryState(kInventoryDown);
- gameStatus.viewState = kViewInvent;
+ gameStatus._viewState = kViewInvent;
} else if (inventState == kInventoryActive) {
_vm->_inventory->setInventoryState(kInventoryUp);
- gameStatus.viewState = kViewInvent;
+ gameStatus._viewState = kViewInvent;
}
}
diff --git a/engines/hugo/parser_v2d.cpp b/engines/hugo/parser_v2d.cpp
index 0095c4d726..6d71186f49 100644
--- a/engines/hugo/parser_v2d.cpp
+++ b/engines/hugo/parser_v2d.cpp
@@ -55,12 +55,12 @@ Parser_v2d::~Parser_v2d() {
void Parser_v2d::lineHandler() {
debugC(1, kDebugParser, "lineHandler()");
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
// Toggle God Mode
if (!strncmp(_vm->_line, "PPG", 3)) {
_vm->_sound->playSound(!_vm->_soundTest, kSoundPriorityHigh);
- gameStatus.godModeFl = !gameStatus.godModeFl;
+ gameStatus._godModeFl = !gameStatus._godModeFl;
return;
}
@@ -71,7 +71,7 @@ void Parser_v2d::lineHandler() {
// fetch <object name> Hero carries named object
// fetch all Hero carries all possible objects
// find <object name> Takes hero to screen containing named object
- if (gameStatus.godModeFl) {
+ if (gameStatus._godModeFl) {
// Special code to allow me to go straight to any screen
if (strstr(_vm->_line, "goto")) {
for (int i = 0; i < _vm->_numScreens; i++) {
@@ -85,7 +85,7 @@ void Parser_v2d::lineHandler() {
// Special code to allow me to get objects from anywhere
if (strstr(_vm->_line, "fetch all")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (_vm->_object->_objects[i].genericCmd & TAKE)
+ if (_vm->_object->_objects[i]._genericCmd & TAKE)
takeObject(&_vm->_object->_objects[i]);
}
return;
@@ -93,7 +93,7 @@ void Parser_v2d::lineHandler() {
if (strstr(_vm->_line, "fetch")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) {
+ if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) {
takeObject(&_vm->_object->_objects[i]);
return;
}
@@ -103,8 +103,8 @@ void Parser_v2d::lineHandler() {
// Special code to allow me to goto objects
if (strstr(_vm->_line, "find")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) {
- _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex);
+ if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) {
+ _vm->_scheduler->newScreen(_vm->_object->_objects[i]._screenIndex);
return;
}
}
@@ -119,7 +119,7 @@ void Parser_v2d::lineHandler() {
// SAVE/RESTORE
if (!strcmp("save", _vm->_line)) {
- if (gameStatus.gameOverFl)
+ if (gameStatus._gameOverFl)
_vm->gameOverMsg();
else
_vm->_file->saveGame(-1, Common::String());
@@ -137,7 +137,7 @@ void Parser_v2d::lineHandler() {
if (strspn(_vm->_line, " ") == strlen(_vm->_line)) // Nothing but spaces!
return;
- if (gameStatus.gameOverFl) {
+ if (gameStatus._gameOverFl) {
// No commands allowed!
_vm->gameOverMsg();
return;
@@ -153,26 +153,26 @@ void Parser_v2d::lineHandler() {
noun = findNextNoun(noun); // Find a noun in the line
// Must try at least once for objects allowing verb-context
for (int i = 0; i < _vm->_object->_numObj; i++) {
- object_t *obj = &_vm->_object->_objects[i];
+ Object *obj = &_vm->_object->_objects[i];
if (isNear_v1(verb, noun, obj, farComment)) {
if (isObjectVerb_v1(verb, obj) // Foreground object
|| isGenericVerb_v1(verb, obj))// Common action type
return;
}
}
- if ((*farComment != '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screen_p]))
+ if ((*farComment != '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screenPtr]))
return;
} while (noun);
}
noun = findNextNoun(noun);
- if ( !isCatchallVerb_v1(true, noun, verb, _backgroundObjects[*_vm->_screen_p])
+ if ( !isCatchallVerb_v1(true, noun, verb, _backgroundObjects[*_vm->_screenPtr])
&& !isCatchallVerb_v1(true, noun, verb, _catchallList)
- && !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screen_p])
+ && !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screenPtr])
&& !isCatchallVerb_v1(false, noun, verb, _catchallList)) {
if (*farComment != '\0') { // An object matched but not near enough
Utils::notifyBox(farComment);
- } else if (_vm->_maze.enabledFl && (verb == _vm->_text->getVerb(_vm->_look, 0))) {
+ } else if (_vm->_maze._enabledFl && (verb == _vm->_text->getVerb(_vm->_look, 0))) {
Utils::notifyBox(_vm->_text->getTextParser(kTBMaze));
_vm->_object->showTakeables();
} else if (verb && noun) { // A combination I didn't think of
diff --git a/engines/hugo/parser_v3d.cpp b/engines/hugo/parser_v3d.cpp
index b45e9186b3..a7e5896833 100644
--- a/engines/hugo/parser_v3d.cpp
+++ b/engines/hugo/parser_v3d.cpp
@@ -55,12 +55,12 @@ Parser_v3d::~Parser_v3d() {
void Parser_v3d::lineHandler() {
debugC(1, kDebugParser, "lineHandler()");
- status_t &gameStatus = _vm->getGameStatus();
+ Status &gameStatus = _vm->getGameStatus();
// Toggle God Mode
if (!strncmp(_vm->_line, "PPG", 3)) {
_vm->_sound->playSound(!_vm->_soundTest, kSoundPriorityHigh);
- gameStatus.godModeFl = !gameStatus.godModeFl;
+ gameStatus._godModeFl = !gameStatus._godModeFl;
return;
}
@@ -71,7 +71,7 @@ void Parser_v3d::lineHandler() {
// fetch <object name> Hero carries named object
// fetch all Hero carries all possible objects
// find <object name> Takes hero to screen containing named object
- if (gameStatus.godModeFl) {
+ if (gameStatus._godModeFl) {
// Special code to allow me to go straight to any screen
if (strstr(_vm->_line, "goto")) {
for (int i = 0; i < _vm->_numScreens; i++) {
@@ -85,7 +85,7 @@ void Parser_v3d::lineHandler() {
// Special code to allow me to get objects from anywhere
if (strstr(_vm->_line, "fetch all")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (_vm->_object->_objects[i].genericCmd & TAKE)
+ if (_vm->_object->_objects[i]._genericCmd & TAKE)
takeObject(&_vm->_object->_objects[i]);
}
return;
@@ -93,7 +93,7 @@ void Parser_v3d::lineHandler() {
if (strstr(_vm->_line, "fetch")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) {
+ if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) {
takeObject(&_vm->_object->_objects[i]);
return;
}
@@ -103,8 +103,8 @@ void Parser_v3d::lineHandler() {
// Special code to allow me to goto objects
if (strstr(_vm->_line, "find")) {
for (int i = 0; i < _vm->_object->_numObj; i++) {
- if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) {
- _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex);
+ if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) {
+ _vm->_scheduler->newScreen(_vm->_object->_objects[i]._screenIndex);
return;
}
}
@@ -121,7 +121,7 @@ void Parser_v3d::lineHandler() {
// SAVE/RESTORE
if (!strcmp("save", _vm->_line)) {
- if (gameStatus.gameOverFl)
+ if (gameStatus._gameOverFl)
_vm->gameOverMsg();
else
_vm->_file->saveGame(-1, Common::String());
@@ -139,7 +139,7 @@ void Parser_v3d::lineHandler() {
if (strspn(_vm->_line, " ") == strlen(_vm->_line)) // Nothing but spaces!
return;
- if (gameStatus.gameOverFl) {
+ if (gameStatus._gameOverFl) {
// No commands allowed!
_vm->gameOverMsg();
return;
@@ -149,8 +149,8 @@ void Parser_v3d::lineHandler() {
// Test for nearby objects referenced explicitly
for (int i = 0; i < _vm->_object->_numObj; i++) {
- object_t *obj = &_vm->_object->_objects[i];
- if (isWordPresent(_vm->_text->getNounArray(obj->nounIndex))) {
+ Object *obj = &_vm->_object->_objects[i];
+ if (isWordPresent(_vm->_text->getNounArray(obj->_nounIndex))) {
if (isObjectVerb_v3(obj, farComment) || isGenericVerb_v3(obj, farComment))
return;
}
@@ -159,8 +159,8 @@ void Parser_v3d::lineHandler() {
// Test for nearby objects that only require a verb
// Note comment is unused if not near.
for (int i = 0; i < _vm->_object->_numObj; i++) {
- object_t *obj = &_vm->_object->_objects[i];
- if (obj->verbOnlyFl) {
+ Object *obj = &_vm->_object->_objects[i];
+ if (obj->_verbOnlyFl) {
char contextComment[kCompLineSize * 5] = ""; // Unused comment for context objects
if (isObjectVerb_v3(obj, contextComment) || isGenericVerb_v3(obj, contextComment))
return;
@@ -168,9 +168,9 @@ void Parser_v3d::lineHandler() {
}
// No objects match command line, try background and catchall commands
- if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screen_p]))
+ if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screenPtr]))
return;
- if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screen_p]))
+ if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screenPtr]))
return;
if (isBackgroundWord_v3(_catchallList))
@@ -204,51 +204,51 @@ void Parser_v3d::lineHandler() {
* If it does, and the object is near and passes the tests in the command
* list then carry out the actions in the action list and return TRUE
*/
-bool Parser_v3d::isObjectVerb_v3(object_t *obj, char *comment) {
- debugC(1, kDebugParser, "isObjectVerb(object_t *obj, %s)", comment);
+bool Parser_v3d::isObjectVerb_v3(Object *obj, char *comment) {
+ debugC(1, kDebugParser, "isObjectVerb(Object *obj, %s)", comment);
// First, find matching verb in cmd list
- uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands
+ uint16 cmdIndex = obj->_cmdIndex; // ptr to list of commands
if (cmdIndex == 0) // No commands for this obj
return false;
int i;
- for (i = 0; _cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
- if (isWordPresent(_vm->_text->getVerbArray(_cmdList[cmdIndex][i].verbIndex))) // Was this verb used?
+ for (i = 0; _cmdList[cmdIndex][i]._verbIndex != 0; i++) { // For each cmd
+ if (isWordPresent(_vm->_text->getVerbArray(_cmdList[cmdIndex][i]._verbIndex))) // Was this verb used?
break;
}
- if (_cmdList[cmdIndex][i].verbIndex == 0) // No verbs used.
+ if (_cmdList[cmdIndex][i]._verbIndex == 0) // No verbs used.
return false;
// Verb match found. Check if object is Near
- char *verb = *_vm->_text->getVerbArray(_cmdList[cmdIndex][i].verbIndex);
+ char *verb = *_vm->_text->getVerbArray(_cmdList[cmdIndex][i]._verbIndex);
if (!isNear_v3(obj, verb, comment))
return false;
// Check all required objects are being carried
cmd *cmnd = &_cmdList[cmdIndex][i]; // ptr to struct cmd
- if (cmnd->reqIndex) { // At least 1 thing in list
- uint16 *reqs = _arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
+ if (cmnd->_reqIndex) { // At least 1 thing in list
+ uint16 *reqs = _arrayReqs[cmnd->_reqIndex]; // ptr to list of required objects
for (i = 0; reqs[i]; i++) { // for each obj
if (!_vm->_object->isCarrying(reqs[i])) {
- Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataNoCarryIndex));
+ Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataNoCarryIndex));
return true;
}
}
}
// Required objects are present, now check state is correct
- if ((obj->state != cmnd->reqState) && (cmnd->reqState != kStateDontCare)) {
- Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataWrongIndex));
+ if ((obj->_state != cmnd->_reqState) && (cmnd->_reqState != kStateDontCare)) {
+ Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataWrongIndex));
return true;
}
// Everything checked. Change the state and carry out any actions
- if (cmnd->reqState != kStateDontCare) // Don't change new state if required state didn't care
- obj->state = cmnd->newState;
- Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataDoneIndex));
- _vm->_scheduler->insertActionList(cmnd->actIndex);
+ if (cmnd->_reqState != kStateDontCare) // Don't change new state if required state didn't care
+ obj->_state = cmnd->_newState;
+ Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataDoneIndex));
+ _vm->_scheduler->insertActionList(cmnd->_actIndex);
// See if any additional generic actions
if ((verb == _vm->_text->getVerb(_vm->_look, 0)) || (verb == _vm->_text->getVerb(_vm->_take, 0)) || (verb == _vm->_text->getVerb(_vm->_drop, 0)))
@@ -259,21 +259,21 @@ bool Parser_v3d::isObjectVerb_v3(object_t *obj, char *comment) {
/**
* Test whether command line contains one of the generic actions
*/
-bool Parser_v3d::isGenericVerb_v3(object_t *obj, char *comment) {
- debugC(1, kDebugParser, "isGenericVerb(object_t *obj, %s)", comment);
+bool Parser_v3d::isGenericVerb_v3(Object *obj, char *comment) {
+ debugC(1, kDebugParser, "isGenericVerb(Object *obj, %s)", comment);
- if (!obj->genericCmd)
+ if (!obj->_genericCmd)
return false;
// Following is equivalent to switch, but couldn't do one
if (isWordPresent(_vm->_text->getVerbArray(_vm->_look)) && isNear_v3(obj, _vm->_text->getVerb(_vm->_look, 0), comment)) {
// Test state-dependent look before general look
- if ((obj->genericCmd & LOOK_S) == LOOK_S) {
- Utils::notifyBox(_vm->_text->getTextData(obj->stateDataIndex[obj->state]));
+ if ((obj->_genericCmd & LOOK_S) == LOOK_S) {
+ Utils::notifyBox(_vm->_text->getTextData(obj->_stateDataIndex[obj->_state]));
} else {
- if ((LOOK & obj->genericCmd) == LOOK) {
- if (obj->dataIndex != 0)
- Utils::notifyBox(_vm->_text->getTextData(obj->dataIndex));
+ if ((LOOK & obj->_genericCmd) == LOOK) {
+ if (obj->_dataIndex != 0)
+ Utils::notifyBox(_vm->_text->getTextData(obj->_dataIndex));
else
return false;
} else {
@@ -281,22 +281,22 @@ bool Parser_v3d::isGenericVerb_v3(object_t *obj, char *comment) {
}
}
} else if (isWordPresent(_vm->_text->getVerbArray(_vm->_take)) && isNear_v3(obj, _vm->_text->getVerb(_vm->_take, 0), comment)) {
- if (obj->carriedFl)
+ if (obj->_carriedFl)
Utils::notifyBox(_vm->_text->getTextParser(kTBHave));
- else if ((TAKE & obj->genericCmd) == TAKE)
+ else if ((TAKE & obj->_genericCmd) == TAKE)
takeObject(obj);
- else if (obj->cmdIndex) // No comment if possible commands
+ else if (obj->_cmdIndex) // No comment if possible commands
return false;
- else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context!
+ else if (!obj->_verbOnlyFl && (TAKE & obj->_genericCmd) == TAKE) // Make sure not taking object in context!
Utils::notifyBox(_vm->_text->getTextParser(kTBNoUse));
else
return false;
} else if (isWordPresent(_vm->_text->getVerbArray(_vm->_drop))) {
- if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
+ if (!obj->_carriedFl && ((DROP & obj->_genericCmd) == DROP))
Utils::notifyBox(_vm->_text->getTextParser(kTBDontHave));
- else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
+ else if (obj->_carriedFl && ((DROP & obj->_genericCmd) == DROP))
dropObject(obj);
- else if (obj->cmdIndex == 0)
+ else if (obj->_cmdIndex == 0)
Utils::notifyBox(_vm->_text->getTextParser(kTBNeed));
else
return false;
@@ -313,35 +313,35 @@ bool Parser_v3d::isGenericVerb_v3(object_t *obj, char *comment) {
* If radius is -1, treat radius as infinity
* Verb is included to determine correct comment if not near
*/
-bool Parser_v3d::isNear_v3(object_t *obj, const char *verb, char *comment) const {
- debugC(1, kDebugParser, "isNear(object_t *obj, %s, %s)", verb, comment);
+bool Parser_v3d::isNear_v3(Object *obj, const char *verb, char *comment) const {
+ debugC(1, kDebugParser, "isNear(Object *obj, %s, %s)", verb, comment);
- if (obj->carriedFl) // Object is being carried
+ if (obj->_carriedFl) // Object is being carried
return true;
- if (obj->screenIndex != *_vm->_screen_p) {
+ if (obj->_screenIndex != *_vm->_screenPtr) {
// Not in same screen
- if (obj->objValue)
+ if (obj->_objValue)
strcpy(comment, _vm->_text->getTextParser(kCmtAny1));
else
strcpy(comment, _vm->_text->getTextParser(kCmtAny2));
return false;
}
- if (obj->cycling == kCycleInvisible) {
- if (obj->seqNumb) {
+ if (obj->_cycling == kCycleInvisible) {
+ if (obj->_seqNumb) {
// There is an image
strcpy(comment, _vm->_text->getTextParser(kCmtAny3));
return false;
} else {
// No image, assume visible
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm->_hero->x) <= obj->radius) &&
- (abs(obj->y - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) {
+ if ((obj->_radius < 0) ||
+ ((abs(obj->_x - _vm->_hero->_x) <= obj->_radius) &&
+ (abs(obj->_y - _vm->_hero->_y - _vm->_hero->_currImagePtr->_y2) <= obj->_radius))) {
return true;
} else {
// User is not close enough
- if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
+ if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
strcpy(comment, _vm->_text->getTextParser(kCmtAny1));
else
strcpy(comment, _vm->_text->getTextParser(kCmtClose));
@@ -350,13 +350,13 @@ bool Parser_v3d::isNear_v3(object_t *obj, const char *verb, char *comment) const
}
}
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm->_hero->x) <= obj->radius) &&
- (abs(obj->y + obj->currImagePtr->y2 - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) {
+ if ((obj->_radius < 0) ||
+ ((abs(obj->_x - _vm->_hero->_x) <= obj->_radius) &&
+ (abs(obj->_y + obj->_currImagePtr->_y2 - _vm->_hero->_y - _vm->_hero->_currImagePtr->_y2) <= obj->_radius))) {
return true;
} else {
// User is not close enough
- if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
+ if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0)))
strcpy(comment, _vm->_text->getTextParser(kCmtAny1));
else
strcpy(comment, _vm->_text->getTextParser(kCmtClose));
@@ -368,36 +368,36 @@ bool Parser_v3d::isNear_v3(object_t *obj, const char *verb, char *comment) const
/**
* Do all things necessary to carry an object
*/
-void Parser_v3d::takeObject(object_t *obj) {
- debugC(1, kDebugParser, "takeObject(object_t *obj)");
+void Parser_v3d::takeObject(Object *obj) {
+ debugC(1, kDebugParser, "takeObject(Object *obj)");
- obj->carriedFl = true;
- if (obj->seqNumb) { // Don't change if no image to display
- obj->cycling = kCycleInvisible;
+ obj->_carriedFl = true;
+ if (obj->_seqNumb) { // Don't change if no image to display
+ obj->_cycling = kCycleInvisible;
}
- _vm->adjustScore(obj->objValue);
+ _vm->adjustScore(obj->_objValue);
- if (obj->seqNumb > 0) // If object has an image, force walk to dropped
- obj->viewx = -1; // (possibly moved) object next time taken!
- Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(obj->nounIndex, TAKE_NAME)));
+ if (obj->_seqNumb > 0) // If object has an image, force walk to dropped
+ obj->_viewx = -1; // (possibly moved) object next time taken!
+ Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(obj->_nounIndex, TAKE_NAME)));
}
/**
* Do all necessary things to drop an object
*/
-void Parser_v3d::dropObject(object_t *obj) {
- debugC(1, kDebugParser, "dropObject(object_t *obj)");
+void Parser_v3d::dropObject(Object *obj) {
+ debugC(1, kDebugParser, "dropObject(Object *obj)");
- obj->carriedFl = false;
- obj->screenIndex = *_vm->_screen_p;
- if ((obj->seqNumb > 1) || (obj->seqList[0].imageNbr > 1))
- obj->cycling = kCycleForward;
+ obj->_carriedFl = false;
+ obj->_screenIndex = *_vm->_screenPtr;
+ if ((obj->_seqNumb > 1) || (obj->_seqList[0]._imageNbr > 1))
+ obj->_cycling = kCycleForward;
else
- obj->cycling = kCycleNotCycling;
- obj->x = _vm->_hero->x - 1;
- obj->y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1;
- obj->y = (obj->y + obj->currImagePtr->y2 < kYPix) ? obj->y : kYPix - obj->currImagePtr->y2 - 10;
- _vm->adjustScore(-obj->objValue);
+ obj->_cycling = kCycleNotCycling;
+ obj->_x = _vm->_hero->_x - 1;
+ obj->_y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1;
+ obj->_y = (obj->_y + obj->_currImagePtr->_y2 < kYPix) ? obj->_y : kYPix - obj->_currImagePtr->_y2 - 10;
+ _vm->adjustScore(-obj->_objValue);
Utils::notifyBox(_vm->_text->getTextParser(kTBOk));
}
@@ -407,22 +407,22 @@ void Parser_v3d::dropObject(object_t *obj) {
* Note that if the background command list has match set TRUE then do not
* print text if there are any recognizable nouns in the command line
*/
-bool Parser_v3d::isCatchallVerb_v3(objectList_t obj) const {
+bool Parser_v3d::isCatchallVerb_v3(ObjectList obj) const {
debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)");
- if (_vm->_maze.enabledFl)
+ if (_vm->_maze._enabledFl)
return false;
- for (int i = 0; obj[i].verbIndex != 0; i++) {
- if (isWordPresent(_vm->_text->getVerbArray(obj[i].verbIndex)) && obj[i].nounIndex == 0 &&
- (!obj[i].matchFl || !findNoun()) &&
- ((obj[i].roomState == kStateDontCare) ||
- (obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) {
- Utils::notifyBox(_vm->_file->fetchString(obj[i].commentIndex));
- _vm->_scheduler->processBonus(obj[i].bonusIndex);
+ for (int i = 0; obj[i]._verbIndex != 0; i++) {
+ if (isWordPresent(_vm->_text->getVerbArray(obj[i]._verbIndex)) && obj[i]._nounIndex == 0 &&
+ (!obj[i]._matchFl || !findNoun()) &&
+ ((obj[i]._roomState == kStateDontCare) ||
+ (obj[i]._roomState == _vm->_screenStates[*_vm->_screenPtr]))) {
+ Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex));
+ _vm->_scheduler->processBonus(obj[i]._bonusIndex);
// If this is LOOK (without a noun), show any takeable objects
- if (*(_vm->_text->getVerbArray(obj[i].verbIndex)) == _vm->_text->getVerb(_vm->_look, 0))
+ if (*(_vm->_text->getVerbArray(obj[i]._verbIndex)) == _vm->_text->getVerb(_vm->_look, 0))
_vm->_object->showTakeables();
return true;
@@ -435,19 +435,19 @@ bool Parser_v3d::isCatchallVerb_v3(objectList_t obj) const {
* Search for matching verb/noun pairs in background command list
* Print text for possible background object. Return TRUE if match found
*/
-bool Parser_v3d::isBackgroundWord_v3(objectList_t obj) const {
+bool Parser_v3d::isBackgroundWord_v3(ObjectList obj) const {
debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)");
- if (_vm->_maze.enabledFl)
+ if (_vm->_maze._enabledFl)
return false;
- for (int i = 0; obj[i].verbIndex != 0; i++) {
- if (isWordPresent(_vm->_text->getVerbArray(obj[i].verbIndex)) &&
- isWordPresent(_vm->_text->getNounArray(obj[i].nounIndex)) &&
- ((obj[i].roomState == kStateDontCare) ||
- (obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) {
- Utils::notifyBox(_vm->_file->fetchString(obj[i].commentIndex));
- _vm->_scheduler->processBonus(obj[i].bonusIndex);
+ for (int i = 0; obj[i]._verbIndex != 0; i++) {
+ if (isWordPresent(_vm->_text->getVerbArray(obj[i]._verbIndex)) &&
+ isWordPresent(_vm->_text->getNounArray(obj[i]._nounIndex)) &&
+ ((obj[i]._roomState == kStateDontCare) ||
+ (obj[i]._roomState == _vm->_screenStates[*_vm->_screenPtr]))) {
+ Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex));
+ _vm->_scheduler->processBonus(obj[i]._bonusIndex);
return true;
}
}
diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp
index 281aacf031..54dae88c28 100644
--- a/engines/hugo/route.cpp
+++ b/engines/hugo/route.cpp
@@ -61,41 +61,41 @@ int16 Route::getRouteIndex() const {
void Route::setDirection(const uint16 keyCode) {
debugC(1, kDebugRoute, "setDirection(%d)", keyCode);
- object_t *obj = _vm->_hero; // Pointer to hero object
+ Object *obj = _vm->_hero; // Pointer to hero object
// Set first image in sequence
switch (keyCode) {
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
- obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr;
break;
case Common::KEYCODE_DOWN:
case Common::KEYCODE_KP2:
- obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr;
break;
case Common::KEYCODE_LEFT:
case Common::KEYCODE_KP4:
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
break;
case Common::KEYCODE_RIGHT:
case Common::KEYCODE_KP6:
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
break;
case Common::KEYCODE_HOME:
case Common::KEYCODE_KP7:
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
break;
case Common::KEYCODE_END:
case Common::KEYCODE_KP1:
- obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr;
break;
case Common::KEYCODE_PAGEUP:
case Common::KEYCODE_KP9:
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
break;
case Common::KEYCODE_PAGEDOWN:
case Common::KEYCODE_KP3:
- obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr;
+ obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr;
break;
}
}
@@ -107,68 +107,68 @@ void Route::setDirection(const uint16 keyCode) {
void Route::setWalk(const uint16 direction) {
debugC(1, kDebugRoute, "setWalk(%d)", direction);
- object_t *obj = _vm->_hero; // Pointer to hero object
+ Object *obj = _vm->_hero; // Pointer to hero object
- if (_vm->getGameStatus().storyModeFl || obj->pathType != kPathUser) // Make sure user has control
+ if (_vm->getGameStatus()._storyModeFl || obj->_pathType != kPathUser) // Make sure user has control
return;
- if (!obj->vx && !obj->vy)
+ if (!obj->_vx && !obj->_vy)
_oldWalkDirection = 0; // Fix for consistant restarts
if (direction != _oldWalkDirection) {
// Direction has changed
setDirection(direction); // Face new direction
- obj->vx = obj->vy = 0;
+ obj->_vx = obj->_vy = 0;
switch (direction) { // And set correct velocity
case Common::KEYCODE_UP:
case Common::KEYCODE_KP8:
- obj->vy = -kStepDy;
+ obj->_vy = -kStepDy;
break;
case Common::KEYCODE_DOWN:
case Common::KEYCODE_KP2:
- obj->vy = kStepDy;
+ obj->_vy = kStepDy;
break;
case Common::KEYCODE_LEFT:
case Common::KEYCODE_KP4:
- obj->vx = -kStepDx;
+ obj->_vx = -kStepDx;
break;
case Common::KEYCODE_RIGHT:
case Common::KEYCODE_KP6:
- obj->vx = kStepDx;
+ obj->_vx = kStepDx;
break;
case Common::KEYCODE_HOME:
case Common::KEYCODE_KP7:
- obj->vx = -kStepDx;
+ obj->_vx = -kStepDx;
// Note: in v1 Dos and v2 Dos, obj->vy is set to DY
- obj->vy = -kStepDy / 2;
+ obj->_vy = -kStepDy / 2;
break;
case Common::KEYCODE_END:
case Common::KEYCODE_KP1:
- obj->vx = -kStepDx;
+ obj->_vx = -kStepDx;
// Note: in v1 Dos and v2 Dos, obj->vy is set to -DY
- obj->vy = kStepDy / 2;
+ obj->_vy = kStepDy / 2;
break;
case Common::KEYCODE_PAGEUP:
case Common::KEYCODE_KP9:
- obj->vx = kStepDx;
+ obj->_vx = kStepDx;
// Note: in v1 Dos and v2 Dos, obj->vy is set to -DY
- obj->vy = -kStepDy / 2;
+ obj->_vy = -kStepDy / 2;
break;
case Common::KEYCODE_PAGEDOWN:
case Common::KEYCODE_KP3:
- obj->vx = kStepDx;
+ obj->_vx = kStepDx;
// Note: in v1 Dos and v2 Dos, obj->vy is set to DY
- obj->vy = kStepDy / 2;
+ obj->_vy = kStepDy / 2;
break;
}
_oldWalkDirection = direction;
- obj->cycling = kCycleForward;
+ obj->_cycling = kCycleForward;
} else {
// Same key twice - halt hero
- obj->vy = 0;
- obj->vx = 0;
+ obj->_vy = 0;
+ obj->_vx = 0;
_oldWalkDirection = 0;
- obj->cycling = kCycleNotCycling;
+ obj->_cycling = kCycleNotCycling;
}
}
@@ -188,8 +188,8 @@ void Route::segment(int16 x, int16 y) {
debugC(1, kDebugRoute, "segment(%d, %d)", x, y);
// Note: use of static - can't waste stack
- static image_pt p; // Ptr to _boundaryMap[y]
- static segment_t *seg_p; // Ptr to segment
+ static ImagePtr p; // Ptr to _boundaryMap[y]
+ static Segment *segPtr; // Ptr to segment
// Bomb out if stack exhausted
// Vinterstum: Is this just a safeguard, or actually used?
@@ -228,7 +228,7 @@ void Route::segment(int16 x, int16 y) {
if (y <= 0 || y >= kYPix - 1)
return;
- if (_vm->_hero->x < x1) {
+ if (_vm->_hero->_x < x1) {
// Hero x not in segment, search x1..x2
// Find all segments above current
for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
@@ -241,7 +241,7 @@ void Route::segment(int16 x, int16 y) {
if (_boundaryMap[y + 1][x] == 0)
segment(x, y + 1);
}
- } else if (_vm->_hero->x + kHeroMaxWidth > x2) {
+ } else if (_vm->_hero->_x + kHeroMaxWidth > x2) {
// Hero x not in segment, search x1..x2
// Find all segments above current
for (x = x2; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x >= x1; x--) {
@@ -257,22 +257,22 @@ void Route::segment(int16 x, int16 y) {
} else {
// Organize search around hero x position - this gives
// better chance for more direct route.
- for (x = _vm->_hero->x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
+ for (x = _vm->_hero->_x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
if (_boundaryMap[y - 1][x] == 0)
segment(x, y - 1);
}
- for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->x; x++) {
+ for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->_x; x++) {
if (_boundaryMap[y - 1][x] == 0)
segment(x, y - 1);
}
- for (x = _vm->_hero->x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
+ for (x = _vm->_hero->_x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) {
if (_boundaryMap[y + 1][x] == 0)
segment(x, y + 1);
}
- for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->x; x++) {
+ for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->_x; x++) {
if (_boundaryMap[y + 1][x] == 0)
segment(x, y + 1);
}
@@ -285,10 +285,10 @@ void Route::segment(int16 x, int16 y) {
_fullSegmentFl = true;
} else {
// Create segment
- seg_p = &_segment[_segmentNumb];
- seg_p->y = y;
- seg_p->x1 = x1;
- seg_p->x2 = x2;
+ segPtr = &_segment[_segmentNumb];
+ segPtr->_y = y;
+ segPtr->_x1 = x1;
+ segPtr->_x2 = x2;
_segmentNumb++;
}
}
@@ -298,7 +298,7 @@ void Route::segment(int16 x, int16 y) {
* Create and return ptr to new node. Initialize with previous node.
* Returns 0 if MAX_NODES exceeded
*/
-Point *Route::newNode() {
+Common::Point *Route::newNode() {
debugC(1, kDebugRoute, "newNode");
_routeListIndex++;
@@ -327,16 +327,16 @@ bool Route::findRoute(const int16 cx, const int16 cy) {
_destY = cy; // Destination coords
_destX = cx; // Destination coords
- int16 herox1 = _vm->_hero->x + _vm->_hero->currImagePtr->x1; // Hero baseline
- int16 herox2 = _vm->_hero->x + _vm->_hero->currImagePtr->x2; // Hero baseline
- int16 heroy = _vm->_hero->y + _vm->_hero->currImagePtr->y2; // Hero baseline
+ int16 herox1 = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1; // Hero baseline
+ int16 herox2 = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x2; // Hero baseline
+ int16 heroy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2; // Hero baseline
// Store all object baselines into objbound (except hero's = [0])
- object_t *obj; // Ptr to object
+ Object *obj; // Ptr to object
int i;
for (i = 1, obj = &_vm->_object->_objects[i]; i < _vm->_object->_numObj; i++, obj++) {
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling != kCycleInvisible) && (obj->priority == kPriorityFloating))
- _vm->_object->storeBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating))
+ _vm->_object->storeBoundary(obj->_oldx + obj->_currImagePtr->_x1, obj->_oldx + obj->_currImagePtr->_x2, obj->_oldy + obj->_currImagePtr->_y2);
}
// Combine objbound and boundary bitmaps to local byte map
@@ -350,8 +350,8 @@ bool Route::findRoute(const int16 cx, const int16 cy) {
// Clear all object baselines from objbound
for (i = 0, obj = _vm->_object->_objects; i < _vm->_object->_numObj; i++, obj++) {
- if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling != kCycleInvisible) && (obj->priority == kPriorityFloating))
- _vm->_object->clearBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
+ if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating))
+ _vm->_object->clearBoundary(obj->_oldx + obj->_currImagePtr->_x1, obj->_oldx + obj->_currImagePtr->_x2, obj->_oldy + obj->_currImagePtr->_y2);
}
// Search from hero to destination
@@ -368,32 +368,32 @@ bool Route::findRoute(const int16 cx, const int16 cy) {
_route[0].y = _destY;
// Make a final segment for hero's base (we left a spare)
- _segment[_segmentNumb].y = heroy;
- _segment[_segmentNumb].x1 = herox1;
- _segment[_segmentNumb].x2 = herox2;
+ _segment[_segmentNumb]._y = heroy;
+ _segment[_segmentNumb]._x1 = herox1;
+ _segment[_segmentNumb]._x2 = herox2;
_segmentNumb++;
- Point *routeNode; // Ptr to route node
+ Common::Point *routeNode; // Ptr to route node
// Look in segments[] for straight lines from destination to hero
for (i = 0, _routeListIndex = 0; i < _segmentNumb - 1; i++) {
if ((routeNode = newNode()) == 0) // New node for new segment
return false; // Too many nodes
- routeNode->y = _segment[i].y;
+ routeNode->y = _segment[i]._y;
// Look ahead for furthest straight line
for (int16 j = i + 1; j < _segmentNumb; j++) {
- segment_t *seg_p = &_segment[j];
+ Segment *segPtr = &_segment[j];
// Can we get to this segment from previous node?
- if (seg_p->x1 <= routeNode->x && seg_p->x2 >= routeNode->x + _heroWidth - 1) {
- routeNode->y = seg_p->y; // Yes, keep updating node
+ if (segPtr->_x1 <= routeNode->x && segPtr->_x2 >= routeNode->x + _heroWidth - 1) {
+ routeNode->y = segPtr->_y; // Yes, keep updating node
} else {
// No, create another node on previous segment to reach it
if ((routeNode = newNode()) == 0) // Add new route node
return false; // Too many nodes
// Find overlap between old and new segments
- int16 x1 = MAX(_segment[j - 1].x1, seg_p->x1);
- int16 x2 = MIN(_segment[j - 1].x2, seg_p->x2);
+ int16 x1 = MAX(_segment[j - 1]._x1, segPtr->_x1);
+ int16 x2 = MIN(_segment[j - 1]._x2, segPtr->_x2);
// If room, add a little offset to reduce staircase effect
int16 dx = kHeroMaxWidth >> 1;
@@ -433,18 +433,18 @@ void Route::processRoute() {
return;
// Current hero position
- int16 herox = _vm->_hero->x + _vm->_hero->currImagePtr->x1;
- int16 heroy = _vm->_hero->y + _vm->_hero->currImagePtr->y2;
- Point *routeNode = &_route[_routeIndex];
+ int16 herox = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1;
+ int16 heroy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2;
+ Common::Point *routeNode = &_route[_routeIndex];
// Arrived at node?
if (abs(herox - routeNode->x) < kStepDx + 1 && abs(heroy - routeNode->y) < kStepDy) {
// kStepDx too low
// Close enough - position hero exactly
- _vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1;
- _vm->_hero->y = _vm->_hero->oldy = routeNode->y - _vm->_hero->currImagePtr->y2;
- _vm->_hero->vx = _vm->_hero->vy = 0;
- _vm->_hero->cycling = kCycleNotCycling;
+ _vm->_hero->_x = _vm->_hero->_oldx = routeNode->x - _vm->_hero->_currImagePtr->_x1;
+ _vm->_hero->_y = _vm->_hero->_oldy = routeNode->y - _vm->_hero->_currImagePtr->_y2;
+ _vm->_hero->_vx = _vm->_hero->_vy = 0;
+ _vm->_hero->_cycling = kCycleNotCycling;
// Arrived at final node?
if (--_routeIndex < 0) {
@@ -458,7 +458,7 @@ void Route::processRoute() {
_vm->_object->lookObject(&_vm->_object->_objects[_routeObjId]);
turnedFl = false;
} else {
- setDirection(_vm->_object->_objects[_routeObjId].direction);
+ setDirection(_vm->_object->_objects[_routeObjId]._direction);
_routeIndex++; // Come round again
turnedFl = true;
}
@@ -468,7 +468,7 @@ void Route::processRoute() {
_vm->_object->useObject(_routeObjId);
turnedFl = false;
} else {
- setDirection(_vm->_object->_objects[_routeObjId].direction);
+ setDirection(_vm->_object->_objects[_routeObjId]._direction);
_routeIndex++; // Come round again
turnedFl = true;
}
@@ -477,7 +477,7 @@ void Route::processRoute() {
break;
}
}
- } else if (_vm->_hero->vx == 0 && _vm->_hero->vy == 0) {
+ } else if (_vm->_hero->_vx == 0 && _vm->_hero->_vy == 0) {
// Set direction of travel if at a node
// Note realignment when changing to (thinner) up/down sprite,
// otherwise hero could bump into boundaries along route.
@@ -487,10 +487,10 @@ void Route::processRoute() {
setWalk(Common::KEYCODE_LEFT);
} else if (heroy < routeNode->y) {
setWalk(Common::KEYCODE_DOWN);
- _vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1;
+ _vm->_hero->_x = _vm->_hero->_oldx = routeNode->x - _vm->_hero->_currImagePtr->_x1;
} else if (heroy > routeNode->y) {
setWalk(Common::KEYCODE_UP);
- _vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1;
+ _vm->_hero->_x = _vm->_hero->_oldx = routeNode->x - _vm->_hero->_currImagePtr->_x1;
}
}
}
@@ -500,11 +500,11 @@ void Route::processRoute() {
* go_for is the purpose, id indexes the exit or object to walk to
* Returns FALSE if route not found
*/
-bool Route::startRoute(const go_t routeType, const int16 objId, int16 cx, int16 cy) {
+bool Route::startRoute(const RouteType routeType, const int16 objId, int16 cx, int16 cy) {
debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", routeType, objId, cx, cy);
// Don't attempt to walk if user does not have control
- if (_vm->_hero->pathType != kPathUser)
+ if (_vm->_hero->_pathType != kPathUser)
return false;
// if inventory showing, make it go away
@@ -521,7 +521,7 @@ bool Route::startRoute(const go_t routeType, const int16 objId, int16 cx, int16
bool foundFl = false; // TRUE if route found ok
if ((foundFl = findRoute(cx, cy))) { // Found a route?
_routeIndex = _routeListIndex; // Node index
- _vm->_hero->vx = _vm->_hero->vy = 0; // Stop manual motion
+ _vm->_hero->_vx = _vm->_hero->_vy = 0; // Stop manual motion
}
return foundFl;
diff --git a/engines/hugo/route.h b/engines/hugo/route.h
index a95dd2151b..716829a201 100644
--- a/engines/hugo/route.h
+++ b/engines/hugo/route.h
@@ -30,21 +30,18 @@
#ifndef HUGO_ROUTE_H
#define HUGO_ROUTE_H
+#include "common/rect.h"
+
namespace Hugo {
/**
* Purpose of an automatic route
*/
-enum go_t {kRouteSpace, kRouteExit, kRouteLook, kRouteGet};
-
-struct Point {
- int x;
- int y;
-};
+enum RouteType {kRouteSpace, kRouteExit, kRouteLook, kRouteGet};
-struct segment_t { // Search segment
- int16 y; // y position
- int16 x1, x2; // Range of segment
+struct Segment { // Search segment
+ int16 _y; // y position
+ int16 _x1, _x2; // Range of segment
};
class Route {
@@ -55,7 +52,7 @@ public:
int16 getRouteIndex() const;
void processRoute();
- bool startRoute(const go_t routeType, const int16 objId, int16 cx, int16 cy);
+ bool startRoute(const RouteType routeType, const int16 objId, int16 cx, int16 cy);
void setDirection(const uint16 keyCode);
void setWalk(const uint16 direction);
@@ -69,13 +66,13 @@ private:
uint16 _oldWalkDirection; // Last direction char
- int16 _routeIndex; // Index into route list, or -1
- go_t _routeType; // Purpose of an automatic route
- int16 _routeObjId; // Index of exit of object walking to
+ int16 _routeIndex; // Index into route list, or -1
+ RouteType _routeType; // Purpose of an automatic route
+ int16 _routeObjId; // Index of exit of object walking to
byte _boundaryMap[kYPix][kXPix]; // Boundary byte map
- segment_t _segment[kMaxSeg]; // List of points in fill-path
- Point _route[kMaxNodes]; // List of nodes in route (global)
+ Segment _segment[kMaxSeg]; // List of points in fill-path
+ Common::Point _route[kMaxNodes]; // List of nodes in route (global)
int16 _segmentNumb; // Count number of segments
int16 _routeListIndex; // Index into route list
int16 _destX;
@@ -87,7 +84,7 @@ private:
void segment(int16 x, int16 y);
bool findRoute(const int16 cx, const int16 cy);
- Point *newNode();
+ Common::Point *newNode();
};
} // End of namespace Hugo
diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index 896e8fa2ce..32b8a47df7 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -66,15 +66,15 @@ void Scheduler::initCypher() {
void Scheduler::initEventQueue() {
debugC(1, kDebugSchedule, "initEventQueue");
- // Chain next_p from first to last
+ // Chain nextEvent from first to last
for (int i = kMaxEvents; --i;)
- _events[i - 1].nextEvent = &_events[i];
- _events[kMaxEvents - 1].nextEvent = 0;
+ _events[i - 1]._nextEvent = &_events[i];
+ _events[kMaxEvents - 1]._nextEvent = 0;
- // Chain prev_p from last to first
+ // Chain prevEvent from last to first
for (int i = 1; i < kMaxEvents; i++)
- _events[i].prevEvent = &_events[i - 1];
- _events[0].prevEvent = 0;
+ _events[i]._prevEvent = &_events[i - 1];
+ _events[0]._prevEvent = 0;
_headEvent = _tailEvent = 0; // Event list is empty
_freeEvent = _events; // Free list is full
@@ -83,14 +83,14 @@ void Scheduler::initEventQueue() {
/**
* Return a ptr to an event structure from the free list
*/
-event_t *Scheduler::getQueue() {
+Event *Scheduler::getQueue() {
debugC(4, kDebugSchedule, "getQueue");
if (!_freeEvent) // Error: no more events available
error("An error has occurred: %s", "getQueue");
- event_t *resEvent = _freeEvent;
- _freeEvent = _freeEvent->nextEvent;
- resEvent->nextEvent = 0;
+ Event *resEvent = _freeEvent;
+ _freeEvent = _freeEvent->_nextEvent;
+ resEvent->_nextEvent = 0;
return resEvent;
}
@@ -101,7 +101,7 @@ void Scheduler::insertActionList(const uint16 actIndex) {
debugC(1, kDebugSchedule, "insertActionList(%d)", actIndex);
if (_actListArr[actIndex]) {
- for (int i = 0; _actListArr[actIndex][i].a0.actType != ANULL; i++)
+ for (int i = 0; _actListArr[actIndex][i]._a0._actType != ANULL; i++)
insertAction(&_actListArr[actIndex][i]);
}
}
@@ -112,7 +112,7 @@ void Scheduler::insertActionList(const uint16 actIndex) {
uint32 Scheduler::getWinTicks() const {
debugC(5, kDebugSchedule, "getWinTicks()");
- return _vm->getGameStatus().tick;
+ return _vm->getGameStatus()._tick;
}
/**
@@ -147,9 +147,9 @@ uint32 Scheduler::getDosTicks(const bool updateFl) {
void Scheduler::processBonus(const int bonusIndex) {
debugC(1, kDebugSchedule, "processBonus(%d)", bonusIndex);
- if (!_points[bonusIndex].scoredFl) {
- _vm->adjustScore(_points[bonusIndex].score);
- _points[bonusIndex].scoredFl = true;
+ if (!_points[bonusIndex]._scoredFl) {
+ _vm->adjustScore(_points[bonusIndex]._score);
+ _points[bonusIndex]._scoredFl = true;
}
}
@@ -175,11 +175,11 @@ void Scheduler::newScreen(const int screenIndex) {
}
// 1. Clear out all local events
- event_t *curEvent = _headEvent; // The earliest event
- event_t *wrkEvent; // Event ptr
+ Event *curEvent = _headEvent; // The earliest event
+ Event *wrkEvent; // Event ptr
while (curEvent) { // While mature events found
- wrkEvent = curEvent->nextEvent; // Save p (becomes undefined after Del)
- if (curEvent->localActionFl)
+ wrkEvent = curEvent->_nextEvent; // Save p (becomes undefined after Del)
+ if (curEvent->_localActionFl)
delQueue(curEvent); // Return event to free list
curEvent = wrkEvent;
}
@@ -259,10 +259,10 @@ void Scheduler::loadPoints(Common::SeekableReadStream &in) {
uint16 numElem = in.readUint16BE();
if (varnt == _vm->_gameVariant) {
_numBonuses = numElem;
- _points = (point_t *)malloc(sizeof(point_t) * _numBonuses);
+ _points = (Point *)malloc(sizeof(Point) * _numBonuses);
for (int i = 0; i < _numBonuses; i++) {
- _points[i].score = in.readByte();
- _points[i].scoredFl = false;
+ _points[i]._score = in.readByte();
+ _points[i]._scoredFl = false;
}
} else {
in.skip(numElem);
@@ -270,280 +270,280 @@ void Scheduler::loadPoints(Common::SeekableReadStream &in) {
}
}
-void Scheduler::readAct(Common::ReadStream &in, act &curAct) {
+void Scheduler::readAct(Common::ReadStream &in, Act &curAct) {
uint16 numSubAct;
- curAct.a0.actType = (action_t) in.readByte();
- switch (curAct.a0.actType) {
+ curAct._a0._actType = (Action) in.readByte();
+ switch (curAct._a0._actType) {
case ANULL: // -1
break;
case ASCHEDULE: // 0
- curAct.a0.timer = in.readSint16BE();
- curAct.a0.actIndex = in.readUint16BE();
+ curAct._a0._timer = in.readSint16BE();
+ curAct._a0._actIndex = in.readUint16BE();
break;
case START_OBJ: // 1
- curAct.a1.timer = in.readSint16BE();
- curAct.a1.objIndex = in.readSint16BE();
- curAct.a1.cycleNumb = in.readSint16BE();
- curAct.a1.cycle = (cycle_t) in.readByte();
+ curAct._a1._timer = in.readSint16BE();
+ curAct._a1._objIndex = in.readSint16BE();
+ curAct._a1._cycleNumb = in.readSint16BE();
+ curAct._a1._cycle = (Cycle) in.readByte();
break;
case INIT_OBJXY: // 2
- curAct.a2.timer = in.readSint16BE();
- curAct.a2.objIndex = in.readSint16BE();
- curAct.a2.x = in.readSint16BE();
- curAct.a2.y = in.readSint16BE();
+ curAct._a2._timer = in.readSint16BE();
+ curAct._a2._objIndex = in.readSint16BE();
+ curAct._a2._x = in.readSint16BE();
+ curAct._a2._y = in.readSint16BE();
break;
case PROMPT: // 3
- curAct.a3.timer = in.readSint16BE();
- curAct.a3.promptIndex = in.readSint16BE();
+ curAct._a3._timer = in.readSint16BE();
+ curAct._a3._promptIndex = in.readSint16BE();
numSubAct = in.readUint16BE();
- curAct.a3.responsePtr = (int *)malloc(sizeof(int) * numSubAct);
+ curAct._a3._responsePtr = (int *)malloc(sizeof(int) * numSubAct);
for (int k = 0; k < numSubAct; k++)
- curAct.a3.responsePtr[k] = in.readSint16BE();
- curAct.a3.actPassIndex = in.readUint16BE();
- curAct.a3.actFailIndex = in.readUint16BE();
- curAct.a3.encodedFl = (in.readByte() == 1) ? true : false;
+ curAct._a3._responsePtr[k] = in.readSint16BE();
+ curAct._a3._actPassIndex = in.readUint16BE();
+ curAct._a3._actFailIndex = in.readUint16BE();
+ curAct._a3._encodedFl = (in.readByte() == 1) ? true : false;
break;
case BKGD_COLOR: // 4
- curAct.a4.timer = in.readSint16BE();
- curAct.a4.newBackgroundColor = in.readUint32BE();
+ curAct._a4._timer = in.readSint16BE();
+ curAct._a4._newBackgroundColor = in.readUint32BE();
break;
case INIT_OBJVXY: // 5
- curAct.a5.timer = in.readSint16BE();
- curAct.a5.objIndex = in.readSint16BE();
- curAct.a5.vx = in.readSint16BE();
- curAct.a5.vy = in.readSint16BE();
+ curAct._a5._timer = in.readSint16BE();
+ curAct._a5._objIndex = in.readSint16BE();
+ curAct._a5._vx = in.readSint16BE();
+ curAct._a5._vy = in.readSint16BE();
break;
case INIT_CARRY: // 6
- curAct.a6.timer = in.readSint16BE();
- curAct.a6.objIndex = in.readSint16BE();
- curAct.a6.carriedFl = (in.readByte() == 1) ? true : false;
+ curAct._a6._timer = in.readSint16BE();
+ curAct._a6._objIndex = in.readSint16BE();
+ curAct._a6._carriedFl = (in.readByte() == 1) ? true : false;
break;
case INIT_HF_COORD: // 7
- curAct.a7.timer = in.readSint16BE();
- curAct.a7.objIndex = in.readSint16BE();
+ curAct._a7._timer = in.readSint16BE();
+ curAct._a7._objIndex = in.readSint16BE();
break;
case NEW_SCREEN: // 8
- curAct.a8.timer = in.readSint16BE();
- curAct.a8.screenIndex = in.readSint16BE();
+ curAct._a8._timer = in.readSint16BE();
+ curAct._a8._screenIndex = in.readSint16BE();
break;
case INIT_OBJSTATE: // 9
- curAct.a9.timer = in.readSint16BE();
- curAct.a9.objIndex = in.readSint16BE();
- curAct.a9.newState = in.readByte();
+ curAct._a9._timer = in.readSint16BE();
+ curAct._a9._objIndex = in.readSint16BE();
+ curAct._a9._newState = in.readByte();
break;
case INIT_PATH: // 10
- curAct.a10.timer = in.readSint16BE();
- curAct.a10.objIndex = in.readSint16BE();
- curAct.a10.newPathType = in.readSint16BE();
- curAct.a10.vxPath = in.readByte();
- curAct.a10.vyPath = in.readByte();
+ curAct._a10._timer = in.readSint16BE();
+ curAct._a10._objIndex = in.readSint16BE();
+ curAct._a10._newPathType = in.readSint16BE();
+ curAct._a10._vxPath = in.readByte();
+ curAct._a10._vyPath = in.readByte();
break;
case COND_R: // 11
- curAct.a11.timer = in.readSint16BE();
- curAct.a11.objIndex = in.readSint16BE();
- curAct.a11.stateReq = in.readByte();
- curAct.a11.actPassIndex = in.readUint16BE();
- curAct.a11.actFailIndex = in.readUint16BE();
+ curAct._a11._timer = in.readSint16BE();
+ curAct._a11._objIndex = in.readSint16BE();
+ curAct._a11._stateReq = in.readByte();
+ curAct._a11._actPassIndex = in.readUint16BE();
+ curAct._a11._actFailIndex = in.readUint16BE();
break;
case TEXT: // 12
- curAct.a12.timer = in.readSint16BE();
- curAct.a12.stringIndex = in.readSint16BE();
+ curAct._a12._timer = in.readSint16BE();
+ curAct._a12._stringIndex = in.readSint16BE();
break;
case SWAP_IMAGES: // 13
- curAct.a13.timer = in.readSint16BE();
- curAct.a13.objIndex1 = in.readSint16BE();
- curAct.a13.objIndex2 = in.readSint16BE();
+ curAct._a13._timer = in.readSint16BE();
+ curAct._a13._objIndex1 = in.readSint16BE();
+ curAct._a13._objIndex2 = in.readSint16BE();
break;
case COND_SCR: // 14
- curAct.a14.timer = in.readSint16BE();
- curAct.a14.objIndex = in.readSint16BE();
- curAct.a14.screenReq = in.readSint16BE();
- curAct.a14.actPassIndex = in.readUint16BE();
- curAct.a14.actFailIndex = in.readUint16BE();
+ curAct._a14._timer = in.readSint16BE();
+ curAct._a14._objIndex = in.readSint16BE();
+ curAct._a14._screenReq = in.readSint16BE();
+ curAct._a14._actPassIndex = in.readUint16BE();
+ curAct._a14._actFailIndex = in.readUint16BE();
break;
case AUTOPILOT: // 15
- curAct.a15.timer = in.readSint16BE();
- curAct.a15.objIndex1 = in.readSint16BE();
- curAct.a15.objIndex2 = in.readSint16BE();
- curAct.a15.dx = in.readByte();
- curAct.a15.dy = in.readByte();
+ curAct._a15._timer = in.readSint16BE();
+ curAct._a15._objIndex1 = in.readSint16BE();
+ curAct._a15._objIndex2 = in.readSint16BE();
+ curAct._a15._dx = in.readByte();
+ curAct._a15._dy = in.readByte();
break;
case INIT_OBJ_SEQ: // 16
- curAct.a16.timer = in.readSint16BE();
- curAct.a16.objIndex = in.readSint16BE();
- curAct.a16.seqIndex = in.readSint16BE();
+ curAct._a16._timer = in.readSint16BE();
+ curAct._a16._objIndex = in.readSint16BE();
+ curAct._a16._seqIndex = in.readSint16BE();
break;
case SET_STATE_BITS: // 17
- curAct.a17.timer = in.readSint16BE();
- curAct.a17.objIndex = in.readSint16BE();
- curAct.a17.stateMask = in.readSint16BE();
+ curAct._a17._timer = in.readSint16BE();
+ curAct._a17._objIndex = in.readSint16BE();
+ curAct._a17._stateMask = in.readSint16BE();
break;
case CLEAR_STATE_BITS: // 18
- curAct.a18.timer = in.readSint16BE();
- curAct.a18.objIndex = in.readSint16BE();
- curAct.a18.stateMask = in.readSint16BE();
+ curAct._a18._timer = in.readSint16BE();
+ curAct._a18._objIndex = in.readSint16BE();
+ curAct._a18._stateMask = in.readSint16BE();
break;
case TEST_STATE_BITS: // 19
- curAct.a19.timer = in.readSint16BE();
- curAct.a19.objIndex = in.readSint16BE();
- curAct.a19.stateMask = in.readSint16BE();
- curAct.a19.actPassIndex = in.readUint16BE();
- curAct.a19.actFailIndex = in.readUint16BE();
+ curAct._a19._timer = in.readSint16BE();
+ curAct._a19._objIndex = in.readSint16BE();
+ curAct._a19._stateMask = in.readSint16BE();
+ curAct._a19._actPassIndex = in.readUint16BE();
+ curAct._a19._actFailIndex = in.readUint16BE();
break;
case DEL_EVENTS: // 20
- curAct.a20.timer = in.readSint16BE();
- curAct.a20.actTypeDel = (action_t) in.readByte();
+ curAct._a20._timer = in.readSint16BE();
+ curAct._a20._actTypeDel = (Action) in.readByte();
break;
case GAMEOVER: // 21
- curAct.a21.timer = in.readSint16BE();
+ curAct._a21._timer = in.readSint16BE();
break;
case INIT_HH_COORD: // 22
- curAct.a22.timer = in.readSint16BE();
- curAct.a22.objIndex = in.readSint16BE();
+ curAct._a22._timer = in.readSint16BE();
+ curAct._a22._objIndex = in.readSint16BE();
break;
case EXIT: // 23
- curAct.a23.timer = in.readSint16BE();
+ curAct._a23._timer = in.readSint16BE();
break;
case BONUS: // 24
- curAct.a24.timer = in.readSint16BE();
- curAct.a24.pointIndex = in.readSint16BE();
+ curAct._a24._timer = in.readSint16BE();
+ curAct._a24._pointIndex = in.readSint16BE();
break;
case COND_BOX: // 25
- curAct.a25.timer = in.readSint16BE();
- curAct.a25.objIndex = in.readSint16BE();
- curAct.a25.x1 = in.readSint16BE();
- curAct.a25.y1 = in.readSint16BE();
- curAct.a25.x2 = in.readSint16BE();
- curAct.a25.y2 = in.readSint16BE();
- curAct.a25.actPassIndex = in.readUint16BE();
- curAct.a25.actFailIndex = in.readUint16BE();
+ curAct._a25._timer = in.readSint16BE();
+ curAct._a25._objIndex = in.readSint16BE();
+ curAct._a25._x1 = in.readSint16BE();
+ curAct._a25._y1 = in.readSint16BE();
+ curAct._a25._x2 = in.readSint16BE();
+ curAct._a25._y2 = in.readSint16BE();
+ curAct._a25._actPassIndex = in.readUint16BE();
+ curAct._a25._actFailIndex = in.readUint16BE();
break;
case SOUND: // 26
- curAct.a26.timer = in.readSint16BE();
- curAct.a26.soundIndex = in.readSint16BE();
+ curAct._a26._timer = in.readSint16BE();
+ curAct._a26._soundIndex = in.readSint16BE();
break;
case ADD_SCORE: // 27
- curAct.a27.timer = in.readSint16BE();
- curAct.a27.objIndex = in.readSint16BE();
+ curAct._a27._timer = in.readSint16BE();
+ curAct._a27._objIndex = in.readSint16BE();
break;
case SUB_SCORE: // 28
- curAct.a28.timer = in.readSint16BE();
- curAct.a28.objIndex = in.readSint16BE();
+ curAct._a28._timer = in.readSint16BE();
+ curAct._a28._objIndex = in.readSint16BE();
break;
case COND_CARRY: // 29
- curAct.a29.timer = in.readSint16BE();
- curAct.a29.objIndex = in.readSint16BE();
- curAct.a29.actPassIndex = in.readUint16BE();
- curAct.a29.actFailIndex = in.readUint16BE();
+ curAct._a29._timer = in.readSint16BE();
+ curAct._a29._objIndex = in.readSint16BE();
+ curAct._a29._actPassIndex = in.readUint16BE();
+ curAct._a29._actFailIndex = in.readUint16BE();
break;
case INIT_MAZE: // 30
- curAct.a30.timer = in.readSint16BE();
- curAct.a30.mazeSize = in.readByte();
- curAct.a30.x1 = in.readSint16BE();
- curAct.a30.y1 = in.readSint16BE();
- curAct.a30.x2 = in.readSint16BE();
- curAct.a30.y2 = in.readSint16BE();
- curAct.a30.x3 = in.readSint16BE();
- curAct.a30.x4 = in.readSint16BE();
- curAct.a30.firstScreenIndex = in.readByte();
+ curAct._a30._timer = in.readSint16BE();
+ curAct._a30._mazeSize = in.readByte();
+ curAct._a30._x1 = in.readSint16BE();
+ curAct._a30._y1 = in.readSint16BE();
+ curAct._a30._x2 = in.readSint16BE();
+ curAct._a30._y2 = in.readSint16BE();
+ curAct._a30._x3 = in.readSint16BE();
+ curAct._a30._x4 = in.readSint16BE();
+ curAct._a30._firstScreenIndex = in.readByte();
break;
case EXIT_MAZE: // 31
- curAct.a31.timer = in.readSint16BE();
+ curAct._a31._timer = in.readSint16BE();
break;
case INIT_PRIORITY: // 32
- curAct.a32.timer = in.readSint16BE();
- curAct.a32.objIndex = in.readSint16BE();
- curAct.a32.priority = in.readByte();
+ curAct._a32._timer = in.readSint16BE();
+ curAct._a32._objIndex = in.readSint16BE();
+ curAct._a32._priority = in.readByte();
break;
case INIT_SCREEN: // 33
- curAct.a33.timer = in.readSint16BE();
- curAct.a33.objIndex = in.readSint16BE();
- curAct.a33.screenIndex = in.readSint16BE();
+ curAct._a33._timer = in.readSint16BE();
+ curAct._a33._objIndex = in.readSint16BE();
+ curAct._a33._screenIndex = in.readSint16BE();
break;
case AGSCHEDULE: // 34
- curAct.a34.timer = in.readSint16BE();
- curAct.a34.actIndex = in.readUint16BE();
+ curAct._a34._timer = in.readSint16BE();
+ curAct._a34._actIndex = in.readUint16BE();
break;
case REMAPPAL: // 35
- curAct.a35.timer = in.readSint16BE();
- curAct.a35.oldColorIndex = in.readSint16BE();
- curAct.a35.newColorIndex = in.readSint16BE();
+ curAct._a35._timer = in.readSint16BE();
+ curAct._a35._oldColorIndex = in.readSint16BE();
+ curAct._a35._newColorIndex = in.readSint16BE();
break;
case COND_NOUN: // 36
- curAct.a36.timer = in.readSint16BE();
- curAct.a36.nounIndex = in.readUint16BE();
- curAct.a36.actPassIndex = in.readUint16BE();
- curAct.a36.actFailIndex = in.readUint16BE();
+ curAct._a36._timer = in.readSint16BE();
+ curAct._a36._nounIndex = in.readUint16BE();
+ curAct._a36._actPassIndex = in.readUint16BE();
+ curAct._a36._actFailIndex = in.readUint16BE();
break;
case SCREEN_STATE: // 37
- curAct.a37.timer = in.readSint16BE();
- curAct.a37.screenIndex = in.readSint16BE();
- curAct.a37.newState = in.readByte();
+ curAct._a37._timer = in.readSint16BE();
+ curAct._a37._screenIndex = in.readSint16BE();
+ curAct._a37._newState = in.readByte();
break;
case INIT_LIPS: // 38
- curAct.a38.timer = in.readSint16BE();
- curAct.a38.lipsObjIndex = in.readSint16BE();
- curAct.a38.objIndex = in.readSint16BE();
- curAct.a38.dxLips = in.readByte();
- curAct.a38.dyLips = in.readByte();
+ curAct._a38._timer = in.readSint16BE();
+ curAct._a38._lipsObjIndex = in.readSint16BE();
+ curAct._a38._objIndex = in.readSint16BE();
+ curAct._a38._dxLips = in.readByte();
+ curAct._a38._dyLips = in.readByte();
break;
case INIT_STORY_MODE: // 39
- curAct.a39.timer = in.readSint16BE();
- curAct.a39.storyModeFl = (in.readByte() == 1);
+ curAct._a39._timer = in.readSint16BE();
+ curAct._a39._storyModeFl = (in.readByte() == 1);
break;
case WARN: // 40
- curAct.a40.timer = in.readSint16BE();
- curAct.a40.stringIndex = in.readSint16BE();
+ curAct._a40._timer = in.readSint16BE();
+ curAct._a40._stringIndex = in.readSint16BE();
break;
case COND_BONUS: // 41
- curAct.a41.timer = in.readSint16BE();
- curAct.a41.BonusIndex = in.readSint16BE();
- curAct.a41.actPassIndex = in.readUint16BE();
- curAct.a41.actFailIndex = in.readUint16BE();
+ curAct._a41._timer = in.readSint16BE();
+ curAct._a41._bonusIndex = in.readSint16BE();
+ curAct._a41._actPassIndex = in.readUint16BE();
+ curAct._a41._actFailIndex = in.readUint16BE();
break;
case TEXT_TAKE: // 42
- curAct.a42.timer = in.readSint16BE();
- curAct.a42.objIndex = in.readSint16BE();
+ curAct._a42._timer = in.readSint16BE();
+ curAct._a42._objIndex = in.readSint16BE();
break;
case YESNO: // 43
- curAct.a43.timer = in.readSint16BE();
- curAct.a43.promptIndex = in.readSint16BE();
- curAct.a43.actYesIndex = in.readUint16BE();
- curAct.a43.actNoIndex = in.readUint16BE();
+ curAct._a43._timer = in.readSint16BE();
+ curAct._a43._promptIndex = in.readSint16BE();
+ curAct._a43._actYesIndex = in.readUint16BE();
+ curAct._a43._actNoIndex = in.readUint16BE();
break;
case STOP_ROUTE: // 44
- curAct.a44.timer = in.readSint16BE();
+ curAct._a44._timer = in.readSint16BE();
break;
case COND_ROUTE: // 45
- curAct.a45.timer = in.readSint16BE();
- curAct.a45.routeIndex = in.readSint16BE();
- curAct.a45.actPassIndex = in.readUint16BE();
- curAct.a45.actFailIndex = in.readUint16BE();
+ curAct._a45._timer = in.readSint16BE();
+ curAct._a45._routeIndex = in.readSint16BE();
+ curAct._a45._actPassIndex = in.readUint16BE();
+ curAct._a45._actFailIndex = in.readUint16BE();
break;
case INIT_JUMPEXIT: // 46
- curAct.a46.timer = in.readSint16BE();
- curAct.a46.jumpExitFl = (in.readByte() == 1);
+ curAct._a46._timer = in.readSint16BE();
+ curAct._a46._jumpExitFl = (in.readByte() == 1);
break;
case INIT_VIEW: // 47
- curAct.a47.timer = in.readSint16BE();
- curAct.a47.objIndex = in.readSint16BE();
- curAct.a47.viewx = in.readSint16BE();
- curAct.a47.viewy = in.readSint16BE();
- curAct.a47.direction = in.readSint16BE();
+ curAct._a47._timer = in.readSint16BE();
+ curAct._a47._objIndex = in.readSint16BE();
+ curAct._a47._viewx = in.readSint16BE();
+ curAct._a47._viewy = in.readSint16BE();
+ curAct._a47._direction = in.readSint16BE();
break;
case INIT_OBJ_FRAME: // 48
- curAct.a48.timer = in.readSint16BE();
- curAct.a48.objIndex = in.readSint16BE();
- curAct.a48.seqIndex = in.readSint16BE();
- curAct.a48.frameIndex = in.readSint16BE();
+ curAct._a48._timer = in.readSint16BE();
+ curAct._a48._objIndex = in.readSint16BE();
+ curAct._a48._seqIndex = in.readSint16BE();
+ curAct._a48._frameIndex = in.readSint16BE();
break;
case OLD_SONG: //49
- curAct.a49.timer = in.readSint16BE();
- curAct.a49.songIndex = in.readUint16BE();
+ curAct._a49._timer = in.readSint16BE();
+ curAct._a49._songIndex = in.readUint16BE();
break;
default:
- error("Engine - Unknown action type encountered: %d", curAct.a0.actType);
+ error("Engine - Unknown action type encountered: %d", curAct._a0._actType);
}
}
@@ -553,32 +553,32 @@ void Scheduler::readAct(Common::ReadStream &in, act &curAct) {
void Scheduler::loadActListArr(Common::ReadStream &in) {
debugC(6, kDebugSchedule, "loadActListArr(&in)");
- act tmpAct;
+ Act tmpAct;
int numElem, numSubElem;
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
numElem = in.readUint16BE();
if (varnt == _vm->_gameVariant) {
_actListArrSize = numElem;
- _actListArr = (act **)malloc(sizeof(act *) * _actListArrSize);
+ _actListArr = (Act **)malloc(sizeof(Act *) * _actListArrSize);
}
for (int i = 0; i < numElem; i++) {
numSubElem = in.readUint16BE();
if (varnt == _vm->_gameVariant)
- _actListArr[i] = (act *)malloc(sizeof(act) * (numSubElem + 1));
+ _actListArr[i] = (Act *)malloc(sizeof(Act) * (numSubElem + 1));
for (int j = 0; j < numSubElem; j++) {
if (varnt == _vm->_gameVariant) {
readAct(in, _actListArr[i][j]);
} else {
readAct(in, tmpAct);
- if (tmpAct.a0.actType == PROMPT)
- free(tmpAct.a3.responsePtr);
+ if (tmpAct._a0._actType == PROMPT)
+ free(tmpAct._a3._responsePtr);
}
}
if (varnt == _vm->_gameVariant)
- _actListArr[i][numSubElem].a0.actType = ANULL;
+ _actListArr[i][numSubElem]._a0._actType = ANULL;
}
}
}
@@ -626,9 +626,9 @@ void Scheduler::freeScheduler() {
if (_actListArr) {
for (int i = 0; i < _actListArrSize; i++) {
- for (int j = 0; _actListArr[i][j].a0.actType != ANULL; j++) {
- if (_actListArr[i][j].a0.actType == PROMPT)
- free(_actListArr[i][j].a3.responsePtr);
+ for (int j = 0; _actListArr[i][j]._a0._actType != ANULL; j++) {
+ if (_actListArr[i][j]._a0._actType == PROMPT)
+ free(_actListArr[i][j]._a3._responsePtr);
}
free(_actListArr[i]);
}
@@ -656,32 +656,32 @@ void Scheduler::screenActions(const int screenNum) {
void Scheduler::processMaze(const int x1, const int x2, const int y1, const int y2) {
debugC(1, kDebugSchedule, "processMaze");
- if (x1 < _vm->_maze.x1) {
+ if (x1 < _vm->_maze._x1) {
// Exit west
- _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - 1;
- _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze.x2 - kShiftSize - (x2 - x1);
- _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->y;
+ _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screenPtr - 1;
+ _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x2 - kShiftSize - (x2 - x1);
+ _actListArr[_alNewscrIndex][0]._a2._y = _vm->_hero->_y;
_vm->_route->resetRoute();
insertActionList(_alNewscrIndex);
- } else if (x2 > _vm->_maze.x2) {
+ } else if (x2 > _vm->_maze._x2) {
// Exit east
- _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + 1;
- _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze.x1 + kShiftSize;
- _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->y;
+ _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screenPtr + 1;
+ _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x1 + kShiftSize;
+ _actListArr[_alNewscrIndex][0]._a2._y = _vm->_hero->_y;
_vm->_route->resetRoute();
insertActionList(_alNewscrIndex);
- } else if (y1 < _vm->_maze.y1 - kShiftSize) {
+ } else if (y1 < _vm->_maze._y1 - kShiftSize) {
// Exit north
- _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - _vm->_maze.size;
- _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze.x3;
- _actListArr[_alNewscrIndex][0].a2.y = _vm->_maze.y2 - kShiftSize - (y2 - y1);
+ _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screenPtr - _vm->_maze._size;
+ _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x3;
+ _actListArr[_alNewscrIndex][0]._a2._y = _vm->_maze._y2 - kShiftSize - (y2 - y1);
_vm->_route->resetRoute();
insertActionList(_alNewscrIndex);
- } else if (y2 > _vm->_maze.y2 - kShiftSize / 2) {
+ } else if (y2 > _vm->_maze._y2 - kShiftSize / 2) {
// Exit south
- _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + _vm->_maze.size;
- _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze.x4;
- _actListArr[_alNewscrIndex][0].a2.y = _vm->_maze.y1 + kShiftSize;
+ _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screenPtr + _vm->_maze._size;
+ _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x4;
+ _actListArr[_alNewscrIndex][0]._a2._y = _vm->_maze._y1 + kShiftSize;
_vm->_route->resetRoute();
insertActionList(_alNewscrIndex);
}
@@ -708,17 +708,17 @@ void Scheduler::saveEvents(Common::WriteStream *f) {
// Convert event ptrs to indexes
for (int16 i = 0; i < kMaxEvents; i++) {
- event_t *wrkEvent = &_events[i];
+ Event *wrkEvent = &_events[i];
// fix up action pointer (to do better)
int16 index, subElem;
- findAction(wrkEvent->action, &index, &subElem);
+ findAction(wrkEvent->_action, &index, &subElem);
f->writeSint16BE(index);
f->writeSint16BE(subElem);
- f->writeByte((wrkEvent->localActionFl) ? 1 : 0);
- f->writeUint32BE(wrkEvent->time);
- f->writeSint16BE((wrkEvent->prevEvent == 0) ? -1 : (wrkEvent->prevEvent - _events));
- f->writeSint16BE((wrkEvent->nextEvent == 0) ? -1 : (wrkEvent->nextEvent - _events));
+ f->writeByte((wrkEvent->_localActionFl) ? 1 : 0);
+ f->writeUint32BE(wrkEvent->_time);
+ f->writeSint16BE((wrkEvent->_prevEvent == 0) ? -1 : (wrkEvent->_prevEvent - _events));
+ f->writeSint16BE((wrkEvent->_nextEvent == 0) ? -1 : (wrkEvent->_nextEvent - _events));
}
}
@@ -738,7 +738,7 @@ void Scheduler::restoreActions(Common::ReadStream *f) {
int16 Scheduler::calcMaxPoints() const {
int16 tmpScore = 0;
for (int i = 0; i < _numBonuses; i++)
- tmpScore += _points[i].score;
+ tmpScore += _points[i]._score;
return tmpScore;
}
@@ -752,282 +752,282 @@ void Scheduler::saveActions(Common::WriteStream *f) const {
for (int i = 0; i < _actListArrSize; i++) {
// write all the sub elems data
- for (nbrSubElem = 1; _actListArr[i][nbrSubElem - 1].a0.actType != ANULL; nbrSubElem++)
+ for (nbrSubElem = 1; _actListArr[i][nbrSubElem - 1]._a0._actType != ANULL; nbrSubElem++)
;
f->writeUint16BE(nbrSubElem);
for (int j = 0; j < nbrSubElem; j++) {
- subElemType = _actListArr[i][j].a0.actType;
+ subElemType = _actListArr[i][j]._a0._actType;
f->writeByte(subElemType);
switch (subElemType) {
case ANULL: // -1
break;
case ASCHEDULE: // 0
- f->writeSint16BE(_actListArr[i][j].a0.timer);
- f->writeUint16BE(_actListArr[i][j].a0.actIndex);
+ f->writeSint16BE(_actListArr[i][j]._a0._timer);
+ f->writeUint16BE(_actListArr[i][j]._a0._actIndex);
break;
case START_OBJ: // 1
- f->writeSint16BE(_actListArr[i][j].a1.timer);
- f->writeSint16BE(_actListArr[i][j].a1.objIndex);
- f->writeSint16BE(_actListArr[i][j].a1.cycleNumb);
- f->writeByte(_actListArr[i][j].a1.cycle);
+ f->writeSint16BE(_actListArr[i][j]._a1._timer);
+ f->writeSint16BE(_actListArr[i][j]._a1._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a1._cycleNumb);
+ f->writeByte(_actListArr[i][j]._a1._cycle);
break;
case INIT_OBJXY: // 2
- f->writeSint16BE(_actListArr[i][j].a2.timer);
- f->writeSint16BE(_actListArr[i][j].a2.objIndex);
- f->writeSint16BE(_actListArr[i][j].a2.x);
- f->writeSint16BE(_actListArr[i][j].a2.y);
+ f->writeSint16BE(_actListArr[i][j]._a2._timer);
+ f->writeSint16BE(_actListArr[i][j]._a2._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a2._x);
+ f->writeSint16BE(_actListArr[i][j]._a2._y);
break;
case PROMPT: // 3
- f->writeSint16BE(_actListArr[i][j].a3.timer);
- f->writeSint16BE(_actListArr[i][j].a3.promptIndex);
- for (nbrCpt = 0; _actListArr[i][j].a3.responsePtr[nbrCpt] != -1; nbrCpt++)
+ f->writeSint16BE(_actListArr[i][j]._a3._timer);
+ f->writeSint16BE(_actListArr[i][j]._a3._promptIndex);
+ for (nbrCpt = 0; _actListArr[i][j]._a3._responsePtr[nbrCpt] != -1; nbrCpt++)
;
nbrCpt++;
f->writeUint16BE(nbrCpt);
for (int k = 0; k < nbrCpt; k++)
- f->writeSint16BE(_actListArr[i][j].a3.responsePtr[k]);
- f->writeUint16BE(_actListArr[i][j].a3.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a3.actFailIndex);
- f->writeByte((_actListArr[i][j].a3.encodedFl) ? 1 : 0);
+ f->writeSint16BE(_actListArr[i][j]._a3._responsePtr[k]);
+ f->writeUint16BE(_actListArr[i][j]._a3._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a3._actFailIndex);
+ f->writeByte((_actListArr[i][j]._a3._encodedFl) ? 1 : 0);
break;
case BKGD_COLOR: // 4
- f->writeSint16BE(_actListArr[i][j].a4.timer);
- f->writeUint32BE(_actListArr[i][j].a4.newBackgroundColor);
+ f->writeSint16BE(_actListArr[i][j]._a4._timer);
+ f->writeUint32BE(_actListArr[i][j]._a4._newBackgroundColor);
break;
case INIT_OBJVXY: // 5
- f->writeSint16BE(_actListArr[i][j].a5.timer);
- f->writeSint16BE(_actListArr[i][j].a5.objIndex);
- f->writeSint16BE(_actListArr[i][j].a5.vx);
- f->writeSint16BE(_actListArr[i][j].a5.vy);
+ f->writeSint16BE(_actListArr[i][j]._a5._timer);
+ f->writeSint16BE(_actListArr[i][j]._a5._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a5._vx);
+ f->writeSint16BE(_actListArr[i][j]._a5._vy);
break;
case INIT_CARRY: // 6
- f->writeSint16BE(_actListArr[i][j].a6.timer);
- f->writeSint16BE(_actListArr[i][j].a6.objIndex);
- f->writeByte((_actListArr[i][j].a6.carriedFl) ? 1 : 0);
+ f->writeSint16BE(_actListArr[i][j]._a6._timer);
+ f->writeSint16BE(_actListArr[i][j]._a6._objIndex);
+ f->writeByte((_actListArr[i][j]._a6._carriedFl) ? 1 : 0);
break;
case INIT_HF_COORD: // 7
- f->writeSint16BE(_actListArr[i][j].a7.timer);
- f->writeSint16BE(_actListArr[i][j].a7.objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a7._timer);
+ f->writeSint16BE(_actListArr[i][j]._a7._objIndex);
break;
case NEW_SCREEN: // 8
- f->writeSint16BE(_actListArr[i][j].a8.timer);
- f->writeSint16BE(_actListArr[i][j].a8.screenIndex);
+ f->writeSint16BE(_actListArr[i][j]._a8._timer);
+ f->writeSint16BE(_actListArr[i][j]._a8._screenIndex);
break;
case INIT_OBJSTATE: // 9
- f->writeSint16BE(_actListArr[i][j].a9.timer);
- f->writeSint16BE(_actListArr[i][j].a9.objIndex);
- f->writeByte(_actListArr[i][j].a9.newState);
+ f->writeSint16BE(_actListArr[i][j]._a9._timer);
+ f->writeSint16BE(_actListArr[i][j]._a9._objIndex);
+ f->writeByte(_actListArr[i][j]._a9._newState);
break;
case INIT_PATH: // 10
- f->writeSint16BE(_actListArr[i][j].a10.timer);
- f->writeSint16BE(_actListArr[i][j].a10.objIndex);
- f->writeSint16BE(_actListArr[i][j].a10.newPathType);
- f->writeByte(_actListArr[i][j].a10.vxPath);
- f->writeByte(_actListArr[i][j].a10.vyPath);
+ f->writeSint16BE(_actListArr[i][j]._a10._timer);
+ f->writeSint16BE(_actListArr[i][j]._a10._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a10._newPathType);
+ f->writeByte(_actListArr[i][j]._a10._vxPath);
+ f->writeByte(_actListArr[i][j]._a10._vyPath);
break;
case COND_R: // 11
- f->writeSint16BE(_actListArr[i][j].a11.timer);
- f->writeSint16BE(_actListArr[i][j].a11.objIndex);
- f->writeByte(_actListArr[i][j].a11.stateReq);
- f->writeUint16BE(_actListArr[i][j].a11.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a11.actFailIndex);
+ f->writeSint16BE(_actListArr[i][j]._a11._timer);
+ f->writeSint16BE(_actListArr[i][j]._a11._objIndex);
+ f->writeByte(_actListArr[i][j]._a11._stateReq);
+ f->writeUint16BE(_actListArr[i][j]._a11._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a11._actFailIndex);
break;
case TEXT: // 12
- f->writeSint16BE(_actListArr[i][j].a12.timer);
- f->writeSint16BE(_actListArr[i][j].a12.stringIndex);
+ f->writeSint16BE(_actListArr[i][j]._a12._timer);
+ f->writeSint16BE(_actListArr[i][j]._a12._stringIndex);
break;
case SWAP_IMAGES: // 13
- f->writeSint16BE(_actListArr[i][j].a13.timer);
- f->writeSint16BE(_actListArr[i][j].a13.objIndex1);
- f->writeSint16BE(_actListArr[i][j].a13.objIndex2);
+ f->writeSint16BE(_actListArr[i][j]._a13._timer);
+ f->writeSint16BE(_actListArr[i][j]._a13._objIndex1);
+ f->writeSint16BE(_actListArr[i][j]._a13._objIndex2);
break;
case COND_SCR: // 14
- f->writeSint16BE(_actListArr[i][j].a14.timer);
- f->writeSint16BE(_actListArr[i][j].a14.objIndex);
- f->writeSint16BE(_actListArr[i][j].a14.screenReq);
- f->writeUint16BE(_actListArr[i][j].a14.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a14.actFailIndex);
+ f->writeSint16BE(_actListArr[i][j]._a14._timer);
+ f->writeSint16BE(_actListArr[i][j]._a14._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a14._screenReq);
+ f->writeUint16BE(_actListArr[i][j]._a14._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a14._actFailIndex);
break;
case AUTOPILOT: // 15
- f->writeSint16BE(_actListArr[i][j].a15.timer);
- f->writeSint16BE(_actListArr[i][j].a15.objIndex1);
- f->writeSint16BE(_actListArr[i][j].a15.objIndex2);
- f->writeByte(_actListArr[i][j].a15.dx);
- f->writeByte(_actListArr[i][j].a15.dy);
+ f->writeSint16BE(_actListArr[i][j]._a15._timer);
+ f->writeSint16BE(_actListArr[i][j]._a15._objIndex1);
+ f->writeSint16BE(_actListArr[i][j]._a15._objIndex2);
+ f->writeByte(_actListArr[i][j]._a15._dx);
+ f->writeByte(_actListArr[i][j]._a15._dy);
break;
case INIT_OBJ_SEQ: // 16
- f->writeSint16BE(_actListArr[i][j].a16.timer);
- f->writeSint16BE(_actListArr[i][j].a16.objIndex);
- f->writeSint16BE(_actListArr[i][j].a16.seqIndex);
+ f->writeSint16BE(_actListArr[i][j]._a16._timer);
+ f->writeSint16BE(_actListArr[i][j]._a16._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a16._seqIndex);
break;
case SET_STATE_BITS: // 17
- f->writeSint16BE(_actListArr[i][j].a17.timer);
- f->writeSint16BE(_actListArr[i][j].a17.objIndex);
- f->writeSint16BE(_actListArr[i][j].a17.stateMask);
+ f->writeSint16BE(_actListArr[i][j]._a17._timer);
+ f->writeSint16BE(_actListArr[i][j]._a17._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a17._stateMask);
break;
case CLEAR_STATE_BITS: // 18
- f->writeSint16BE(_actListArr[i][j].a18.timer);
- f->writeSint16BE(_actListArr[i][j].a18.objIndex);
- f->writeSint16BE(_actListArr[i][j].a18.stateMask);
+ f->writeSint16BE(_actListArr[i][j]._a18._timer);
+ f->writeSint16BE(_actListArr[i][j]._a18._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a18._stateMask);
break;
case TEST_STATE_BITS: // 19
- f->writeSint16BE(_actListArr[i][j].a19.timer);
- f->writeSint16BE(_actListArr[i][j].a19.objIndex);
- f->writeSint16BE(_actListArr[i][j].a19.stateMask);
- f->writeUint16BE(_actListArr[i][j].a19.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a19.actFailIndex);
+ f->writeSint16BE(_actListArr[i][j]._a19._timer);
+ f->writeSint16BE(_actListArr[i][j]._a19._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a19._stateMask);
+ f->writeUint16BE(_actListArr[i][j]._a19._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a19._actFailIndex);
break;
case DEL_EVENTS: // 20
- f->writeSint16BE(_actListArr[i][j].a20.timer);
- f->writeByte(_actListArr[i][j].a20.actTypeDel);
+ f->writeSint16BE(_actListArr[i][j]._a20._timer);
+ f->writeByte(_actListArr[i][j]._a20._actTypeDel);
break;
case GAMEOVER: // 21
- f->writeSint16BE(_actListArr[i][j].a21.timer);
+ f->writeSint16BE(_actListArr[i][j]._a21._timer);
break;
case INIT_HH_COORD: // 22
- f->writeSint16BE(_actListArr[i][j].a22.timer);
- f->writeSint16BE(_actListArr[i][j].a22.objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a22._timer);
+ f->writeSint16BE(_actListArr[i][j]._a22._objIndex);
break;
case EXIT: // 23
- f->writeSint16BE(_actListArr[i][j].a23.timer);
+ f->writeSint16BE(_actListArr[i][j]._a23._timer);
break;
case BONUS: // 24
- f->writeSint16BE(_actListArr[i][j].a24.timer);
- f->writeSint16BE(_actListArr[i][j].a24.pointIndex);
+ f->writeSint16BE(_actListArr[i][j]._a24._timer);
+ f->writeSint16BE(_actListArr[i][j]._a24._pointIndex);
break;
case COND_BOX: // 25
- f->writeSint16BE(_actListArr[i][j].a25.timer);
- f->writeSint16BE(_actListArr[i][j].a25.objIndex);
- f->writeSint16BE(_actListArr[i][j].a25.x1);
- f->writeSint16BE(_actListArr[i][j].a25.y1);
- f->writeSint16BE(_actListArr[i][j].a25.x2);
- f->writeSint16BE(_actListArr[i][j].a25.y2);
- f->writeUint16BE(_actListArr[i][j].a25.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a25.actFailIndex);
+ f->writeSint16BE(_actListArr[i][j]._a25._timer);
+ f->writeSint16BE(_actListArr[i][j]._a25._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a25._x1);
+ f->writeSint16BE(_actListArr[i][j]._a25._y1);
+ f->writeSint16BE(_actListArr[i][j]._a25._x2);
+ f->writeSint16BE(_actListArr[i][j]._a25._y2);
+ f->writeUint16BE(_actListArr[i][j]._a25._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a25._actFailIndex);
break;
case SOUND: // 26
- f->writeSint16BE(_actListArr[i][j].a26.timer);
- f->writeSint16BE(_actListArr[i][j].a26.soundIndex);
+ f->writeSint16BE(_actListArr[i][j]._a26._timer);
+ f->writeSint16BE(_actListArr[i][j]._a26._soundIndex);
break;
case ADD_SCORE: // 27
- f->writeSint16BE(_actListArr[i][j].a27.timer);
- f->writeSint16BE(_actListArr[i][j].a27.objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a27._timer);
+ f->writeSint16BE(_actListArr[i][j]._a27._objIndex);
break;
case SUB_SCORE: // 28
- f->writeSint16BE(_actListArr[i][j].a28.timer);
- f->writeSint16BE(_actListArr[i][j].a28.objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a28._timer);
+ f->writeSint16BE(_actListArr[i][j]._a28._objIndex);
break;
case COND_CARRY: // 29
- f->writeSint16BE(_actListArr[i][j].a29.timer);
- f->writeSint16BE(_actListArr[i][j].a29.objIndex);
- f->writeUint16BE(_actListArr[i][j].a29.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a29.actFailIndex);
+ f->writeSint16BE(_actListArr[i][j]._a29._timer);
+ f->writeSint16BE(_actListArr[i][j]._a29._objIndex);
+ f->writeUint16BE(_actListArr[i][j]._a29._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a29._actFailIndex);
break;
case INIT_MAZE: // 30
- f->writeSint16BE(_actListArr[i][j].a30.timer);
- f->writeByte(_actListArr[i][j].a30.mazeSize);
- f->writeSint16BE(_actListArr[i][j].a30.x1);
- f->writeSint16BE(_actListArr[i][j].a30.y1);
- f->writeSint16BE(_actListArr[i][j].a30.x2);
- f->writeSint16BE(_actListArr[i][j].a30.y2);
- f->writeSint16BE(_actListArr[i][j].a30.x3);
- f->writeSint16BE(_actListArr[i][j].a30.x4);
- f->writeByte(_actListArr[i][j].a30.firstScreenIndex);
+ f->writeSint16BE(_actListArr[i][j]._a30._timer);
+ f->writeByte(_actListArr[i][j]._a30._mazeSize);
+ f->writeSint16BE(_actListArr[i][j]._a30._x1);
+ f->writeSint16BE(_actListArr[i][j]._a30._y1);
+ f->writeSint16BE(_actListArr[i][j]._a30._x2);
+ f->writeSint16BE(_actListArr[i][j]._a30._y2);
+ f->writeSint16BE(_actListArr[i][j]._a30._x3);
+ f->writeSint16BE(_actListArr[i][j]._a30._x4);
+ f->writeByte(_actListArr[i][j]._a30._firstScreenIndex);
break;
case EXIT_MAZE: // 31
- f->writeSint16BE(_actListArr[i][j].a31.timer);
+ f->writeSint16BE(_actListArr[i][j]._a31._timer);
break;
case INIT_PRIORITY: // 32
- f->writeSint16BE(_actListArr[i][j].a32.timer);
- f->writeSint16BE(_actListArr[i][j].a32.objIndex);
- f->writeByte(_actListArr[i][j].a32.priority);
+ f->writeSint16BE(_actListArr[i][j]._a32._timer);
+ f->writeSint16BE(_actListArr[i][j]._a32._objIndex);
+ f->writeByte(_actListArr[i][j]._a32._priority);
break;
case INIT_SCREEN: // 33
- f->writeSint16BE(_actListArr[i][j].a33.timer);
- f->writeSint16BE(_actListArr[i][j].a33.objIndex);
- f->writeSint16BE(_actListArr[i][j].a33.screenIndex);
+ f->writeSint16BE(_actListArr[i][j]._a33._timer);
+ f->writeSint16BE(_actListArr[i][j]._a33._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a33._screenIndex);
break;
case AGSCHEDULE: // 34
- f->writeSint16BE(_actListArr[i][j].a34.timer);
- f->writeUint16BE(_actListArr[i][j].a34.actIndex);
+ f->writeSint16BE(_actListArr[i][j]._a34._timer);
+ f->writeUint16BE(_actListArr[i][j]._a34._actIndex);
break;
case REMAPPAL: // 35
- f->writeSint16BE(_actListArr[i][j].a35.timer);
- f->writeSint16BE(_actListArr[i][j].a35.oldColorIndex);
- f->writeSint16BE(_actListArr[i][j].a35.newColorIndex);
+ f->writeSint16BE(_actListArr[i][j]._a35._timer);
+ f->writeSint16BE(_actListArr[i][j]._a35._oldColorIndex);
+ f->writeSint16BE(_actListArr[i][j]._a35._newColorIndex);
break;
case COND_NOUN: // 36
- f->writeSint16BE(_actListArr[i][j].a36.timer);
- f->writeUint16BE(_actListArr[i][j].a36.nounIndex);
- f->writeUint16BE(_actListArr[i][j].a36.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a36.actFailIndex);
+ f->writeSint16BE(_actListArr[i][j]._a36._timer);
+ f->writeUint16BE(_actListArr[i][j]._a36._nounIndex);
+ f->writeUint16BE(_actListArr[i][j]._a36._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a36._actFailIndex);
break;
case SCREEN_STATE: // 37
- f->writeSint16BE(_actListArr[i][j].a37.timer);
- f->writeSint16BE(_actListArr[i][j].a37.screenIndex);
- f->writeByte(_actListArr[i][j].a37.newState);
+ f->writeSint16BE(_actListArr[i][j]._a37._timer);
+ f->writeSint16BE(_actListArr[i][j]._a37._screenIndex);
+ f->writeByte(_actListArr[i][j]._a37._newState);
break;
case INIT_LIPS: // 38
- f->writeSint16BE(_actListArr[i][j].a38.timer);
- f->writeSint16BE(_actListArr[i][j].a38.lipsObjIndex);
- f->writeSint16BE(_actListArr[i][j].a38.objIndex);
- f->writeByte(_actListArr[i][j].a38.dxLips);
- f->writeByte(_actListArr[i][j].a38.dyLips);
+ f->writeSint16BE(_actListArr[i][j]._a38._timer);
+ f->writeSint16BE(_actListArr[i][j]._a38._lipsObjIndex);
+ f->writeSint16BE(_actListArr[i][j]._a38._objIndex);
+ f->writeByte(_actListArr[i][j]._a38._dxLips);
+ f->writeByte(_actListArr[i][j]._a38._dyLips);
break;
case INIT_STORY_MODE: // 39
- f->writeSint16BE(_actListArr[i][j].a39.timer);
- f->writeByte((_actListArr[i][j].a39.storyModeFl) ? 1 : 0);
+ f->writeSint16BE(_actListArr[i][j]._a39._timer);
+ f->writeByte((_actListArr[i][j]._a39._storyModeFl) ? 1 : 0);
break;
case WARN: // 40
- f->writeSint16BE(_actListArr[i][j].a40.timer);
- f->writeSint16BE(_actListArr[i][j].a40.stringIndex);
+ f->writeSint16BE(_actListArr[i][j]._a40._timer);
+ f->writeSint16BE(_actListArr[i][j]._a40._stringIndex);
break;
case COND_BONUS: // 41
- f->writeSint16BE(_actListArr[i][j].a41.timer);
- f->writeSint16BE(_actListArr[i][j].a41.BonusIndex);
- f->writeUint16BE(_actListArr[i][j].a41.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a41.actFailIndex);
+ f->writeSint16BE(_actListArr[i][j]._a41._timer);
+ f->writeSint16BE(_actListArr[i][j]._a41._bonusIndex);
+ f->writeUint16BE(_actListArr[i][j]._a41._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a41._actFailIndex);
break;
case TEXT_TAKE: // 42
- f->writeSint16BE(_actListArr[i][j].a42.timer);
- f->writeSint16BE(_actListArr[i][j].a42.objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a42._timer);
+ f->writeSint16BE(_actListArr[i][j]._a42._objIndex);
break;
case YESNO: // 43
- f->writeSint16BE(_actListArr[i][j].a43.timer);
- f->writeSint16BE(_actListArr[i][j].a43.promptIndex);
- f->writeUint16BE(_actListArr[i][j].a43.actYesIndex);
- f->writeUint16BE(_actListArr[i][j].a43.actNoIndex);
+ f->writeSint16BE(_actListArr[i][j]._a43._timer);
+ f->writeSint16BE(_actListArr[i][j]._a43._promptIndex);
+ f->writeUint16BE(_actListArr[i][j]._a43._actYesIndex);
+ f->writeUint16BE(_actListArr[i][j]._a43._actNoIndex);
break;
case STOP_ROUTE: // 44
- f->writeSint16BE(_actListArr[i][j].a44.timer);
+ f->writeSint16BE(_actListArr[i][j]._a44._timer);
break;
case COND_ROUTE: // 45
- f->writeSint16BE(_actListArr[i][j].a45.timer);
- f->writeSint16BE(_actListArr[i][j].a45.routeIndex);
- f->writeUint16BE(_actListArr[i][j].a45.actPassIndex);
- f->writeUint16BE(_actListArr[i][j].a45.actFailIndex);
+ f->writeSint16BE(_actListArr[i][j]._a45._timer);
+ f->writeSint16BE(_actListArr[i][j]._a45._routeIndex);
+ f->writeUint16BE(_actListArr[i][j]._a45._actPassIndex);
+ f->writeUint16BE(_actListArr[i][j]._a45._actFailIndex);
break;
case INIT_JUMPEXIT: // 46
- f->writeSint16BE(_actListArr[i][j].a46.timer);
- f->writeByte((_actListArr[i][j].a46.jumpExitFl) ? 1 : 0);
+ f->writeSint16BE(_actListArr[i][j]._a46._timer);
+ f->writeByte((_actListArr[i][j]._a46._jumpExitFl) ? 1 : 0);
break;
case INIT_VIEW: // 47
- f->writeSint16BE(_actListArr[i][j].a47.timer);
- f->writeSint16BE(_actListArr[i][j].a47.objIndex);
- f->writeSint16BE(_actListArr[i][j].a47.viewx);
- f->writeSint16BE(_actListArr[i][j].a47.viewy);
- f->writeSint16BE(_actListArr[i][j].a47.direction);
+ f->writeSint16BE(_actListArr[i][j]._a47._timer);
+ f->writeSint16BE(_actListArr[i][j]._a47._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a47._viewx);
+ f->writeSint16BE(_actListArr[i][j]._a47._viewy);
+ f->writeSint16BE(_actListArr[i][j]._a47._direction);
break;
case INIT_OBJ_FRAME: // 48
- f->writeSint16BE(_actListArr[i][j].a48.timer);
- f->writeSint16BE(_actListArr[i][j].a48.objIndex);
- f->writeSint16BE(_actListArr[i][j].a48.seqIndex);
- f->writeSint16BE(_actListArr[i][j].a48.frameIndex);
+ f->writeSint16BE(_actListArr[i][j]._a48._timer);
+ f->writeSint16BE(_actListArr[i][j]._a48._objIndex);
+ f->writeSint16BE(_actListArr[i][j]._a48._seqIndex);
+ f->writeSint16BE(_actListArr[i][j]._a48._frameIndex);
break;
case OLD_SONG: // 49, Added by Strangerke for DOS versions
- f->writeSint16BE(_actListArr[i][j].a49.timer);
- f->writeUint16BE(_actListArr[i][j].a49.songIndex);
+ f->writeSint16BE(_actListArr[i][j]._a49._timer);
+ f->writeUint16BE(_actListArr[i][j]._a49._songIndex);
break;
default:
error("Unknown action %d", subElemType);
@@ -1039,7 +1039,7 @@ void Scheduler::saveActions(Common::WriteStream *f) const {
/*
* Find the index in the action list to be able to serialize the action to save game
*/
-void Scheduler::findAction(const act* action, int16* index, int16* subElem) {
+void Scheduler::findAction(const Act *action, int16 *index, int16 *subElem) {
assert(index && subElem);
if (!action) {
@@ -1057,7 +1057,7 @@ void Scheduler::findAction(const act* action, int16* index, int16* subElem) {
return;
}
j++;
- } while (_actListArr[i][j-1].a0.actType != ANULL);
+ } while (_actListArr[i][j-1]._a0._actType != ANULL);
}
// action not found ??
assert(0);
@@ -1090,10 +1090,10 @@ void Scheduler::restoreSchedulerData(Common::ReadStream *in) {
void Scheduler::restoreEvents(Common::ReadStream *f) {
debugC(1, kDebugSchedule, "restoreEvents");
- uint32 saveTime = f->readUint32BE(); // time of save
- int16 freeIndex = f->readSint16BE(); // Free list index
- int16 headIndex = f->readSint16BE(); // Head of list index
- int16 tailIndex = f->readSint16BE(); // Tail of list index
+ uint32 saveTime = f->readUint32BE(); // time of save
+ int16 freeIndex = f->readSint16BE(); // Free list index
+ int16 headIndex = f->readSint16BE(); // Head of list index
+ int16 tailIndex = f->readSint16BE(); // Tail of list index
// Restore events indexes to pointers
for (int i = 0; i < kMaxEvents; i++) {
@@ -1102,18 +1102,18 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
// fix up action pointer (to do better)
if ((index == -1) && (subElem == -1))
- _events[i].action = 0;
+ _events[i]._action = 0;
else
- _events[i].action = (act *)&_actListArr[index][subElem];
+ _events[i]._action = (Act *)&_actListArr[index][subElem];
- _events[i].localActionFl = (f->readByte() == 1) ? true : false;
- _events[i].time = f->readUint32BE();
+ _events[i]._localActionFl = (f->readByte() == 1) ? true : false;
+ _events[i]._time = f->readUint32BE();
int16 prevIndex = f->readSint16BE();
int16 nextIndex = f->readSint16BE();
- _events[i].prevEvent = (prevIndex == -1) ? (event_t *)0 : &_events[prevIndex];
- _events[i].nextEvent = (nextIndex == -1) ? (event_t *)0 : &_events[nextIndex];
+ _events[i]._prevEvent = (prevIndex == -1) ? (Event *)0 : &_events[prevIndex];
+ _events[i]._nextEvent = (nextIndex == -1) ? (Event *)0 : &_events[nextIndex];
}
_freeEvent = (freeIndex == -1) ? 0 : &_events[freeIndex];
_headEvent = (headIndex == -1) ? 0 : &_events[headIndex];
@@ -1121,10 +1121,10 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
// Adjust times to fit our time
uint32 curTime = getTicks();
- event_t *wrkEvent = _headEvent; // The earliest event
- while (wrkEvent) { // While mature events found
- wrkEvent->time = wrkEvent->time - saveTime + curTime;
- wrkEvent = wrkEvent->nextEvent;
+ Event *wrkEvent = _headEvent; // The earliest event
+ while (wrkEvent) { // While mature events found
+ wrkEvent->_time = wrkEvent->_time - saveTime + curTime;
+ wrkEvent = wrkEvent->_nextEvent;
}
}
@@ -1132,53 +1132,53 @@ void Scheduler::restoreEvents(Common::ReadStream *f) {
* Insert the action pointed to by p into the timer event queue
* The queue goes from head (earliest) to tail (latest) timewise
*/
-void Scheduler::insertAction(act *action) {
- debugC(1, kDebugSchedule, "insertAction() - Action type A%d", action->a0.actType);
+void Scheduler::insertAction(Act *action) {
+ debugC(1, kDebugSchedule, "insertAction() - Action type A%d", action->_a0._actType);
// First, get and initialize the event structure
- event_t *curEvent = getQueue();
- curEvent->action = action;
- switch (action->a0.actType) { // Assign whether local or global
+ Event *curEvent = getQueue();
+ curEvent->_action = action;
+ switch (action->_a0._actType) { // Assign whether local or global
case AGSCHEDULE:
- curEvent->localActionFl = false; // Lasts over a new screen
+ curEvent->_localActionFl = false; // Lasts over a new screen
break;
// Workaround: When dying, switch to storyMode in order to block the keyboard.
case GAMEOVER:
- _vm->getGameStatus().storyModeFl = true;
+ _vm->getGameStatus()._storyModeFl = true;
// No break on purpose
default:
- curEvent->localActionFl = true; // Rest are for current screen only
+ curEvent->_localActionFl = true; // Rest are for current screen only
break;
}
- curEvent->time = action->a0.timer + getTicks(); // Convert rel to abs time
+ curEvent->_time = action->_a0._timer + getTicks(); // Convert rel to abs time
// Now find the place to insert the event
- if (!_tailEvent) { // Empty queue
+ if (!_tailEvent) { // Empty queue
_tailEvent = _headEvent = curEvent;
- curEvent->nextEvent = curEvent->prevEvent = 0;
+ curEvent->_nextEvent = curEvent->_prevEvent = 0;
} else {
- event_t *wrkEvent = _tailEvent; // Search from latest time back
+ Event *wrkEvent = _tailEvent; // Search from latest time back
bool found = false;
while (wrkEvent && !found) {
- if (wrkEvent->time <= curEvent->time) { // Found if new event later
+ if (wrkEvent->_time <= curEvent->_time) { // Found if new event later
found = true;
- if (wrkEvent == _tailEvent) // New latest in list
+ if (wrkEvent == _tailEvent) // New latest in list
_tailEvent = curEvent;
else
- wrkEvent->nextEvent->prevEvent = curEvent;
- curEvent->nextEvent = wrkEvent->nextEvent;
- wrkEvent->nextEvent = curEvent;
- curEvent->prevEvent = wrkEvent;
+ wrkEvent->_nextEvent->_prevEvent = curEvent;
+ curEvent->_nextEvent = wrkEvent->_nextEvent;
+ wrkEvent->_nextEvent = curEvent;
+ curEvent->_prevEvent = wrkEvent;
}
- wrkEvent = wrkEvent->prevEvent;
+ wrkEvent = wrkEvent->_prevEvent;
}
- if (!found) { // Must be earliest in list
- _headEvent->prevEvent = curEvent; // So insert as new head
- curEvent->nextEvent = _headEvent;
- curEvent->prevEvent = 0;
+ if (!found) { // Must be earliest in list
+ _headEvent->_prevEvent = curEvent; // So insert as new head
+ curEvent->_nextEvent = _headEvent;
+ curEvent->_prevEvent = 0;
_headEvent = curEvent;
}
}
@@ -1189,246 +1189,246 @@ void Scheduler::insertAction(act *action) {
* It dequeues the event and returns it to the free list. It returns a ptr
* to the next action in the list, except special case of NEW_SCREEN
*/
-event_t *Scheduler::doAction(event_t *curEvent) {
- debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->action->a0.actType);
+Event *Scheduler::doAction(Event *curEvent) {
+ debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->_action->_a0._actType);
- status_t &gameStatus = _vm->getGameStatus();
- act *action = curEvent->action;
- object_t *obj1;
- int dx, dy;
- event_t *wrkEvent; // Save ev_p->next_p for return
+ Status &gameStatus = _vm->getGameStatus();
+ Act *action = curEvent->_action;
+ Object *obj1;
+ int dx, dy;
+ Event *wrkEvent; // Save ev_p->nextEvent for return
- switch (action->a0.actType) {
- case ANULL: // Big NOP from DEL_EVENTS
+ switch (action->_a0._actType) {
+ case ANULL: // Big NOP from DEL_EVENTS
break;
- case ASCHEDULE: // act0: Schedule an action list
- insertActionList(action->a0.actIndex);
+ case ASCHEDULE: // act0: Schedule an action list
+ insertActionList(action->_a0._actIndex);
break;
- case START_OBJ: // act1: Start an object cycling
- _vm->_object->_objects[action->a1.objIndex].cycleNumb = action->a1.cycleNumb;
- _vm->_object->_objects[action->a1.objIndex].cycling = action->a1.cycle;
+ case START_OBJ: // act1: Start an object cycling
+ _vm->_object->_objects[action->_a1._objIndex]._cycleNumb = action->_a1._cycleNumb;
+ _vm->_object->_objects[action->_a1._objIndex]._cycling = action->_a1._cycle;
break;
- case INIT_OBJXY: // act2: Initialize an object
- _vm->_object->_objects[action->a2.objIndex].x = action->a2.x; // Coordinates
- _vm->_object->_objects[action->a2.objIndex].y = action->a2.y;
+ case INIT_OBJXY: // act2: Initialize an object
+ _vm->_object->_objects[action->_a2._objIndex]._x = action->_a2._x; // Coordinates
+ _vm->_object->_objects[action->_a2._objIndex]._y = action->_a2._y;
break;
- case PROMPT: // act3: Prompt user for key phrase
+ case PROMPT: // act3: Prompt user for key phrase
promptAction(action);
break;
- case BKGD_COLOR: // act4: Set new background color
- _vm->_screen->setBackgroundColor(action->a4.newBackgroundColor);
+ case BKGD_COLOR: // act4: Set new background color
+ _vm->_screen->setBackgroundColor(action->_a4._newBackgroundColor);
break;
- case INIT_OBJVXY: // act5: Initialize an object velocity
- _vm->_object->setVelocity(action->a5.objIndex, action->a5.vx, action->a5.vy);
+ case INIT_OBJVXY: // act5: Initialize an object velocity
+ _vm->_object->setVelocity(action->_a5._objIndex, action->_a5._vx, action->_a5._vy);
break;
- case INIT_CARRY: // act6: Initialize an object
- _vm->_object->setCarry(action->a6.objIndex, action->a6.carriedFl); // carried status
+ case INIT_CARRY: // act6: Initialize an object
+ _vm->_object->setCarry(action->_a6._objIndex, action->_a6._carriedFl); // carried status
break;
- case INIT_HF_COORD: // act7: Initialize an object to hero's "feet" coords
- _vm->_object->_objects[action->a7.objIndex].x = _vm->_hero->x - 1;
- _vm->_object->_objects[action->a7.objIndex].y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1;
- _vm->_object->_objects[action->a7.objIndex].screenIndex = *_vm->_screen_p; // Don't forget screen!
+ case INIT_HF_COORD: // act7: Initialize an object to hero's "feet" coords
+ _vm->_object->_objects[action->_a7._objIndex]._x = _vm->_hero->_x - 1;
+ _vm->_object->_objects[action->_a7._objIndex]._y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1;
+ _vm->_object->_objects[action->_a7._objIndex]._screenIndex = *_vm->_screenPtr; // Don't forget screen!
break;
- case NEW_SCREEN: // act8: Start new screen
- newScreen(action->a8.screenIndex);
+ case NEW_SCREEN: // act8: Start new screen
+ newScreen(action->_a8._screenIndex);
break;
- case INIT_OBJSTATE: // act9: Initialize an object state
- _vm->_object->_objects[action->a9.objIndex].state = action->a9.newState;
+ case INIT_OBJSTATE: // act9: Initialize an object state
+ _vm->_object->_objects[action->_a9._objIndex]._state = action->_a9._newState;
break;
- case INIT_PATH: // act10: Initialize an object path and velocity
- _vm->_object->setPath(action->a10.objIndex, (path_t) action->a10.newPathType, action->a10.vxPath, action->a10.vyPath);
+ case INIT_PATH: // act10: Initialize an object path and velocity
+ _vm->_object->setPath(action->_a10._objIndex, (Path) action->_a10._newPathType, action->_a10._vxPath, action->_a10._vyPath);
break;
- case COND_R: // act11: action lists conditional on object state
- if (_vm->_object->_objects[action->a11.objIndex].state == action->a11.stateReq)
- insertActionList(action->a11.actPassIndex);
+ case COND_R: // act11: action lists conditional on object state
+ if (_vm->_object->_objects[action->_a11._objIndex]._state == action->_a11._stateReq)
+ insertActionList(action->_a11._actPassIndex);
else
- insertActionList(action->a11.actFailIndex);
+ insertActionList(action->_a11._actFailIndex);
break;
- case TEXT: // act12: Text box (CF WARN)
- Utils::notifyBox(_vm->_file->fetchString(action->a12.stringIndex)); // Fetch string from file
+ case TEXT: // act12: Text box (CF WARN)
+ Utils::notifyBox(_vm->_file->fetchString(action->_a12._stringIndex)); // Fetch string from file
break;
- case SWAP_IMAGES: // act13: Swap 2 object images
- _vm->_object->swapImages(action->a13.objIndex1, action->a13.objIndex2);
+ case SWAP_IMAGES: // act13: Swap 2 object images
+ _vm->_object->swapImages(action->_a13._objIndex1, action->_a13._objIndex2);
break;
- case COND_SCR: // act14: Conditional on current screen
- if (_vm->_object->_objects[action->a14.objIndex].screenIndex == action->a14.screenReq)
- insertActionList(action->a14.actPassIndex);
+ case COND_SCR: // act14: Conditional on current screen
+ if (_vm->_object->_objects[action->_a14._objIndex]._screenIndex == action->_a14._screenReq)
+ insertActionList(action->_a14._actPassIndex);
else
- insertActionList(action->a14.actFailIndex);
+ insertActionList(action->_a14._actFailIndex);
break;
- case AUTOPILOT: // act15: Home in on a (stationary) object
- _vm->_object->homeIn(action->a15.objIndex1, action->a15.objIndex2, action->a15.dx, action->a15.dy);
+ case AUTOPILOT: // act15: Home in on a (stationary) object
+ _vm->_object->homeIn(action->_a15._objIndex1, action->_a15._objIndex2, action->_a15._dx, action->_a15._dy);
break;
- case INIT_OBJ_SEQ: // act16: Set sequence number to use
+ case INIT_OBJ_SEQ: // act16: Set sequence number to use
// Note: Don't set a sequence at time 0 of a new screen, it causes
// problems clearing the boundary bits of the object! t>0 is safe
- _vm->_object->_objects[action->a16.objIndex].currImagePtr = _vm->_object->_objects[action->a16.objIndex].seqList[action->a16.seqIndex].seqPtr;
+ _vm->_object->_objects[action->_a16._objIndex]._currImagePtr = _vm->_object->_objects[action->_a16._objIndex]._seqList[action->_a16._seqIndex]._seqPtr;
break;
- case SET_STATE_BITS: // act17: OR mask with curr obj state
- _vm->_object->_objects[action->a17.objIndex].state |= action->a17.stateMask;
+ case SET_STATE_BITS: // act17: OR mask with curr obj state
+ _vm->_object->_objects[action->_a17._objIndex]._state |= action->_a17._stateMask;
break;
- case CLEAR_STATE_BITS: // act18: AND ~mask with curr obj state
- _vm->_object->_objects[action->a18.objIndex].state &= ~action->a18.stateMask;
+ case CLEAR_STATE_BITS: // act18: AND ~mask with curr obj state
+ _vm->_object->_objects[action->_a18._objIndex]._state &= ~action->_a18._stateMask;
break;
- case TEST_STATE_BITS: // act19: If all bits set, do apass else afail
- if ((_vm->_object->_objects[action->a19.objIndex].state & action->a19.stateMask) == action->a19.stateMask)
- insertActionList(action->a19.actPassIndex);
+ case TEST_STATE_BITS: // act19: If all bits set, do apass else afail
+ if ((_vm->_object->_objects[action->_a19._objIndex]._state & action->_a19._stateMask) == action->_a19._stateMask)
+ insertActionList(action->_a19._actPassIndex);
else
- insertActionList(action->a19.actFailIndex);
+ insertActionList(action->_a19._actFailIndex);
break;
- case DEL_EVENTS: // act20: Remove all events of this action type
- delEventType(action->a20.actTypeDel);
+ case DEL_EVENTS: // act20: Remove all events of this action type
+ delEventType(action->_a20._actTypeDel);
break;
- case GAMEOVER: // act21: Game over!
+ case GAMEOVER: // act21: Game over!
// NOTE: Must wait at least 1 tick before issuing this action if
// any objects are to be made invisible!
- gameStatus.gameOverFl = true;
+ gameStatus._gameOverFl = true;
break;
- case INIT_HH_COORD: // act22: Initialize an object to hero's actual coords
- _vm->_object->_objects[action->a22.objIndex].x = _vm->_hero->x;
- _vm->_object->_objects[action->a22.objIndex].y = _vm->_hero->y;
- _vm->_object->_objects[action->a22.objIndex].screenIndex = *_vm->_screen_p;// Don't forget screen!
+ case INIT_HH_COORD: // act22: Initialize an object to hero's actual coords
+ _vm->_object->_objects[action->_a22._objIndex]._x = _vm->_hero->_x;
+ _vm->_object->_objects[action->_a22._objIndex]._y = _vm->_hero->_y;
+ _vm->_object->_objects[action->_a22._objIndex]._screenIndex = *_vm->_screenPtr;// Don't forget screen!
break;
- case EXIT: // act23: Exit game back to DOS
+ case EXIT: // act23: Exit game back to DOS
_vm->endGame();
break;
- case BONUS: // act24: Get bonus score for action
- processBonus(action->a24.pointIndex);
+ case BONUS: // act24: Get bonus score for action
+ processBonus(action->_a24._pointIndex);
break;
- case COND_BOX: // act25: Conditional on bounding box
- obj1 = &_vm->_object->_objects[action->a25.objIndex];
- dx = obj1->x + obj1->currImagePtr->x1;
- dy = obj1->y + obj1->currImagePtr->y2;
- if ((dx >= action->a25.x1) && (dx <= action->a25.x2) &&
- (dy >= action->a25.y1) && (dy <= action->a25.y2))
- insertActionList(action->a25.actPassIndex);
+ case COND_BOX: // act25: Conditional on bounding box
+ obj1 = &_vm->_object->_objects[action->_a25._objIndex];
+ dx = obj1->_x + obj1->_currImagePtr->_x1;
+ dy = obj1->_y + obj1->_currImagePtr->_y2;
+ if ((dx >= action->_a25._x1) && (dx <= action->_a25._x2) &&
+ (dy >= action->_a25._y1) && (dy <= action->_a25._y2))
+ insertActionList(action->_a25._actPassIndex);
else
- insertActionList(action->a25.actFailIndex);
+ insertActionList(action->_a25._actFailIndex);
break;
- case SOUND: // act26: Play a sound (or tune)
- if (action->a26.soundIndex < _vm->_tunesNbr)
- _vm->_sound->playMusic(action->a26.soundIndex);
+ case SOUND: // act26: Play a sound (or tune)
+ if (action->_a26._soundIndex < _vm->_tunesNbr)
+ _vm->_sound->playMusic(action->_a26._soundIndex);
else
- _vm->_sound->playSound(action->a26.soundIndex, kSoundPriorityMedium);
+ _vm->_sound->playSound(action->_a26._soundIndex, kSoundPriorityMedium);
break;
- case ADD_SCORE: // act27: Add object's value to score
- _vm->adjustScore(_vm->_object->_objects[action->a27.objIndex].objValue);
+ case ADD_SCORE: // act27: Add object's value to score
+ _vm->adjustScore(_vm->_object->_objects[action->_a27._objIndex]._objValue);
break;
- case SUB_SCORE: // act28: Subtract object's value from score
- _vm->adjustScore(-_vm->_object->_objects[action->a28.objIndex].objValue);
+ case SUB_SCORE: // act28: Subtract object's value from score
+ _vm->adjustScore(-_vm->_object->_objects[action->_a28._objIndex]._objValue);
break;
- case COND_CARRY: // act29: Conditional on object being carried
- if (_vm->_object->isCarried(action->a29.objIndex))
- insertActionList(action->a29.actPassIndex);
+ case COND_CARRY: // act29: Conditional on object being carried
+ if (_vm->_object->isCarried(action->_a29._objIndex))
+ insertActionList(action->_a29._actPassIndex);
else
- insertActionList(action->a29.actFailIndex);
- break;
- case INIT_MAZE: // act30: Enable and init maze structure
- _vm->_maze.enabledFl = true;
- _vm->_maze.size = action->a30.mazeSize;
- _vm->_maze.x1 = action->a30.x1;
- _vm->_maze.y1 = action->a30.y1;
- _vm->_maze.x2 = action->a30.x2;
- _vm->_maze.y2 = action->a30.y2;
- _vm->_maze.x3 = action->a30.x3;
- _vm->_maze.x4 = action->a30.x4;
- _vm->_maze.firstScreenIndex = action->a30.firstScreenIndex;
- break;
- case EXIT_MAZE: // act31: Disable maze mode
- _vm->_maze.enabledFl = false;
+ insertActionList(action->_a29._actFailIndex);
+ break;
+ case INIT_MAZE: // act30: Enable and init maze structure
+ _vm->_maze._enabledFl = true;
+ _vm->_maze._size = action->_a30._mazeSize;
+ _vm->_maze._x1 = action->_a30._x1;
+ _vm->_maze._y1 = action->_a30._y1;
+ _vm->_maze._x2 = action->_a30._x2;
+ _vm->_maze._y2 = action->_a30._y2;
+ _vm->_maze._x3 = action->_a30._x3;
+ _vm->_maze._x4 = action->_a30._x4;
+ _vm->_maze._firstScreenIndex = action->_a30._firstScreenIndex;
+ break;
+ case EXIT_MAZE: // act31: Disable maze mode
+ _vm->_maze._enabledFl = false;
break;
case INIT_PRIORITY:
- _vm->_object->_objects[action->a32.objIndex].priority = action->a32.priority;
+ _vm->_object->_objects[action->_a32._objIndex]._priority = action->_a32._priority;
break;
case INIT_SCREEN:
- _vm->_object->_objects[action->a33.objIndex].screenIndex = action->a33.screenIndex;
+ _vm->_object->_objects[action->_a33._objIndex]._screenIndex = action->_a33._screenIndex;
break;
- case AGSCHEDULE: // act34: Schedule a (global) action list
- insertActionList(action->a34.actIndex);
+ case AGSCHEDULE: // act34: Schedule a (global) action list
+ insertActionList(action->_a34._actIndex);
break;
- case REMAPPAL: // act35: Remap a palette color
- _vm->_screen->remapPal(action->a35.oldColorIndex, action->a35.newColorIndex);
+ case REMAPPAL: // act35: Remap a palette color
+ _vm->_screen->remapPal(action->_a35._oldColorIndex, action->_a35._newColorIndex);
break;
- case COND_NOUN: // act36: Conditional on noun mentioned
- if (_vm->_parser->isWordPresent(_vm->_text->getNounArray(action->a36.nounIndex)))
- insertActionList(action->a36.actPassIndex);
+ case COND_NOUN: // act36: Conditional on noun mentioned
+ if (_vm->_parser->isWordPresent(_vm->_text->getNounArray(action->_a36._nounIndex)))
+ insertActionList(action->_a36._actPassIndex);
else
- insertActionList(action->a36.actFailIndex);
+ insertActionList(action->_a36._actFailIndex);
break;
- case SCREEN_STATE: // act37: Set new screen state
- _vm->_screenStates[action->a37.screenIndex] = action->a37.newState;
+ case SCREEN_STATE: // act37: Set new screen state
+ _vm->_screenStates[action->_a37._screenIndex] = action->_a37._newState;
break;
- case INIT_LIPS: // act38: Position lips on object
- _vm->_object->_objects[action->a38.lipsObjIndex].x = _vm->_object->_objects[action->a38.objIndex].x + action->a38.dxLips;
- _vm->_object->_objects[action->a38.lipsObjIndex].y = _vm->_object->_objects[action->a38.objIndex].y + action->a38.dyLips;
- _vm->_object->_objects[action->a38.lipsObjIndex].screenIndex = *_vm->_screen_p; // Don't forget screen!
- _vm->_object->_objects[action->a38.lipsObjIndex].cycling = kCycleForward;
+ case INIT_LIPS: // act38: Position lips on object
+ _vm->_object->_objects[action->_a38._lipsObjIndex]._x = _vm->_object->_objects[action->_a38._objIndex]._x + action->_a38._dxLips;
+ _vm->_object->_objects[action->_a38._lipsObjIndex]._y = _vm->_object->_objects[action->_a38._objIndex]._y + action->_a38._dyLips;
+ _vm->_object->_objects[action->_a38._lipsObjIndex]._screenIndex = *_vm->_screenPtr; // Don't forget screen!
+ _vm->_object->_objects[action->_a38._lipsObjIndex]._cycling = kCycleForward;
break;
- case INIT_STORY_MODE: // act39: Init story_mode flag
+ case INIT_STORY_MODE: // act39: Init story_mode flag
// This is similar to the QUIET path mode, except that it is
// independant of it and it additionally disables the ">" prompt
- gameStatus.storyModeFl = action->a39.storyModeFl;
+ gameStatus._storyModeFl = action->_a39._storyModeFl;
break;
- case WARN: // act40: Text box (CF TEXT)
- Utils::notifyBox(_vm->_file->fetchString(action->a40.stringIndex));
+ case WARN: // act40: Text box (CF TEXT)
+ Utils::notifyBox(_vm->_file->fetchString(action->_a40._stringIndex));
break;
- case COND_BONUS: // act41: Perform action if got bonus
- if (_points[action->a41.BonusIndex].scoredFl)
- insertActionList(action->a41.actPassIndex);
+ case COND_BONUS: // act41: Perform action if got bonus
+ if (_points[action->_a41._bonusIndex]._scoredFl)
+ insertActionList(action->_a41._actPassIndex);
else
- insertActionList(action->a41.actFailIndex);
+ insertActionList(action->_a41._actFailIndex);
break;
- case TEXT_TAKE: // act42: Text box with "take" message
- Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(_vm->_object->_objects[action->a42.objIndex].nounIndex, TAKE_NAME)));
+ case TEXT_TAKE: // act42: Text box with "take" message
+ Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(_vm->_object->_objects[action->_a42._objIndex]._nounIndex, TAKE_NAME)));
break;
- case YESNO: // act43: Prompt user for Yes or No
- if (Utils::yesNoBox(_vm->_file->fetchString(action->a43.promptIndex)))
- insertActionList(action->a43.actYesIndex);
+ case YESNO: // act43: Prompt user for Yes or No
+ if (Utils::yesNoBox(_vm->_file->fetchString(action->_a43._promptIndex)))
+ insertActionList(action->_a43._actYesIndex);
else
- insertActionList(action->a43.actNoIndex);
+ insertActionList(action->_a43._actNoIndex);
break;
- case STOP_ROUTE: // act44: Stop any route in progress
+ case STOP_ROUTE: // act44: Stop any route in progress
_vm->_route->resetRoute();
break;
- case COND_ROUTE: // act45: Conditional on route in progress
- if (_vm->_route->getRouteIndex() >= action->a45.routeIndex)
- insertActionList(action->a45.actPassIndex);
+ case COND_ROUTE: // act45: Conditional on route in progress
+ if (_vm->_route->getRouteIndex() >= action->_a45._routeIndex)
+ insertActionList(action->_a45._actPassIndex);
else
- insertActionList(action->a45.actFailIndex);
+ insertActionList(action->_a45._actFailIndex);
break;
- case INIT_JUMPEXIT: // act46: Init status.jumpexit flag
+ case INIT_JUMPEXIT: // act46: Init status.jumpexit flag
// This is to allow left click on exit to get there immediately
// For example the plane crash in Hugo2 where hero is invisible
// Couldn't use INVISIBLE flag since conflicts with boat in Hugo1
- _vm->_mouse->setJumpExitFl(action->a46.jumpExitFl);
+ _vm->_mouse->setJumpExitFl(action->_a46._jumpExitFl);
break;
- case INIT_VIEW: // act47: Init object.viewx, viewy, dir
- _vm->_object->_objects[action->a47.objIndex].viewx = action->a47.viewx;
- _vm->_object->_objects[action->a47.objIndex].viewy = action->a47.viewy;
- _vm->_object->_objects[action->a47.objIndex].direction = action->a47.direction;
+ case INIT_VIEW: // act47: Init object._viewx, viewy, dir
+ _vm->_object->_objects[action->_a47._objIndex]._viewx = action->_a47._viewx;
+ _vm->_object->_objects[action->_a47._objIndex]._viewy = action->_a47._viewy;
+ _vm->_object->_objects[action->_a47._objIndex]._direction = action->_a47._direction;
break;
- case INIT_OBJ_FRAME: // act48: Set seq,frame number to use
+ case INIT_OBJ_FRAME: // act48: Set seq,frame number to use
// Note: Don't set a sequence at time 0 of a new screen, it causes
// problems clearing the boundary bits of the object! t>0 is safe
- _vm->_object->_objects[action->a48.objIndex].currImagePtr = _vm->_object->_objects[action->a48.objIndex].seqList[action->a48.seqIndex].seqPtr;
- for (dx = 0; dx < action->a48.frameIndex; dx++)
- _vm->_object->_objects[action->a48.objIndex].currImagePtr = _vm->_object->_objects[action->a48.objIndex].currImagePtr->nextSeqPtr;
+ _vm->_object->_objects[action->_a48._objIndex]._currImagePtr = _vm->_object->_objects[action->_a48._objIndex]._seqList[action->_a48._seqIndex]._seqPtr;
+ for (dx = 0; dx < action->_a48._frameIndex; dx++)
+ _vm->_object->_objects[action->_a48._objIndex]._currImagePtr = _vm->_object->_objects[action->_a48._objIndex]._currImagePtr->_nextSeqPtr;
break;
case OLD_SONG:
// Replaces ACT26 for DOS games.
- _vm->_sound->_DOSSongPtr = _vm->_text->getTextData(action->a49.songIndex);
+ _vm->_sound->_DOSSongPtr = _vm->_text->getTextData(action->_a49._songIndex);
break;
default:
error("An error has occurred: %s", "doAction");
break;
}
- if (action->a0.actType == NEW_SCREEN) { // New_screen() deletes entire list
- return 0; // next_p = 0 since list now empty
+ if (action->_a0._actType == NEW_SCREEN) { // New_screen() deletes entire list
+ return 0; // nextEvent = 0 since list now empty
} else {
- wrkEvent = curEvent->nextEvent;
- delQueue(curEvent); // Return event to free list
- return wrkEvent; // Return next event ptr
+ wrkEvent = curEvent->_nextEvent;
+ delQueue(curEvent); // Return event to free list
+ return wrkEvent; // Return next event ptr
}
}
@@ -1441,41 +1441,41 @@ event_t *Scheduler::doAction(event_t *curEvent) {
* was modified to allow deletes anywhere in the list, and the DEL_EVENT
* action was modified to perform the actual delete.
*/
-void Scheduler::delQueue(event_t *curEvent) {
+void Scheduler::delQueue(Event *curEvent) {
debugC(4, kDebugSchedule, "delQueue()");
- if (curEvent == _headEvent) { // If p was the head ptr
- _headEvent = curEvent->nextEvent; // then make new head_p
- } else { // Unlink p
- curEvent->prevEvent->nextEvent = curEvent->nextEvent;
- if (curEvent->nextEvent)
- curEvent->nextEvent->prevEvent = curEvent->prevEvent;
+ if (curEvent == _headEvent) { // If p was the head ptr
+ _headEvent = curEvent->_nextEvent; // then make new head_p
+ } else { // Unlink p
+ curEvent->_prevEvent->_nextEvent = curEvent->_nextEvent;
+ if (curEvent->_nextEvent)
+ curEvent->_nextEvent->_prevEvent = curEvent->_prevEvent;
else
- _tailEvent = curEvent->prevEvent;
+ _tailEvent = curEvent->_prevEvent;
}
if (_headEvent)
- _headEvent->prevEvent = 0; // Mark end of list
+ _headEvent->_prevEvent = 0; // Mark end of list
else
- _tailEvent = 0; // Empty queue
+ _tailEvent = 0; // Empty queue
- curEvent->nextEvent = _freeEvent; // Return p to free list
- if (_freeEvent) // Special case, if free list was empty
- _freeEvent->prevEvent = curEvent;
+ curEvent->_nextEvent = _freeEvent; // Return p to free list
+ if (_freeEvent) // Special case, if free list was empty
+ _freeEvent->_prevEvent = curEvent;
_freeEvent = curEvent;
}
/**
* Delete all the active events of a given type
*/
-void Scheduler::delEventType(const action_t actTypeDel) {
+void Scheduler::delEventType(const Action _actTypeDel) {
// Note: actions are not deleted here, simply turned into NOPs!
- event_t *wrkEvent = _headEvent; // The earliest event
- event_t *saveEvent;
+ Event *wrkEvent = _headEvent; // The earliest event
+ Event *saveEvent;
- while (wrkEvent) { // While events found in list
- saveEvent = wrkEvent->nextEvent;
- if (wrkEvent->action->a20.actType == actTypeDel)
+ while (wrkEvent) { // While events found in list
+ saveEvent = wrkEvent->_nextEvent;
+ if (wrkEvent->_action->_a20._actType == _actTypeDel)
delQueue(wrkEvent);
wrkEvent = saveEvent;
}
@@ -1486,8 +1486,8 @@ void Scheduler::delEventType(const action_t actTypeDel) {
*/
void Scheduler::savePoints(Common::WriteStream *out) const {
for (int i = 0; i < _numBonuses; i++) {
- out->writeByte(_points[i].score);
- out->writeByte((_points[i].scoredFl) ? 1 : 0);
+ out->writeByte(_points[i]._score);
+ out->writeByte((_points[i]._scoredFl) ? 1 : 0);
}
}
@@ -1497,8 +1497,8 @@ void Scheduler::savePoints(Common::WriteStream *out) const {
void Scheduler::restorePoints(Common::ReadStream *in) {
// Restore points table
for (int i = 0; i < _numBonuses; i++) {
- _points[i].score = in->readByte();
- _points[i].scoredFl = (in->readByte() == 1);
+ _points[i]._score = in->readByte();
+ _points[i]._scoredFl = (in->readByte() == 1);
}
}
@@ -1524,30 +1524,30 @@ uint32 Scheduler_v1d::getTicks() {
void Scheduler_v1d::runScheduler() {
debugC(6, kDebugSchedule, "runScheduler");
- uint32 ticker = getTicks(); // The time now, in ticks
- event_t *curEvent = _headEvent; // The earliest event
+ uint32 ticker = getTicks(); // The time now, in ticks
+ Event *curEvent = _headEvent; // The earliest event
- while (curEvent && (curEvent->time <= ticker)) // While mature events found
- curEvent = doAction(curEvent); // Perform the action (returns next_p)
+ while (curEvent && (curEvent->_time <= ticker)) // While mature events found
+ curEvent = doAction(curEvent); // Perform the action (returns nextEvent)
}
-void Scheduler_v1d::promptAction(act *action) {
+void Scheduler_v1d::promptAction(Act *action) {
Common::String response;
- response = Utils::promptBox(_vm->_file->fetchString(action->a3.promptIndex));
+ response = Utils::promptBox(_vm->_file->fetchString(action->_a3._promptIndex));
response.toLowercase();
char resp[256];
Common::strlcpy(resp, response.c_str(), 256);
- if (action->a3.encodedFl)
+ if (action->_a3._encodedFl)
decodeString(resp);
- if (strstr(resp, _vm->_file->fetchString(action->a3.responsePtr[0])))
- insertActionList(action->a3.actPassIndex);
+ if (strstr(resp, _vm->_file->fetchString(action->_a3._responsePtr[0])))
+ insertActionList(action->_a3._actPassIndex);
else
- insertActionList(action->a3.actFailIndex);
+ insertActionList(action->_a3._actFailIndex);
}
/**
@@ -1574,27 +1574,27 @@ const char *Scheduler_v2d::getCypher() const {
return "Copyright 1991, Gray Design Associates";
}
-void Scheduler_v2d::promptAction(act *action) {
+void Scheduler_v2d::promptAction(Act *action) {
Common::String response;
- response = Utils::promptBox(_vm->_file->fetchString(action->a3.promptIndex));
+ response = Utils::promptBox(_vm->_file->fetchString(action->_a3._promptIndex));
response.toLowercase();
- debug(1, "doAction(act3), expecting answer %s", _vm->_file->fetchString(action->a3.responsePtr[0]));
+ debug(1, "doAction(act3), expecting answer %s", _vm->_file->fetchString(action->_a3._responsePtr[0]));
bool found = false;
- const char *tmpStr; // General purpose string ptr
+ const char *tmpStr; // General purpose string ptr
- for (int dx = 0; !found && (action->a3.responsePtr[dx] != -1); dx++) {
- tmpStr = _vm->_file->fetchString(action->a3.responsePtr[dx]);
+ for (int dx = 0; !found && (action->_a3._responsePtr[dx] != -1); dx++) {
+ tmpStr = _vm->_file->fetchString(action->_a3._responsePtr[dx]);
if (response.contains(tmpStr))
found = true;
}
if (found)
- insertActionList(action->a3.actPassIndex);
+ insertActionList(action->_a3._actPassIndex);
else
- insertActionList(action->a3.actFailIndex);
+ insertActionList(action->_a3._actFailIndex);
}
/**
@@ -1638,12 +1638,12 @@ uint32 Scheduler_v1w::getTicks() {
void Scheduler_v1w::runScheduler() {
debugC(6, kDebugSchedule, "runScheduler");
- uint32 ticker = getTicks(); // The time now, in ticks
- event_t *curEvent = _headEvent; // The earliest event
+ uint32 ticker = getTicks(); // The time now, in ticks
+ Event *curEvent = _headEvent; // The earliest event
- while (curEvent && (curEvent->time <= ticker)) // While mature events found
- curEvent = doAction(curEvent); // Perform the action (returns next_p)
+ while (curEvent && (curEvent->_time <= ticker)) // While mature events found
+ curEvent = doAction(curEvent); // Perform the action (returns nextEvent)
- _vm->getGameStatus().tick++; // Accessed elsewhere via getTicks()
+ _vm->getGameStatus()._tick++; // Accessed elsewhere via getTicks()
}
} // End of namespace Hugo
diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h
index 60d51f0673..37851f1ebc 100644
--- a/engines/hugo/schedule.h
+++ b/engines/hugo/schedule.h
@@ -37,7 +37,7 @@ namespace Hugo {
/**
* Following defines the action types and action list
*/
-enum action_t { // Parameters:
+enum Action { // Parameters:
ANULL = 0xff, // Special NOP used to 'delete' events in DEL_EVENTS
ASCHEDULE = 0, // 0 - Ptr to action list to be rescheduled
START_OBJ, // 1 - Object number
@@ -56,7 +56,7 @@ enum action_t { // Parameters:
SWAP_IMAGES, // 13 - Swap 2 object images
COND_SCR, // 14 - Conditional on current screen
AUTOPILOT, // 15 - Set object to home in on another (stationary) object
- INIT_OBJ_SEQ, // 16 - Object number, sequence index to set curr_seq_p to
+ INIT_OBJ_SEQ, // 16 - Object number, sequence index to set curr_seqPtr to
SET_STATE_BITS, // 17 - Objnum, mask to OR with obj states word
CLEAR_STATE_BITS, // 18 - Objnum, mask to ~AND with obj states word
TEST_STATE_BITS, // 19 - Objnum, mask to test obj states word
@@ -88,429 +88,430 @@ enum action_t { // Parameters:
COND_ROUTE, // 45 - Conditional on route in progress
INIT_JUMPEXIT, // 46 - Initialize status.jumpexit
INIT_VIEW, // 47 - Initialize viewx, viewy, dir
- INIT_OBJ_FRAME, // 48 - Object number, seq,frame to set curr_seq_p to
+ INIT_OBJ_FRAME, // 48 - Object number, seq,frame to set curr_seqPtr to
OLD_SONG = 49 // Added by Strangerke - Set currently playing sound, old way: that is, using a string index instead of a reference in a file
};
struct act0 { // Type 0 - Schedule
- action_t actType; // The type of action
- int timer; // Time to set off the action
- uint16 actIndex; // Ptr to an action list
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ uint16 _actIndex; // Ptr to an action list
};
struct act1 { // Type 1 - Start an object
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int cycleNumb; // Number of times to cycle
- cycle_t cycle; // Direction to start cycling
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _cycleNumb; // Number of times to cycle
+ Cycle _cycle; // Direction to start cycling
};
struct act2 { // Type 2 - Initialize an object coords
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int x, y; // Coordinates
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _x, _y; // Coordinates
};
struct act3 { // Type 3 - Prompt user for text
- action_t actType; // The type of action
- int timer; // Time to set off the action
- uint16 promptIndex; // Index of prompt string
- int *responsePtr; // Array of indexes to valid response string(s) (terminate list with -1)
- uint16 actPassIndex; // Ptr to action list if success
- uint16 actFailIndex; // Ptr to action list if failure
- bool encodedFl; // (HUGO 1 DOS ONLY) Whether response is encoded or not
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ uint16 _promptIndex; // Index of prompt string
+ int *_responsePtr; // Array of indexes to valid response string(s) (terminate list with -1)
+ uint16 _actPassIndex; // Ptr to action list if success
+ uint16 _actFailIndex; // Ptr to action list if failure
+ bool _encodedFl; // (HUGO 1 DOS ONLY) Whether response is encoded or not
};
struct act4 { // Type 4 - Set new background color
- action_t actType; // The type of action
- int timer; // Time to set off the action
- long newBackgroundColor; // New color
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ long _newBackgroundColor; // New color
};
struct act5 { // Type 5 - Initialize an object velocity
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int vx, vy; // velocity
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _vx, _vy; // velocity
};
struct act6 { // Type 6 - Initialize an object carrying
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- bool carriedFl; // carrying
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ bool _carriedFl; // carrying
};
struct act7 { // Type 7 - Initialize an object to hero's coords
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
};
struct act8 { // Type 8 - switch to new screen
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int screenIndex; // The new screen number
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _screenIndex; // The new screen number
};
struct act9 { // Type 9 - Initialize an object state
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- byte newState; // New state
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ byte _newState; // New state
};
struct act10 { // Type 10 - Initialize an object path type
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int newPathType; // New path type
- int8 vxPath, vyPath; // Max delta velocities e.g. for CHASE
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _newPathType; // New path type
+ int8 _vxPath, _vyPath; // Max delta velocities e.g. for CHASE
};
struct act11 { // Type 11 - Conditional on object's state
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- byte stateReq; // Required state
- uint16 actPassIndex; // Ptr to action list if success
- uint16 actFailIndex; // Ptr to action list if failure
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ byte _stateReq; // Required state
+ uint16 _actPassIndex; // Ptr to action list if success
+ uint16 _actFailIndex; // Ptr to action list if failure
};
struct act12 { // Type 12 - Simple text box
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int stringIndex; // Index (enum) of string in strings.dat
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _stringIndex; // Index (enum) of string in strings.dat
};
struct act13 { // Type 13 - Swap first object image with second
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex1; // Index of first object
- int objIndex2; // 2nd
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex1; // Index of first object
+ int _objIndex2; // 2nd
};
struct act14 { // Type 14 - Conditional on current screen
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The required object
- int screenReq; // The required screen number
- uint16 actPassIndex; // Ptr to action list if success
- uint16 actFailIndex; // Ptr to action list if failure
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The required object
+ int _screenReq; // The required screen number
+ uint16 _actPassIndex; // Ptr to action list if success
+ uint16 _actFailIndex; // Ptr to action list if failure
};
struct act15 { // Type 15 - Home in on an object
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex1; // The object number homing in
- int objIndex2; // The object number to home in on
- int8 dx, dy; // Max delta velocities
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex1; // The object number homing in
+ int _objIndex2; // The object number to home in on
+ int8 _dx, _dy; // Max delta velocities
};
+
// Note: Don't set a sequence at time 0 of a new screen, it causes
// problems clearing the boundary bits of the object! timer > 0 is safe
-struct act16 { // Type 16 - Set curr_seq_p to seq
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int seqIndex; // The index of seq array to set to
+struct act16 { // Type 16 - Set curr_seqPtr to seq
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _seqIndex; // The index of seq array to set to
};
struct act17 { // Type 17 - SET obj individual state bits
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int stateMask; // The mask to OR with current obj state
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _stateMask; // The mask to OR with current obj state
};
struct act18 { // Type 18 - CLEAR obj individual state bits
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int stateMask; // The mask to ~AND with current obj state
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _stateMask; // The mask to ~AND with current obj state
};
struct act19 { // Type 19 - TEST obj individual state bits
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int stateMask; // The mask to AND with current obj state
- uint16 actPassIndex; // Ptr to action list (all bits set)
- uint16 actFailIndex; // Ptr to action list (not all set)
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _stateMask; // The mask to AND with current obj state
+ uint16 _actPassIndex; // Ptr to action list (all bits set)
+ uint16 _actFailIndex; // Ptr to action list (not all set)
};
struct act20 { // Type 20 - Remove all events with this type of action
- action_t actType; // The type of action
- int timer; // Time to set off the action
- action_t actTypeDel; // The action type to remove
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ Action _actTypeDel; // The action type to remove
};
struct act21 { // Type 21 - Gameover. Disable hero & commands
- action_t actType; // The type of action
- int timer; // Time to set off the action
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
};
struct act22 { // Type 22 - Initialize an object to hero's coords
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
};
struct act23 { // Type 23 - Exit game back to DOS
- action_t actType; // The type of action
- int timer; // Time to set off the action
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
};
struct act24 { // Type 24 - Get bonus score
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int pointIndex; // Index into points array
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _pointIndex; // Index into points array
};
struct act25 { // Type 25 - Conditional on bounding box
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The required object number
- int x1, y1, x2, y2; // The bounding box
- uint16 actPassIndex; // Ptr to action list if success
- uint16 actFailIndex; // Ptr to action list if failure
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The required object number
+ int _x1, _y1, _x2, _y2; // The bounding box
+ uint16 _actPassIndex; // Ptr to action list if success
+ uint16 _actFailIndex; // Ptr to action list if failure
};
struct act26 { // Type 26 - Play a sound
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int16 soundIndex; // Sound index in data file
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int16 _soundIndex; // Sound index in data file
};
struct act27 { // Type 27 - Add object's value to score
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // object number
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // object number
};
struct act28 { // Type 28 - Subtract object's value from score
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // object number
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // object number
};
struct act29 { // Type 29 - Conditional on object carried
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The required object number
- uint16 actPassIndex; // Ptr to action list if success
- uint16 actFailIndex; // Ptr to action list if failure
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The required object number
+ uint16 _actPassIndex; // Ptr to action list if success
+ uint16 _actFailIndex; // Ptr to action list if failure
};
struct act30 { // Type 30 - Start special maze processing
- action_t actType; // The type of action
- int timer; // Time to set off the action
- byte mazeSize; // Size of (square) maze
- int x1, y1, x2, y2; // Bounding box of maze
- int x3, x4; // Extra x points for perspective correction
- byte firstScreenIndex; // First (top left) screen of maze
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ byte _mazeSize; // Size of (square) maze
+ int _x1, _y1, _x2, _y2; // Bounding box of maze
+ int _x3, _x4; // Extra x points for perspective correction
+ byte _firstScreenIndex; // First (top left) screen of maze
};
struct act31 { // Type 31 - Exit special maze processing
- action_t actType; // The type of action
- int timer; // Time to set off the action
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
};
struct act32 { // Type 32 - Init fbg field of object
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- byte priority; // Value of foreground/background field
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ byte _priority; // Value of foreground/background field
};
struct act33 { // Type 33 - Init screen field of object
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int screenIndex; // Screen number
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _screenIndex; // Screen number
};
struct act34 { // Type 34 - Global Schedule
- action_t actType; // The type of action
- int timer; // Time to set off the action
- uint16 actIndex; // Ptr to an action list
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ uint16 _actIndex; // Ptr to an action list
};
struct act35 { // Type 35 - Remappe palette
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int16 oldColorIndex; // Old color index, 0..15
- int16 newColorIndex; // New color index, 0..15
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int16 _oldColorIndex; // Old color index, 0..15
+ int16 _newColorIndex; // New color index, 0..15
};
struct act36 { // Type 36 - Conditional on noun mentioned
- action_t actType; // The type of action
- int timer; // Time to set off the action
- uint16 nounIndex; // The required noun (list)
- uint16 actPassIndex; // Ptr to action list if success
- uint16 actFailIndex; // Ptr to action list if failure
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ uint16 _nounIndex; // The required noun (list)
+ uint16 _actPassIndex; // Ptr to action list if success
+ uint16 _actFailIndex; // Ptr to action list if failure
};
struct act37 { // Type 37 - Set new screen state
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int screenIndex; // The screen number
- byte newState; // The new state
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _screenIndex; // The screen number
+ byte _newState; // The new state
};
struct act38 { // Type 38 - Position lips
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int lipsObjIndex; // The LIPS object
- int objIndex; // The object to speak
- byte dxLips; // Relative offset of x
- byte dyLips; // Relative offset of y
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _lipsObjIndex; // The LIPS object
+ int _objIndex; // The object to speak
+ byte _dxLips; // Relative offset of x
+ byte _dyLips; // Relative offset of y
};
struct act39 { // Type 39 - Init story mode
- action_t actType; // The type of action
- int timer; // Time to set off the action
- bool storyModeFl; // New state of story_mode flag
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ bool _storyModeFl; // New state of story_mode flag
};
struct act40 { // Type 40 - Unsolicited text box
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int stringIndex; // Index (enum) of string in strings.dat
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _stringIndex; // Index (enum) of string in strings.dat
};
struct act41 { // Type 41 - Conditional on bonus scored
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int BonusIndex; // Index into bonus list
- uint16 actPassIndex; // Index of the action list if scored for the first time
- uint16 actFailIndex; // Index of the action list if already scored
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _bonusIndex; // Index into bonus list
+ uint16 _actPassIndex; // Index of the action list if scored for the first time
+ uint16 _actFailIndex; // Index of the action list if already scored
};
struct act42 { // Type 42 - Text box with "take" string
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object taken
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object taken
};
struct act43 { // Type 43 - Prompt user for Yes or No
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int promptIndex; // index of prompt string
- uint16 actYesIndex; // Ptr to action list if YES
- uint16 actNoIndex; // Ptr to action list if NO
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _promptIndex; // index of prompt string
+ uint16 _actYesIndex; // Ptr to action list if YES
+ uint16 _actNoIndex; // Ptr to action list if NO
};
struct act44 { // Type 44 - Stop any route in progress
- action_t actType; // The type of action
- int timer; // Time to set off the action
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
};
struct act45 { // Type 45 - Conditional on route in progress
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int routeIndex; // Must be >= current status.rindex
- uint16 actPassIndex; // Ptr to action list if en-route
- uint16 actFailIndex; // Ptr to action list if not
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _routeIndex; // Must be >= current status.rindex
+ uint16 _actPassIndex; // Ptr to action list if en-route
+ uint16 _actFailIndex; // Ptr to action list if not
};
struct act46 { // Type 46 - Init status.jumpexit
- action_t actType; // The type of action
- int timer; // Time to set off the action
- bool jumpExitFl; // New state of jumpexit flag
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ bool _jumpExitFl; // New state of jumpexit flag
};
struct act47 { // Type 47 - Init viewx,viewy,dir
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object
- int16 viewx; // object.viewx
- int16 viewy; // object.viewy
- int16 direction; // object.dir
-};
-
-struct act48 { // Type 48 - Set curr_seq_p to frame n
- action_t actType; // The type of action
- int timer; // Time to set off the action
- int objIndex; // The object number
- int seqIndex; // The index of seq array to set to
- int frameIndex; // The index of frame to set to
-};
-
-struct act49 { // Added by Strangerke - Type 79 - Play a song (DOS way)
- action_t actType; // The type of action
- int timer; // Time to set off the action
- uint16 songIndex; // Song index in string array
-};
-
-union act {
- act0 a0;
- act1 a1;
- act2 a2;
- act3 a3;
- act4 a4;
- act5 a5;
- act6 a6;
- act7 a7;
- act8 a8;
- act9 a9;
- act10 a10;
- act11 a11;
- act12 a12;
- act13 a13;
- act14 a14;
- act15 a15;
- act16 a16;
- act17 a17;
- act18 a18;
- act19 a19;
- act20 a20;
- act21 a21;
- act22 a22;
- act23 a23;
- act24 a24;
- act25 a25;
- act26 a26;
- act27 a27;
- act28 a28;
- act29 a29;
- act30 a30;
- act31 a31;
- act32 a32;
- act33 a33;
- act34 a34;
- act35 a35;
- act36 a36;
- act37 a37;
- act38 a38;
- act39 a39;
- act40 a40;
- act41 a41;
- act42 a42;
- act43 a43;
- act44 a44;
- act45 a45;
- act46 a46;
- act47 a47;
- act48 a48;
- act49 a49;
-};
-
-struct event_t {
- act *action; // Ptr to action to perform
- bool localActionFl; // true if action is only for this screen
- uint32 time; // (absolute) time to perform action
- struct event_t *prevEvent; // Chain to previous event
- struct event_t *nextEvent; // Chain to next event
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object
+ int16 _viewx; // object.viewx
+ int16 _viewy; // object.viewy
+ int16 _direction; // object.dir
+};
+
+struct act48 { // Type 48 - Set curr_seqPtr to frame n
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ int _objIndex; // The object number
+ int _seqIndex; // The index of seq array to set to
+ int _frameIndex; // The index of frame to set to
+};
+
+struct act49 { // Added by Strangerke - Type 49 - Play a song (DOS way)
+ Action _actType; // The type of action
+ int _timer; // Time to set off the action
+ uint16 _songIndex; // Song index in string array
+};
+
+union Act {
+ act0 _a0;
+ act1 _a1;
+ act2 _a2;
+ act3 _a3;
+ act4 _a4;
+ act5 _a5;
+ act6 _a6;
+ act7 _a7;
+ act8 _a8;
+ act9 _a9;
+ act10 _a10;
+ act11 _a11;
+ act12 _a12;
+ act13 _a13;
+ act14 _a14;
+ act15 _a15;
+ act16 _a16;
+ act17 _a17;
+ act18 _a18;
+ act19 _a19;
+ act20 _a20;
+ act21 _a21;
+ act22 _a22;
+ act23 _a23;
+ act24 _a24;
+ act25 _a25;
+ act26 _a26;
+ act27 _a27;
+ act28 _a28;
+ act29 _a29;
+ act30 _a30;
+ act31 _a31;
+ act32 _a32;
+ act33 _a33;
+ act34 _a34;
+ act35 _a35;
+ act36 _a36;
+ act37 _a37;
+ act38 _a38;
+ act39 _a39;
+ act40 _a40;
+ act41 _a41;
+ act42 _a42;
+ act43 _a43;
+ act44 _a44;
+ act45 _a45;
+ act46 _a46;
+ act47 _a47;
+ act48 _a48;
+ act49 _a49;
+};
+
+struct Event {
+ Act *_action; // Ptr to action to perform
+ bool _localActionFl; // true if action is only for this screen
+ uint32 _time; // (absolute) time to perform action
+ struct Event *_prevEvent; // Chain to previous event
+ struct Event *_nextEvent; // Chain to next event
};
/**
* Following are points for achieving certain actions.
*/
-struct point_t {
- byte score; // The value of the point
- bool scoredFl; // Whether scored yet
+struct Point {
+ byte _score; // The value of the point
+ bool _scoredFl; // Whether scored yet
};
class Scheduler {
@@ -553,36 +554,36 @@ protected:
uint16 **_screenActs;
byte _numBonuses;
- point_t *_points;
+ Point *_points;
uint32 _curTick; // Current system time in ticks
uint32 _oldTime; // The previous wall time in ticks
uint32 _refreshTimeout;
- event_t *_freeEvent; // Free list of event structures
- event_t *_headEvent; // Head of list (earliest time)
- event_t *_tailEvent; // Tail of list (latest time)
- event_t _events[kMaxEvents]; // Statically declare event structures
+ Event *_freeEvent; // Free list of event structures
+ Event *_headEvent; // Head of list (earliest time)
+ Event *_tailEvent; // Tail of list (latest time)
+ Event _events[kMaxEvents]; // Statically declare event structures
- act **_actListArr;
+ Act **_actListArr;
virtual const char *getCypher() const = 0;
virtual uint32 getTicks() = 0;
- virtual void promptAction(act *action) = 0;
+ virtual void promptAction(Act *action) = 0;
- event_t *doAction(event_t *curEvent);
- event_t *getQueue();
+ Event *doAction(Event *curEvent);
+ Event *getQueue();
uint32 getDosTicks(const bool updateFl);
uint32 getWinTicks() const;
- void delEventType(const action_t actTypeDel);
- void delQueue(event_t *curEvent);
- void findAction(const act* action, int16* index, int16* subElem);
- void insertAction(act *action);
- void readAct(Common::ReadStream &in, act &curAct);
+ void delEventType(const Action actTypeDel);
+ void delQueue(Event *curEvent);
+ void findAction(const Act* action, int16* index, int16* subElem);
+ void insertAction(Act *action);
+ void readAct(Common::ReadStream &in, Act &curAct);
void restoreActions(Common::ReadStream *f);
void restoreEvents(Common::ReadStream *f);
void restorePoints(Common::ReadStream *in);
@@ -604,7 +605,7 @@ public:
protected:
virtual const char *getCypher() const;
virtual uint32 getTicks();
- virtual void promptAction(act *action);
+ virtual void promptAction(Act *action);
};
class Scheduler_v2d : public Scheduler_v1d {
@@ -617,7 +618,7 @@ public:
protected:
virtual const char *getCypher() const;
- void promptAction(act *action);
+ void promptAction(Act *action);
};
class Scheduler_v3d : public Scheduler_v2d {
diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp
index d0b4e3dfe8..aefa03cd5e 100644
--- a/engines/hugo/sound.cpp
+++ b/engines/hugo/sound.cpp
@@ -162,31 +162,31 @@ void SoundHandler::stopMusic() {
* Turn music on and off
*/
void SoundHandler::toggleMusic() {
- _vm->_config.musicFl = !_vm->_config.musicFl;
+ _vm->_config._musicFl = !_vm->_config._musicFl;
- _midiPlayer->pause(!_vm->_config.musicFl);
+ _midiPlayer->pause(!_vm->_config._musicFl);
}
/**
* Turn digitized sound on and off
*/
void SoundHandler::toggleSound() {
- _vm->_config.soundFl = !_vm->_config.soundFl;
+ _vm->_config._soundFl = !_vm->_config._soundFl;
}
-void SoundHandler::playMIDI(sound_pt seq_p, uint16 size) {
- _midiPlayer->play(seq_p, size);
+void SoundHandler::playMIDI(SoundPtr seqPtr, uint16 size) {
+ _midiPlayer->play(seqPtr, size);
}
/**
* Read a tune sequence from the sound database and start playing it
*/
void SoundHandler::playMusic(int16 tune) {
- sound_pt seqPtr; // Sequence data from file
+ SoundPtr seqPtr; // Sequence data from file
uint16 size; // Size of sequence data
- if (_vm->_config.musicFl) {
- _vm->getGameStatus().song = tune;
+ if (_vm->_config._musicFl) {
+ _vm->getGameStatus()._song = tune;
seqPtr = _vm->_file->getSound(tune, &size);
playMIDI(seqPtr, size);
free(seqPtr);
@@ -198,22 +198,22 @@ void SoundHandler::playMusic(int16 tune) {
* Override currently playing sound only if lower or same priority
*/
void SoundHandler::playSound(int16 sound, const byte priority) {
- // uint32 dwVolume; // Left, right volume of sound
- sound_pt sound_p; // Sound data
- uint16 size; // Size of data
+ // uint32 dwVolume; // Left, right volume of sound
+ SoundPtr soundPtr; // Sound data
+ uint16 size; // Size of data
// Sound disabled
- if (!_vm->_config.soundFl || !_vm->_mixer->isReady())
+ if (!_vm->_config._soundFl || !_vm->_mixer->isReady())
return;
syncVolume();
_curPriority = priority;
// Get sound data
- if ((sound_p = _vm->_file->getSound(sound, &size)) == 0)
+ if ((soundPtr = _vm->_file->getSound(sound, &size)) == 0)
return;
- Audio::AudioStream *stream = Audio::makeRawStream(sound_p, size, 11025, Audio::FLAG_UNSIGNED);
+ Audio::AudioStream *stream = Audio::makeRawStream(soundPtr, size, 11025, Audio::FLAG_UNSIGNED);
_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, stream);
}
@@ -245,7 +245,7 @@ void SoundHandler::checkMusic() {
return;
for (int i = 0; _vm->_defltTunes[i] != -1; i++) {
- if (_vm->_defltTunes[i] == _vm->getGameStatus().song) {
+ if (_vm->_defltTunes[i] == _vm->getGameStatus()._song) {
if (_vm->_defltTunes[i + 1] != -1)
playMusic(_vm->_defltTunes[i + 1]);
else
@@ -270,7 +270,7 @@ void SoundHandler::pcspkr_player() {
static const uint16 pcspkrFlats[8] = {1435, 1279, 2342, 2150, 1916, 1755, 1611}; // The flats, Ab to Bb
// Does the user not want any sound?
- if (!_vm->_config.soundFl || !_vm->_mixer->isReady())
+ if (!_vm->_config._soundFl || !_vm->_mixer->isReady())
return;
// Is there no song?
diff --git a/engines/hugo/sound.h b/engines/hugo/sound.h
index cb6d4e3168..b00d93eeb1 100644
--- a/engines/hugo/sound.h
+++ b/engines/hugo/sound.h
@@ -97,7 +97,7 @@ private:
void stopSound();
void stopMusic();
- void playMIDI(sound_pt seq_p, uint16 size);
+ void playMIDI(SoundPtr seqPtr, uint16 size);
};
} // End of namespace Hugo
diff --git a/engines/kyra/animator_hof.cpp b/engines/kyra/animator_hof.cpp
index 5a2378f4d0..59112504d6 100644
--- a/engines/kyra/animator_hof.cpp
+++ b/engines/kyra/animator_hof.cpp
@@ -104,9 +104,7 @@ void KyraEngine_HoF::refreshAnimObjects(int force) {
if (height + y > 143)
height -= height + y - 144;
- _screen->hideMouse();
_screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK);
- _screen->showMouse();
curObject->needRefresh = false;
}
diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp
index 29fa3aba80..83e774e2fc 100644
--- a/engines/kyra/animator_mr.cpp
+++ b/engines/kyra/animator_mr.cpp
@@ -175,9 +175,7 @@ void KyraEngine_MR::refreshAnimObjects(int force) {
height -= height + y - (maxY + 1);
if (height > 0) {
- _screen->hideMouse();
_screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK);
- _screen->showMouse();
}
curObject->needRefresh = false;
@@ -209,9 +207,7 @@ void KyraEngine_MR::updateItemAnimations() {
nextFrame = true;
_screen->drawShape(2, getShapePtr(422 + i), 9, 0, 0, 0);
_screen->drawShape(2, getShapePtr(shpIdx), 9, 0, 0, 0);
- _screen->hideMouse();
_screen->copyRegion(9, 0, _inventoryX[i], _inventoryY[i], 24, 20, 2, 0, Screen::CR_NO_P_CHECK);
- _screen->showMouse();
}
}
}
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index 884fca659b..79ef11e7a9 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -159,7 +159,7 @@ const KYRAGameDescription adGameDescs[] = {
},
KYRA1_FLOPPY_FLAGS
},
- {
+ { // russian fan translation
{
"kyra1",
"Extracted",
diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp
index c1bfee066f..36fbb0b40a 100644
--- a/engines/kyra/gui_hof.cpp
+++ b/engines/kyra/gui_hof.cpp
@@ -121,14 +121,12 @@ int KyraEngine_HoF::buttonInventory(Button *button) {
if (_itemInHand == kItemNone) {
if (item == kItemNone)
return 0;
- _screen->hideMouse();
clearInventorySlot(inventorySlot, 0);
snd_playSoundEffect(0x0B);
setMouseCursor(item);
int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7;
updateCommandLineEx(item+54, string, 0xD6);
_itemInHand = (int16)item;
- _screen->showMouse();
_mainCharacter.inventory[inventorySlot] = kItemNone;
} else {
if (_mainCharacter.inventory[inventorySlot] != kItemNone) {
@@ -137,23 +135,19 @@ int KyraEngine_HoF::buttonInventory(Button *button) {
item = _mainCharacter.inventory[inventorySlot];
snd_playSoundEffect(0x0B);
- _screen->hideMouse();
clearInventorySlot(inventorySlot, 0);
drawInventoryShape(0, _itemInHand, inventorySlot);
setMouseCursor(item);
int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7;
updateCommandLineEx(item+54, string, 0xD6);
- _screen->showMouse();
_mainCharacter.inventory[inventorySlot] = _itemInHand;
setHandItem(item);
} else {
snd_playSoundEffect(0x0C);
- _screen->hideMouse();
drawInventoryShape(0, _itemInHand, inventorySlot);
_screen->setMouseCursor(0, 0, getShapePtr(0));
int string = (_lang == 1) ? getItemCommandStringInv(_itemInHand) : 8;
updateCommandLineEx(_itemInHand+54, string, 0xD6);
- _screen->showMouse();
_mainCharacter.inventory[inventorySlot] = _itemInHand;
_itemInHand = kItemNone;
}
@@ -172,9 +166,7 @@ int KyraEngine_HoF::scrollInventory(Button *button) {
memcpy(src+5, dst, sizeof(Item)*5);
memcpy(dst, dst+5, sizeof(Item)*5);
memcpy(dst+5, temp, sizeof(Item)*5);
- _screen->hideMouse();
_screen->copyRegion(0x46, 0x90, 0x46, 0x90, 0x71, 0x2E, 0, 2);
- _screen->showMouse();
redrawInventory(2);
scrollInventoryWheel();
return 0;
@@ -199,9 +191,7 @@ int KyraEngine_HoF::findFreeVisibleInventorySlot() {
void KyraEngine_HoF::removeSlotFromInventory(int slot) {
_mainCharacter.inventory[slot] = kItemNone;
if (slot < 10) {
- _screen->hideMouse();
clearInventorySlot(slot, 0);
- _screen->showMouse();
}
}
@@ -223,15 +213,12 @@ bool KyraEngine_HoF::checkInventoryItemExchange(Item handItem, int slot) {
snd_playSoundEffect(0x68);
_mainCharacter.inventory[slot] = newItem;
- _screen->hideMouse();
clearInventorySlot(slot, 0);
drawInventoryShape(0, newItem, slot);
if (removeItem)
removeHandItem();
- _screen->showMouse();
-
if (_lang != 1)
updateCommandLineEx(newItem+54, 0x2E, 0xD6);
@@ -243,12 +230,10 @@ bool KyraEngine_HoF::checkInventoryItemExchange(Item handItem, int slot) {
void KyraEngine_HoF::drawInventoryShape(int page, Item item, int slot) {
_screen->drawShape(page, getShapePtr(item+64), _inventoryX[slot], _inventoryY[slot], 0, 0);
- _screen->updateScreen();
}
void KyraEngine_HoF::clearInventorySlot(int slot, int page) {
_screen->drawShape(page, getShapePtr(240+slot), _inventoryX[slot], _inventoryY[slot], 0, 0);
- _screen->updateScreen();
}
void KyraEngine_HoF::redrawInventory(int page) {
@@ -256,7 +241,6 @@ void KyraEngine_HoF::redrawInventory(int page) {
_screen->_curPage = page;
const Item *inventory = _mainCharacter.inventory;
- _screen->hideMouse();
for (int i = 0; i < 10; ++i) {
clearInventorySlot(i, page);
if (inventory[i] != kItemNone) {
@@ -264,7 +248,6 @@ void KyraEngine_HoF::redrawInventory(int page) {
drawInventoryShape(page, inventory[i], i);
}
}
- _screen->showMouse();
_screen->updateScreen();
_screen->_curPage = pageBackUp;
@@ -277,17 +260,13 @@ void KyraEngine_HoF::scrollInventoryWheel() {
memcpy(_screenBuffer, _screen->getCPagePtr(2), 64000);
uint8 overlay[0x100];
_screen->generateOverlay(_screen->getPalette(0), overlay, 0, 50);
- _screen->hideMouse();
_screen->copyRegion(0x46, 0x90, 0x46, 0x79, 0x71, 0x17, 0, 2, Screen::CR_NO_P_CHECK);
- _screen->showMouse();
snd_playSoundEffect(0x25);
bool breakFlag = false;
for (int i = 0; i <= 6 && !breakFlag; ++i) {
if (movie.opened()) {
- _screen->hideMouse();
movie.displayFrame(i % frames, 0, 0, 0, 0, 0, 0);
- _screen->showMouse();
_screen->updateScreen();
}
@@ -355,9 +334,7 @@ int KyraEngine_HoF::bookButton(Button *button) {
_bookNewPage = _bookCurPage;
if (_screenBuffer) {
- _screen->hideMouse();
memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000);
- _screen->showMouse();
}
_screen->copyPalette(2, 0);
@@ -382,9 +359,7 @@ int KyraEngine_HoF::bookButton(Button *button) {
restorePage3();
if (_screenBuffer) {
- _screen->hideMouse();
_screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer);
- _screen->showMouse();
}
setHandItem(_itemInHand);
@@ -471,7 +446,6 @@ void KyraEngine_HoF::showBookPage() {
int rightPageY = _bookPageYOffset[_bookCurPage+1];
- _screen->hideMouse();
if (leftPage) {
bookDecodeText(leftPage);
bookPrintText(2, leftPage, 20, leftPageY+20, 0x31);
@@ -483,7 +457,6 @@ void KyraEngine_HoF::showBookPage() {
bookPrintText(2, rightPage, 176, rightPageY+20, 0x31);
delete[] rightPage;
}
- _screen->showMouse();
}
void KyraEngine_HoF::bookLoop() {
@@ -517,10 +490,8 @@ void KyraEngine_HoF::bookLoop() {
loadBookBkgd();
showBookPage();
snd_playSoundEffect(0x64);
- _screen->hideMouse();
_screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
- _screen->showMouse();
}
_system->delayMillis(10);
}
@@ -550,9 +521,7 @@ void KyraEngine_HoF::bookPrintText(int dstPage, const uint8 *str, int x, int y,
Screen::FontId oldFont = _screen->setFont(_flags.lang == Common::JA_JPN ? Screen::FID_SJIS_FNT : Screen::FID_BOOKFONT_FNT);
_screen->_charWidth = -2;
- _screen->hideMouse();
_screen->printText((const char *)str, x, y, color, (_flags.lang == Common::JA_JPN) ? 0xf6 : 0);
- _screen->showMouse();
_screen->_charWidth = 0;
_screen->setFont(oldFont);
@@ -679,9 +648,7 @@ int GUI_HoF::optionsButton(Button *button) {
_restartGame = false;
_reloadTemporarySave = false;
- _screen->hideMouse();
updateButton(&_vm->_inventoryButtons[0]);
- _screen->showMouse();
if (!_screen->isMouseVisible() && button)
return 0;
@@ -690,9 +657,7 @@ int GUI_HoF::optionsButton(Button *button) {
if (_vm->_mouseState < -1) {
_vm->_mouseState = -1;
- _screen->hideMouse();
_screen->setMouseCursor(1, 1, _vm->getShapePtr(0));
- _screen->showMouse();
return 0;
}
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index b4e5148b64..8e18ff910d 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -48,19 +48,16 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
snd_playSoundEffect(0x36);
return 0;
} else {
- _screen->hideMouse();
_screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
snd_playSoundEffect(0x35);
setMouseItem(inventoryItem);
updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179);
_itemInHand = inventoryItem;
- _screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = kItemNone;
}
} else {
if (inventoryItem != kItemNone) {
snd_playSoundEffect(0x35);
- _screen->hideMouse();
_screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
_screen->drawShape(0, _shapes[216 + _itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
setMouseItem(inventoryItem);
@@ -69,16 +66,13 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179);
else
updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[1], 179);
- _screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = _itemInHand;
_itemInHand = inventoryItem;
} else {
snd_playSoundEffect(0x32);
- _screen->hideMouse();
_screen->drawShape(0, _shapes[216 + _itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
_screen->setMouseCursor(1, 1, _shapes[0]);
updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _placedList[0], 179);
- _screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = _itemInHand;
_itemInHand = kItemNone;
}
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index e88b7fdffb..37526f9a5f 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -104,7 +104,6 @@ int KyraEngine_MR::callbackButton3(Button *button) {
void KyraEngine_MR::showMessage(const char *string, uint8 c0, uint8 c1) {
_shownMessage = string;
- _screen->hideMouse();
restoreCommandLine();
_restoreCommandLine = false;
@@ -118,8 +117,6 @@ void KyraEngine_MR::showMessage(const char *string, uint8 c0, uint8 c1) {
_screen->updateScreen();
setCommandLineRestoreTimer(7);
}
-
- _screen->showMouse();
}
void KyraEngine_MR::showMessageFromCCode(int string, uint8 c0, int) {
@@ -330,10 +327,8 @@ void KyraEngine_MR::drawMalcolmsMoodText() {
_screen->_curPage = 2;
}
- _screen->hideMouse();
_screen->drawShape(_screen->_curPage, getShapePtr(432), 244, 189, 0, 0);
_text->printText(string, x, y+1, 0xFF, 0xF0, 0x00);
- _screen->showMouse();
_screen->_curPage = pageBackUp;
}
@@ -441,7 +436,6 @@ void KyraEngine_MR::redrawInventory(int page) {
int pageBackUp = _screen->_curPage;
_screen->_curPage = page;
- _screen->hideMouse();
for (int i = 0; i < 10; ++i) {
clearInventorySlot(i, page);
@@ -451,7 +445,6 @@ void KyraEngine_MR::redrawInventory(int page) {
}
}
- _screen->showMouse();
_screen->_curPage = pageBackUp;
if (page == 0 || page == 1)
@@ -489,14 +482,12 @@ int KyraEngine_MR::buttonInventory(Button *button) {
if (slotItem == kItemNone)
return 0;
- _screen->hideMouse();
clearInventorySlot(slot, 0);
snd_playSoundEffect(0x0B, 0xC8);
setMouseCursor(slotItem);
updateItemCommand(slotItem, (_lang == 1) ? getItemCommandStringPickUp(slotItem) : 0, 0xFF);
_itemInHand = slotItem;
_mainCharacter.inventory[slot] = kItemNone;
- _screen->showMouse();
} else if (_itemInHand == 27) {
if (_chatText)
return 0;
@@ -508,21 +499,17 @@ int KyraEngine_MR::buttonInventory(Button *button) {
snd_playSoundEffect(0x0B, 0xC8);
- _screen->hideMouse();
clearInventorySlot(slot, 0);
drawInventorySlot(0, _itemInHand, slot);
setMouseCursor(slotItem);
updateItemCommand(slotItem, (_lang == 1) ? getItemCommandStringPickUp(slotItem) : 0, 0xFF);
_mainCharacter.inventory[slot] = _itemInHand;
_itemInHand = slotItem;
- _screen->showMouse();
} else {
snd_playSoundEffect(0x0C, 0xC8);
- _screen->hideMouse();
drawInventorySlot(0, _itemInHand, slot);
_screen->setMouseCursor(0, 0, getShapePtr(0));
updateItemCommand(_itemInHand, (_lang == 1) ? getItemCommandStringInv(_itemInHand) : 2, 0xFF);
- _screen->showMouse();
_mainCharacter.inventory[slot] = _itemInHand;
_itemInHand = kItemNone;
}
@@ -624,22 +611,18 @@ int KyraEngine_MR::buttonShowScore(Button *button) {
int KyraEngine_MR::buttonJesterStaff(Button *button) {
makeCharFacingMouse();
if (_itemInHand == 27) {
- _screen->hideMouse();
removeHandItem();
snd_playSoundEffect(0x0C, 0xC8);
drawJestersStaff(1, 0);
updateItemCommand(27, 2, 0xFF);
setGameFlag(0x97);
- _screen->showMouse();
} else if (_itemInHand == kItemNone) {
if (queryGameFlag(0x97)) {
- _screen->hideMouse();
snd_playSoundEffect(0x0B, 0xC8);
setHandItem(27);
drawJestersStaff(0, 0);
updateItemCommand(27, 0, 0xFF);
resetGameFlag(0x97);
- _screen->showMouse();
} else {
if (queryGameFlag(0x2F))
objectChat((const char *)getTableEntry(_cCodeFile, 20), 0, 204, 20);
@@ -1108,9 +1091,7 @@ int GUI_MR::redrawButtonCallback(Button *button) {
if (!_displayMenu)
return 0;
- _screen->hideMouse();
_screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xD0);
- _screen->showMouse();
return 0;
}
@@ -1119,9 +1100,7 @@ int GUI_MR::redrawShadedButtonCallback(Button *button) {
if (!_displayMenu)
return 0;
- _screen->hideMouse();
_screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xD1, 0xCF);
- _screen->showMouse();
return 0;
}
@@ -1162,9 +1141,7 @@ int GUI_MR::quitGame(Button *caller) {
int GUI_MR::optionsButton(Button *button) {
PauseTimer pause(*_vm->_timer);
- _screen->hideMouse();
updateButton(&_vm->_mainButtonData[0]);
- _screen->showMouse();
if (!_vm->_inventoryState && button && !_vm->_menuDirectlyToLoad)
return 0;
@@ -1179,9 +1156,7 @@ int GUI_MR::optionsButton(Button *button) {
if (_vm->_mouseState < -1) {
_vm->_mouseState = -1;
- _screen->hideMouse();
_screen->setMouseCursor(1, 1, _vm->getShapePtr(0));
- _screen->showMouse();
return 0;
}
diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp
index f3459ddfe3..cec6562dd9 100644
--- a/engines/kyra/gui_v1.cpp
+++ b/engines/kyra/gui_v1.cpp
@@ -70,8 +70,6 @@ void GUI_v1::initMenuLayout(Menu &menu) {
void GUI_v1::initMenu(Menu &menu) {
_menuButtonList = 0;
- _screen->hideMouse();
-
int textX;
int textY;
@@ -192,7 +190,6 @@ void GUI_v1::initMenu(Menu &menu) {
updateMenuButton(scrollDownButton);
}
- _screen->showMouse();
_screen->updateScreen();
}
@@ -309,10 +306,8 @@ void GUI_v1::updateMenuButton(Button *button) {
if (!_displayMenu)
return;
- _screen->hideMouse();
updateButton(button);
_screen->updateScreen();
- _screen->showMouse();
}
void GUI_v1::updateButton(Button *button) {
@@ -340,12 +335,10 @@ int GUI_v1::redrawButtonCallback(Button *button) {
if (!_displayMenu)
return 0;
- _screen->hideMouse();
if (_vm->gameFlags().platform == Common::kPlatformAmiga)
_screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17);
else
_screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
- _screen->showMouse();
return 0;
}
@@ -354,12 +347,10 @@ int GUI_v1::redrawShadedButtonCallback(Button *button) {
if (!_displayMenu)
return 0;
- _screen->hideMouse();
if (_vm->gameFlags().platform == Common::kPlatformAmiga)
_screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18);
else
_screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
- _screen->showMouse();
return 0;
}
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index 65f8bd45e5..1df4149d2e 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -105,15 +105,11 @@ void GUI_v2::processButton(Button *button) {
switch (val1 - 1) {
case 0:
- _screen->hideMouse();
_screen->drawShape(_screen->_curPage, dataPtr, x, y, button->dimTableIndex, 0x10);
- _screen->showMouse();
break;
case 1:
- _screen->hideMouse();
_screen->printText((const char *)dataPtr, x, y, val2, val3);
- _screen->showMouse();
break;
case 3:
@@ -122,22 +118,16 @@ void GUI_v2::processButton(Button *button) {
break;
case 4:
- _screen->hideMouse();
_screen->drawBox(x, y, x2, y2, val2);
- _screen->showMouse();
break;
case 5:
- _screen->hideMouse();
_screen->fillRect(x, y, x2, y2, val2, -1, true);
- _screen->showMouse();
break;
default:
break;
}
-
- _screen->updateScreen();
}
int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseWheel) {
diff --git a/engines/kyra/items_hof.cpp b/engines/kyra/items_hof.cpp
index 711e1b8f7c..ef2c50c0c5 100644
--- a/engines/kyra/items_hof.cpp
+++ b/engines/kyra/items_hof.cpp
@@ -300,8 +300,6 @@ void KyraEngine_HoF::itemDropDown(int startX, int startY, int dstX, int dstY, in
}
void KyraEngine_HoF::exchangeMouseItem(int itemPos) {
- _screen->hideMouse();
-
deleteItemAnimEntry(itemPos);
int itemId = _itemList[itemPos].id;
@@ -317,7 +315,6 @@ void KyraEngine_HoF::exchangeMouseItem(int itemPos) {
str2 = getItemCommandStringPickUp(itemId);
updateCommandLineEx(itemId + 54, str2, 0xD6);
- _screen->showMouse();
runSceneScript6();
}
@@ -331,7 +328,6 @@ bool KyraEngine_HoF::pickUpItem(int x, int y) {
if (_itemInHand >= 0) {
exchangeMouseItem(itemPos);
} else {
- _screen->hideMouse();
deleteItemAnimEntry(itemPos);
int itemId = _itemList[itemPos].id;
_itemList[itemPos].id = kItemNone;
@@ -344,7 +340,6 @@ bool KyraEngine_HoF::pickUpItem(int x, int y) {
updateCommandLineEx(itemId + 54, str2, 0xD6);
_itemInHand = itemId;
- _screen->showMouse();
runSceneScript6();
}
diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp
index 2937038463..b92cd616c1 100644
--- a/engines/kyra/items_lok.cpp
+++ b/engines/kyra/items_lok.cpp
@@ -163,17 +163,13 @@ void KyraEngine_LoK::placeItemInGenericMapScene(int item, int index) {
}
void KyraEngine_LoK::setHandItem(Item item) {
- _screen->hideMouse();
setMouseItem(item);
_itemInHand = item;
- _screen->showMouse();
}
void KyraEngine_LoK::removeHandItem() {
- _screen->hideMouse();
_screen->setMouseCursor(1, 1, _shapes[0]);
_itemInHand = kItemNone;
- _screen->showMouse();
}
void KyraEngine_LoK::setMouseItem(Item item) {
@@ -415,7 +411,6 @@ int KyraEngine_LoK::processItemDrop(uint16 sceneId, uint8 item, int x, int y, in
}
void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) {
- _screen->hideMouse();
_animator->animRemoveGameItem(itemIndex);
assert(sceneId < _roomTableSize);
Room *currentRoom = &_roomTable[sceneId];
@@ -432,7 +427,6 @@ void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) {
updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[0], 179);
else
updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[1], 179);
- _screen->showMouse();
clickEventHandler2();
}
@@ -720,9 +714,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) {
_itemInHand = kItemNone;
} else {
_characterList[0].inventoryItems[itemPos] = kItemNone;
- _screen->hideMouse();
_screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0);
- _screen->showMouse();
}
_screen->showMouse();
@@ -793,9 +785,7 @@ void KyraEngine_LoK::magicInMouseItem(int animIndex, int item, int itemPos) {
_itemInHand = item;
} else {
_characterList[0].inventoryItems[itemPos] = item;
- _screen->hideMouse();
_screen->drawShape(0, _shapes[216 + item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0);
- _screen->showMouse();
}
_screen->showMouse();
_screen->_curPage = videoPageBackUp;
@@ -846,9 +836,7 @@ void KyraEngine_LoK::updatePlayerItemsForScene() {
++_itemInHand;
if (_itemInHand > 33)
_itemInHand = 33;
- _screen->hideMouse();
_screen->setMouseCursor(8, 15, _shapes[216 + _itemInHand]);
- _screen->showMouse();
}
bool redraw = false;
@@ -864,9 +852,7 @@ void KyraEngine_LoK::updatePlayerItemsForScene() {
}
if (redraw) {
- _screen->hideMouse();
redrawInventory(0);
- _screen->showMouse();
}
if (_itemInHand == 33)
@@ -884,7 +870,6 @@ void KyraEngine_LoK::updatePlayerItemsForScene() {
void KyraEngine_LoK::redrawInventory(int page) {
int videoPageBackUp = _screen->_curPage;
_screen->_curPage = page;
- _screen->hideMouse();
for (int i = 0; i < 10; ++i) {
_screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, page);
@@ -893,7 +878,6 @@ void KyraEngine_LoK::redrawInventory(int page) {
_screen->drawShape(page, _shapes[216 + item], _itemPosX[i], _itemPosY[i], 0, 0);
}
}
- _screen->showMouse();
_screen->_curPage = videoPageBackUp;
_screen->updateScreen();
}
diff --git a/engines/kyra/items_mr.cpp b/engines/kyra/items_mr.cpp
index c731627026..029f676538 100644
--- a/engines/kyra/items_mr.cpp
+++ b/engines/kyra/items_mr.cpp
@@ -319,7 +319,6 @@ void KyraEngine_MR::exchangeMouseItem(int itemPos, int runScript) {
return;
}
- _screen->hideMouse();
deleteItemAnimEntry(itemPos);
Item itemId = _itemList[itemPos].id;
@@ -335,7 +334,6 @@ void KyraEngine_MR::exchangeMouseItem(int itemPos, int runScript) {
str2 = getItemCommandStringPickUp(itemId);
updateItemCommand(itemId, str2, 0xFF);
- _screen->showMouse();
if (runScript)
runSceneScript6();
@@ -350,7 +348,6 @@ bool KyraEngine_MR::pickUpItem(int x, int y, int runScript) {
if (_itemInHand >= 0) {
exchangeMouseItem(itemPos, runScript);
} else {
- _screen->hideMouse();
deleteItemAnimEntry(itemPos);
Item itemId = _itemList[itemPos].id;
_itemList[itemPos].id = kItemNone;
@@ -363,7 +360,6 @@ bool KyraEngine_MR::pickUpItem(int x, int y, int runScript) {
updateItemCommand(itemId, itemString, 0xFF);
_itemInHand = itemId;
- _screen->showMouse();
if (runScript)
runSceneScript6();
@@ -401,7 +397,6 @@ bool KyraEngine_MR::itemListMagic(Item handItem, int itemSlot) {
assert(animObjIndex != -1);
- _screen->hideMouse();
snd_playSoundEffect(0x93, 0xC8);
for (int i = 109; i <= 141; ++i) {
_animObjects[animObjIndex].shapeIndex1 = i+248;
@@ -411,7 +406,6 @@ bool KyraEngine_MR::itemListMagic(Item handItem, int itemSlot) {
deleteItemAnimEntry(itemSlot);
_itemList[itemSlot].id = kItemNone;
- _screen->showMouse();
return true;
}
@@ -440,7 +434,6 @@ bool KyraEngine_MR::itemListMagic(Item handItem, int itemSlot) {
_itemList[itemSlot].id = (int8)resItem;
- _screen->hideMouse();
deleteItemAnimEntry(itemSlot);
addItemToAnimList(itemSlot);
@@ -448,7 +441,6 @@ bool KyraEngine_MR::itemListMagic(Item handItem, int itemSlot) {
removeHandItem();
else if (newItem != 0xFF)
setHandItem(newItem);
- _screen->showMouse();
if (_lang != 1)
updateItemCommand(resItem, 3, 0xFF);
@@ -500,7 +492,6 @@ bool KyraEngine_MR::itemInventoryMagic(Item handItem, int invSlot) {
_mainCharacter.inventory[invSlot] = (int8)resItem;
- _screen->hideMouse();
clearInventorySlot(invSlot, 0);
drawInventorySlot(0, resItem, invSlot);
@@ -508,7 +499,6 @@ bool KyraEngine_MR::itemInventoryMagic(Item handItem, int invSlot) {
removeHandItem();
else if (newItem != 0xFF)
setHandItem(newItem);
- _screen->showMouse();
if (_lang != 1)
updateItemCommand(resItem, 3, 0xFF);
diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp
index c191c2e62b..2145a2c2f0 100644
--- a/engines/kyra/items_v2.cpp
+++ b/engines/kyra/items_v2.cpp
@@ -82,26 +82,19 @@ void KyraEngine_v2::resetItem(int index) {
}
void KyraEngine_v2::setHandItem(Item item) {
- Screen *scr = screen();
- scr->hideMouse();
-
if (item == kItemNone) {
removeHandItem();
} else {
setMouseCursor(item);
_itemInHand = item;
}
-
- scr->showMouse();
}
void KyraEngine_v2::removeHandItem() {
Screen *scr = screen();
- scr->hideMouse();
scr->setMouseCursor(0, 0, getShapePtr(0));
_itemInHand = kItemNone;
_mouseState = kItemNone;
- scr->showMouse();
}
} // end of namesapce Kyra
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 0ba173d9d0..7fbecb7f53 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -419,8 +419,6 @@ void KyraEngine_HoF::startup() {
_screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
_screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0);
_screen->copyPage(3, 0);
- _screen->showMouse();
- _screen->hideMouse();
clearAnimObjects();
@@ -784,20 +782,16 @@ void KyraEngine_HoF::updateMouse() {
if (type != 0 && _mouseState != type && _screen->isMouseVisible()) {
_mouseState = type;
- _screen->hideMouse();
_screen->setMouseCursor(xOffset, yOffset, getShapePtr(shapeIndex));
- _screen->showMouse();
}
if (type == 0 && _mouseState != _itemInHand && _screen->isMouseVisible()) {
if ((mouse.y > 145) || (mouse.x > 6 && mouse.x < 312 && mouse.y > 6 && mouse.y < 135)) {
_mouseState = _itemInHand;
- _screen->hideMouse();
if (_itemInHand == kItemNone)
_screen->setMouseCursor(0, 0, getShapePtr(0));
else
_screen->setMouseCursor(8, 15, getShapePtr(_itemInHand+64));
- _screen->showMouse();
}
}
}
@@ -914,7 +908,6 @@ void KyraEngine_HoF::showMessageFromCCode(int id, int16 palIndex, int) {
void KyraEngine_HoF::showMessage(const char *string, int16 palIndex) {
_shownMessage = string;
- _screen->hideMouse();
_screen->fillRect(0, 190, 319, 199, 0xCF);
if (string) {
@@ -932,7 +925,6 @@ void KyraEngine_HoF::showMessage(const char *string, int16 palIndex) {
}
_fadeMessagePalette = false;
- _screen->showMouse();
}
void KyraEngine_HoF::showChapterMessage(int id, int16 palIndex) {
@@ -1116,9 +1108,7 @@ int KyraEngine_HoF::getDrawLayer(int x, int y) {
void KyraEngine_HoF::backUpPage0() {
if (_screenBuffer) {
- _screen->hideMouse();
memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000);
- _screen->showMouse();
}
}
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index ece4a0daba..27bc2ad22a 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -454,10 +454,8 @@ void KyraEngine_LoK::mainLoop() {
if (_deathHandler != -1) {
snd_playWanderScoreViaMap(0, 1);
snd_playSoundEffect(49);
- _screen->hideMouse();
_screen->setMouseCursor(1, 1, _shapes[0]);
removeHandItem();
- _screen->showMouse();
_gui->buttonMenuCallback(0);
_deathHandler = -1;
}
@@ -706,7 +704,6 @@ int KyraEngine_LoK::processInputHelper(int xpos, int ypos) {
uint8 item = findItemAtPos(xpos, ypos);
if (item != 0xFF) {
if (_itemInHand == kItemNone) {
- _screen->hideMouse();
_animator->animRemoveGameItem(item);
snd_playSoundEffect(53);
assert(_currentCharacter->sceneId < _roomTableSize);
@@ -717,7 +714,6 @@ int KyraEngine_LoK::processInputHelper(int xpos, int ypos) {
assert(_itemList && _takenList);
updateSentenceCommand(_itemList[getItemListIndex(item2)], _takenList[0], 179);
_itemInHand = item2;
- _screen->showMouse();
clickEventHandler2();
return 1;
} else {
@@ -834,21 +830,17 @@ void KyraEngine_LoK::updateMousePointer(bool forceUpdate) {
if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) {
_mouseState = newMouseState;
- _screen->hideMouse();
_screen->setMouseCursor(newX, newY, _shapes[shape]);
- _screen->showMouse();
}
if (!newMouseState) {
if (_mouseState != _itemInHand || forceUpdate) {
if (mouse.y > 158 || (mouse.x >= 12 && mouse.x < 308 && mouse.y < 136 && mouse.y >= 12) || forceUpdate) {
_mouseState = _itemInHand;
- _screen->hideMouse();
if (_itemInHand == kItemNone)
_screen->setMouseCursor(1, 1, _shapes[0]);
else
_screen->setMouseCursor(8, 15, _shapes[216 + _itemInHand]);
- _screen->showMouse();
}
}
}
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 39ed0d038a..448e4ef70d 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -1298,7 +1298,6 @@ bool KyraEngine_MR::updateScore(int scoreId, int strId) {
setNextIdleAnimTimer();
_scoreFlagTable[scoreIndex] |= (1 << scoreBit);
- _screen->hideMouse();
strcpy(_stringBuffer, (const char *)getTableEntry(_scoreFile, strId));
strcat(_stringBuffer, ": ");
@@ -1308,7 +1307,6 @@ bool KyraEngine_MR::updateScore(int scoreId, int strId) {
if (count > 0)
scoreIncrease(count, _stringBuffer);
- _screen->showMouse();
setNextIdleAnimTimer();
return true;
}
diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp
index 75b568a00a..848fb18b6a 100644
--- a/engines/kyra/kyra_v2.cpp
+++ b/engines/kyra/kyra_v2.cpp
@@ -198,8 +198,6 @@ void KyraEngine_v2::moveCharacter(int facing, int x, int y) {
y &= ~1;
_mainCharacter.facing = facing;
- Screen *scr = screen();
- scr->hideMouse();
switch (facing) {
case 0:
while (_mainCharacter.y1 > y)
@@ -224,7 +222,6 @@ void KyraEngine_v2::moveCharacter(int facing, int x, int y) {
default:
break;
}
- scr->showMouse();
}
void KyraEngine_v2::updateCharPosWithUpdate() {
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 711fe15348..4fd5985a09 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -1128,8 +1128,6 @@ void Screen::drawBox(int x1, int y1, int x2, int y2, int color) {
void Screen::drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2) {
assert(x1 >= 0 && y1 >= 0);
- hideMouse();
-
fillRect(x1, y1, x2, y1 + 1, color1);
fillRect(x2 - 1, y1, x2, y2, color1);
@@ -1137,8 +1135,6 @@ void Screen::drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color
drawClippedLine(x1 + 1, y1 + 1, x1 + 1, y2 - 1, color2);
drawClippedLine(x1, y2 - 1, x2 - 1, y2 - 1, color2);
drawClippedLine(x1, y2, x2, y2, color2);
-
- showMouse();
}
void Screen::drawClippedLine(int x1, int y1, int x2, int y2, int color) {
diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp
index f32a898dd9..f028f93294 100644
--- a/engines/kyra/screen_lok.cpp
+++ b/engines/kyra/screen_lok.cpp
@@ -190,7 +190,6 @@ void Screen_LoK::copyBackgroundBlock(int x, int page, int flag) {
_curPage = page;
int curX = x;
- hideMouse();
copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2);
for (int i = 0; i < 19; ++i) {
int tempX = curX + 1;
@@ -208,7 +207,6 @@ void Screen_LoK::copyBackgroundBlock(int x, int page, int flag) {
curX = curX % 38;
}
}
- showMouse();
_curPage = oldVideoPage;
}
diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp
index b80b8105a1..fca83ae632 100644
--- a/engines/kyra/script_hof.cpp
+++ b/engines/kyra/script_hof.cpp
@@ -325,7 +325,6 @@ int KyraEngine_HoF::o2_drawShape(EMCState *script) {
if (modeFlag) {
_screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0);
} else {
- _screen->hideMouse();
restorePage3();
_screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0);
memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080);
@@ -334,7 +333,6 @@ int KyraEngine_HoF::o2_drawShape(EMCState *script) {
flagAnimObjsForRefresh();
flagAnimObjsSpecialRefresh();
refreshAnimObjectsIfNeed();
- _screen->showMouse();
}
return 0;
@@ -492,7 +490,6 @@ int KyraEngine_HoF::o2_drawSceneShape(EMCState *script) {
int y = stackPos(2);
int flag = (stackPos(3) != 0) ? 1 : 0;
- _screen->hideMouse();
restorePage3();
_screen->drawShape(2, _sceneShapeTable[shape], x, y, 2, flag);
@@ -504,7 +501,6 @@ int KyraEngine_HoF::o2_drawSceneShape(EMCState *script) {
flagAnimObjsSpecialRefresh();
flagAnimObjsForRefresh();
refreshAnimObjectsIfNeed();
- _screen->showMouse();
return 0;
}
diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp
index 8342bccab6..db9e01cabb 100644
--- a/engines/kyra/script_lok.cpp
+++ b/engines/kyra/script_lok.cpp
@@ -157,7 +157,6 @@ int KyraEngine_LoK::o1_dropItemInScene(EMCState *script) {
int KyraEngine_LoK::o1_drawAnimShapeIntoScene(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
- _screen->hideMouse();
_animator->restoreAllObjectBackgrounds();
int shape = stackPos(0);
int xpos = stackPos(1);
@@ -169,7 +168,6 @@ int KyraEngine_LoK::o1_drawAnimShapeIntoScene(EMCState *script) {
_animator->preserveAnyChangedBackgrounds();
_animator->flagAllObjectsForRefresh();
_animator->updateAllObjectShapes();
- _screen->showMouse();
return 0;
}
@@ -1298,7 +1296,6 @@ int KyraEngine_LoK::o1_drawItemShapeIntoScene(EMCState *script) {
if (onlyHidPage) {
_screen->drawShape(2, _shapes[216 + item], x, y, 0, flags);
} else {
- _screen->hideMouse();
_animator->restoreAllObjectBackgrounds();
_screen->drawShape(2, _shapes[216 + item], x, y, 0, flags);
_screen->drawShape(0, _shapes[216 + item], x, y, 0, flags);
@@ -1306,7 +1303,6 @@ int KyraEngine_LoK::o1_drawItemShapeIntoScene(EMCState *script) {
_animator->preserveAnyChangedBackgrounds();
_animator->flagAllObjectsForRefresh();
_animator->updateAllObjectShapes();
- _screen->showMouse();
}
return 0;
}
diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp
index afe11aba02..22d0bc4e95 100644
--- a/engines/kyra/script_mr.cpp
+++ b/engines/kyra/script_mr.cpp
@@ -150,9 +150,7 @@ int KyraEngine_MR::o3_addItemToInventory(EMCState *script) {
if (slot >= 0) {
_mainCharacter.inventory[slot] = stackPos(0);
if (_inventoryState) {
- _screen->hideMouse();
redrawInventory(0);
- _screen->showMouse();
}
}
return slot;
@@ -330,7 +328,6 @@ int KyraEngine_MR::o3_drawSceneShape(EMCState *script) {
int shape = stackPos(0);
int flag = (stackPos(1) != 0) ? 1 : 0;
- _screen->hideMouse();
restorePage3();
const int x = _sceneShapeDescs[shape].drawX;
@@ -344,7 +341,6 @@ int KyraEngine_MR::o3_drawSceneShape(EMCState *script) {
flagAnimObjsForRefresh();
refreshAnimObjectsIfNeed();
- _screen->showMouse();
return 0;
}
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index dd49d6faaa..e63d0a7d8f 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -838,9 +838,7 @@ void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) {
if (newItem == -1)
return;
- _screen->hideMouse();
setMouseItem(newItem);
- _screen->showMouse();
_itemInHand = newItem;
assert(_fullFlask);
diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp
index 4a52d7d740..06067d6693 100644
--- a/engines/kyra/text_hof.cpp
+++ b/engines/kyra/text_hof.cpp
@@ -42,9 +42,7 @@ void TextDisplayer_HoF::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
void TextDisplayer_HoF::restoreScreen() {
_vm->restorePage3();
_vm->drawAnimObjects();
- _screen->hideMouse();
_screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, 2, 0, Screen::CR_NO_P_CHECK);
- _screen->showMouse();
_vm->flagAnimObjsForRefresh();
_vm->refreshAnimObjects(0);
}
@@ -58,8 +56,6 @@ void TextDisplayer_HoF::printCustomCharacterText(const char *text, int x, int y,
int x1 = 0, x2 = 0;
calcWidestLineBounds(x1, x2, w, x);
- _screen->hideMouse();
-
_talkCoords.x = x1;
_talkCoords.w = w+2;
_talkCoords.y = y;
@@ -78,7 +74,6 @@ void TextDisplayer_HoF::printCustomCharacterText(const char *text, int x, int y,
}
_screen->_curPage = curPageBackUp;
- _screen->showMouse();
}
char *TextDisplayer_HoF::preprocessString(const char *str) {
@@ -248,8 +243,6 @@ void KyraEngine_HoF::objectChatInit(const char *str, int object, int vocHigh, in
restorePage3();
_text->backupTalkTextMessageBkgd(2, 2);
- _screen->hideMouse();
-
_chatTextEnabled = textEnabled();
if (_chatTextEnabled) {
objectChatPrintText(str, object);
@@ -264,8 +257,6 @@ void KyraEngine_HoF::objectChatInit(const char *str, int object, int vocHigh, in
} else {
_chatVocHigh = _chatVocLow = -1;
}
-
- _screen->showMouse();
}
void KyraEngine_HoF::objectChatPrintText(const char *str, int object) {
diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp
index 62bdf18816..a557940868 100644
--- a/engines/kyra/text_lok.cpp
+++ b/engines/kyra/text_lok.cpp
@@ -296,10 +296,8 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu
_animator->restoreAllObjectBackgrounds();
_screen->copyRegion(12, _text->_talkMessageY, 12, 136, 296, _text->_talkMessageH, 2, 2);
- _screen->hideMouse();
_text->printCharacterText(processedString, charNum, _characterList[charNum].x1);
- _screen->showMouse();
}
if (chatDuration == -2)
@@ -317,10 +315,8 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu
_screen->copyRegion(12, 136, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 2);
_animator->preserveAllBackgrounds();
_animator->prepDrawAllObjects();
- _screen->hideMouse();
_screen->copyRegion(12, _text->_talkMessageY, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 0);
- _screen->showMouse();
_animator->flagAllObjectsForRefresh();
_animator->copyChangedObjectsForward(0);
}
@@ -332,7 +328,6 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu
}
void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) {
- _screen->hideMouse();
_screen->fillRect(8, 143, 311, 152, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
if (_flags.platform == Common::kPlatformAmiga) {
@@ -354,7 +349,6 @@ void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) {
}
_text->printText(sentence, 8, 143, 0xFF, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0);
- _screen->showMouse();
setTextFadeTimerCountdown(15);
_fadeText = false;
}
diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp
index b680e9c6f9..10b0880f29 100644
--- a/engines/kyra/text_mr.cpp
+++ b/engines/kyra/text_mr.cpp
@@ -145,9 +145,7 @@ void TextDisplayer_MR::printText(const char *str, int x, int y, uint8 c0, uint8
void TextDisplayer_MR::restoreScreen() {
_vm->restorePage3();
_vm->drawAnimObjects();
- _screen->hideMouse();
_screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, 2, 0, Screen::CR_NO_P_CHECK);
- _screen->showMouse();
_vm->flagAnimObjsForRefresh();
_vm->refreshAnimObjects(0);
}
@@ -261,8 +259,6 @@ void KyraEngine_MR::objectChatInit(const char *str, int object, int vocHigh, int
restorePage3();
- _screen->hideMouse();
-
_chatTextEnabled = textEnabled();
if (_chatTextEnabled) {
objectChatPrintText(str, object);
@@ -277,8 +273,6 @@ void KyraEngine_MR::objectChatInit(const char *str, int object, int vocHigh, int
} else {
_chatVocHigh = _chatVocLow = -1;
}
-
- _screen->showMouse();
}
void KyraEngine_MR::objectChatPrintText(const char *str, int object) {
diff --git a/engines/lastexpress/data/cursor.cpp b/engines/lastexpress/data/cursor.cpp
index 86a66b49d9..a3e7b773a7 100644
--- a/engines/lastexpress/data/cursor.cpp
+++ b/engines/lastexpress/data/cursor.cpp
@@ -93,7 +93,7 @@ void Cursor::setStyle(CursorStyle style) {
Graphics::PixelFormat pf = g_system->getScreenFormat();
CursorMan.replaceCursor((const byte *)getCursorImage(style),
32, 32, _cursors[style].hotspotX, _cursors[style].hotspotY,
- 0, 1, &pf);
+ 0, false, &pf);
}
const uint16 *Cursor::getCursorImage(CursorStyle style) const {
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index 3cf5ac740e..47a7d0225b 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -125,7 +125,7 @@ void MystCursorManager::setCursor(uint16 id) {
CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
} else {
Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
- CursorMan.replaceCursor((byte *)surface->pixels, surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), 1, &pixelFormat);
+ CursorMan.replaceCursor((byte *)surface->pixels, surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
}
_vm->_needsUpdate = true;
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index c22b30ad4d..0efd412bd0 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -252,8 +252,7 @@ Common::Error MohawkEngine_Myst::run() {
_gfx = new MystGraphics(this);
_console = new MystConsole(this);
_gameState = new MystGameState(this, _saveFileMan);
- _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"));
- _loadDialog->setSaveMode(false);
+ _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false);
_optionsDialog = new MystOptionsDialog(this);
_cursor = new MystCursorManager(this);
_rnd = new Common::RandomSource("myst");
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 07b1b59929..e54d6fefa2 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -713,19 +713,11 @@ void MohawkEngine_Riven::delayAndUpdate(uint32 ms) {
}
void MohawkEngine_Riven::runLoadDialog() {
- GUI::SaveLoadChooser slc(_("Load game:"), _("Load"));
- slc.setSaveMode(false);
+ GUI::SaveLoadChooser slc(_("Load game:"), _("Load"), false);
- Common::String gameId = ConfMan.get("gameid");
-
- const EnginePlugin *plugin = 0;
- EngineMan.findGame(gameId, &plugin);
-
- int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ int slot = slc.runModalWithCurrentTarget();
if (slot >= 0)
loadGameState(slot);
-
- slc.close();
}
Common::Error MohawkEngine_Riven::loadGameState(int slot) {
diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp
index c10b986c60..15103b2021 100644
--- a/engines/mohawk/video.cpp
+++ b/engines/mohawk/video.cpp
@@ -227,17 +227,19 @@ bool VideoManager::updateMovies() {
Graphics::Surface *convertedFrame = 0;
if (frame && _videoStreams[i].enabled) {
- // Convert from 8bpp to the current screen format if necessary
Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat();
- if (frame->format.bytesPerPixel == 1) {
- if (pixelFormat.bytesPerPixel == 1) {
- if (_videoStreams[i]->hasDirtyPalette())
- _videoStreams[i]->setSystemPalette();
- } else {
- convertedFrame = frame->convertTo(pixelFormat, _videoStreams[i]->getPalette());
- frame = convertedFrame;
- }
+ if (frame->format != pixelFormat) {
+ // We don't support downconverting to 8bpp
+ if (pixelFormat.bytesPerPixel == 1)
+ error("Cannot convert high color video frame to 8bpp");
+
+ // Convert to the current screen format
+ convertedFrame = frame->convertTo(pixelFormat, _videoStreams[i]->getPalette());
+ frame = convertedFrame;
+ } else if (pixelFormat.bytesPerPixel == 1 && _videoStreams[i]->hasDirtyPalette()) {
+ // Set the palette when running in 8bpp mode only
+ _videoStreams[i]->setSystemPalette();
}
// Clip the width/height to make sure we stay on the screen (Myst does this a few times)
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index 3ab25f203f..8de2d89b18 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -180,20 +180,13 @@ void SaveLoad_ns::doSaveGame(uint16 slot, const char* name) {
}
int SaveLoad::selectSaveFile(Common::String &selectedName, bool saveMode, const Common::String &caption, const Common::String &button) {
- GUI::SaveLoadChooser slc(caption, button);
- slc.setSaveMode(saveMode);
+ GUI::SaveLoadChooser slc(caption, button, saveMode);
selectedName.clear();
- Common::String gameId = ConfMan.get("gameid");
-
- const EnginePlugin *plugin = 0;
- EngineMan.findGame(gameId, &plugin);
-
- int idx = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ int idx = slc.runModalWithCurrentTarget();
if (idx >= 0) {
selectedName = slc.getResultString();
- slc.close();
}
return idx;
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 5b5301b468..94ac437a15 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -373,6 +373,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" animate_list / al - Shows the current list of objects in kAnimate's draw list (SCI0 - SCI1.1)\n");
DebugPrintf(" window_list / wl - Shows a list of all the windows (ports) in the draw list (SCI0 - SCI1.1)\n");
DebugPrintf(" plane_list / pl - Shows a list of all the planes in the draw list (SCI2+)\n");
+ DebugPrintf(" plane_items / pi - Shows a list of all items for a plane (SCI2+)\n");
DebugPrintf(" saved_bits - List saved bits on the hunk\n");
DebugPrintf(" show_saved_bits - Display saved bits\n");
DebugPrintf("\n");
@@ -1216,6 +1217,27 @@ bool Console::cmdRestartGame(int argc, const char **argv) {
return Cmd_Exit(0, 0);
}
+// The scripts get IDs ranging from 100->199, because the scripts require us to assign unique ids THAT EVEN STAY BETWEEN
+// SAVES and the scripts also use "saves-count + 1" to create a new savedgame slot.
+// SCI1.1 actually recycles ids, in that case we will currently get "0".
+// This behavior is required especially for LSL6. In this game, it's possible to quick save. The scripts will use
+// the last-used id for that feature. If we don't assign sticky ids, the feature will overwrite different saves all the
+// time. And sadly we can't just use the actual filename ids directly, because of the creation method for new slots.
+
+extern void listSavegames(Common::Array<SavegameDesc> &saves);
+
+bool Console::cmdListSaves(int argc, const char **argv) {
+ Common::Array<SavegameDesc> saves;
+ listSavegames(saves);
+
+ for (uint i = 0; i < saves.size(); i++) {
+ Common::String filename = g_sci->getSavegameName(saves[i].id);
+ DebugPrintf("%s: '%s'\n", filename.c_str(), saves[i].name);
+ }
+
+ return true;
+}
+
bool Console::cmdClassTable(int argc, const char **argv) {
DebugPrintf("Available classes (parse a parameter to filter the table by a specific class):\n");
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 506f79b4d8..6e66c48ff1 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -3744,53 +3744,61 @@ static const struct ADGameDescription SciGameDescriptions[] = {
#ifdef ENABLE_SCI32
// Torin's Passage - English Windows Interactive Demo
- // SCI interpreter version 2.100.002 (just a guess)
+ // SCI interpreter version 2.100.002
{"torin", "Demo", {
{"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403},
{"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
- // Torin's Passage - English Windows
- // SCI interpreter version 2.100.002 (just a guess)
+ // Torin's Passage (Multilingual) - English Windows CD
+ // SCI interpreter version 2.100.002
{"torin", "", {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
- // Torin's Passage - Spanish Windows (from jvprat)
+ // Torin's Passage (Multilingual) - Spanish Windows CD (from jvprat)
// Executable scanning reports "2.100.002", VERSION file reports "1.0"
{"torin", "", {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
// TODO: depend on one of the patches?
AD_LISTEND},
- Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
- // Torin's Passage - French Windows
- // SCI interpreter version 2.100.002 (just a guess)
+ // Torin's Passage (Multilingual) - French Windows CD
+ // SCI interpreter version 2.100.002
{"torin", "", {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
- // Torin's Passage - German Windows
- // SCI interpreter version 2.100.002 (just a guess)
+ // Torin's Passage (Multilingual) - German Windows CD
+ // SCI interpreter version 2.100.002
{"torin", "", {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
- Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+ Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
- // Torin's Passage - Italian Windows CD (from glorifindel)
- // SCI interpreter version 2.100.002 (just a guess)
+ // Torin's Passage (Multilingual) - Italian Windows CD (from glorifindel)
+ // SCI interpreter version 2.100.002
{"torin", "", {
{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
{"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887},
AD_LISTEND},
Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
+
+ // Torin's Passage - French Windows (from LePhilousophe)
+ // SCI interpreter version 2.100.002
+ {"torin", "", {
+ {"resmap.000", 0, "66ed46e3e56f487e688d52f05b33d0ba", 9787},
+ {"ressci.000", 0, "118f9bec04bfe17c4f87bbb5ddb43c18", 56126981},
+ AD_LISTEND},
+ Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) },
#endif // ENABLE_SCI32
// SCI Fanmade Games
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
new file mode 100644
index 0000000000..3470d23fe2
--- /dev/null
+++ b/engines/sci/engine/file.cpp
@@ -0,0 +1,451 @@
+/* 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/savefile.h"
+#include "common/stream.h"
+
+#include "sci/sci.h"
+#include "sci/engine/file.h"
+#include "sci/engine/kernel.h"
+#include "sci/engine/savegame.h"
+#include "sci/engine/selector.h"
+#include "sci/engine/state.h"
+
+namespace Sci {
+
+/*
+ * Note on how file I/O is implemented: In ScummVM, one can not create/write
+ * arbitrary data files, simply because many of our target platforms do not
+ * support this. The only files one can create are savestates. But SCI has an
+ * opcode to create and write to seemingly 'arbitrary' files. This is mainly
+ * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver, used
+ * for persisting the results of the "age quiz" across restarts) and in LSL5
+ * for MEMORY.DRV (which is again a game data file and contains the game's
+ * password, XOR encrypted).
+ * To implement that opcode, we combine the SaveFileManager with regular file
+ * code, similarly to how the SCUMM HE engine does it.
+ *
+ * To handle opening a file called "foobar", what we do is this: First, we
+ * create an 'augmented file name', by prepending the game target and a dash,
+ * so if we running game target sq1sci, the name becomes "sq1sci-foobar".
+ * Next, we check if such a file is known to the SaveFileManager. If so, we
+ * we use that for reading/writing, delete it, whatever.
+ *
+ * If no such file is present but we were only asked to *read* the file,
+ * we fallback to looking for a regular file called "foobar", and open that
+ * for reading only.
+ */
+
+reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename) {
+ Common::String englishName = g_sci->getSciLanguageString(filename, K_LANG_ENGLISH);
+ Common::String wrappedName = unwrapFilename ? g_sci->wrapFilename(englishName) : englishName;
+ Common::SeekableReadStream *inFile = 0;
+ Common::WriteStream *outFile = 0;
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
+
+ if (mode == _K_FILE_MODE_OPEN_OR_FAIL) {
+ // Try to open file, abort if not possible
+ inFile = saveFileMan->openForLoading(wrappedName);
+ // If no matching savestate exists: fall back to reading from a regular
+ // file
+ if (!inFile)
+ inFile = SearchMan.createReadStreamForMember(englishName);
+
+ if (!inFile)
+ debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str());
+ } else if (mode == _K_FILE_MODE_CREATE) {
+ // Create the file, destroying any content it might have had
+ outFile = saveFileMan->openForSaving(wrappedName);
+ if (!outFile)
+ debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str());
+ } else if (mode == _K_FILE_MODE_OPEN_OR_CREATE) {
+ // Try to open file, create it if it doesn't exist
+ outFile = saveFileMan->openForSaving(wrappedName);
+ if (!outFile)
+ debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str());
+
+ // QfG1 opens the character export file with _K_FILE_MODE_CREATE first,
+ // closes it immediately and opens it again with this here. Perhaps
+ // other games use this for read access as well. I guess changing this
+ // whole code into using virtual files and writing them after close
+ // would be more appropriate.
+ } else {
+ error("file_open: unsupported mode %d (filename '%s')", mode, englishName.c_str());
+ }
+
+ if (!inFile && !outFile) { // Failed
+ debugC(kDebugLevelFile, " -> file_open() failed");
+ return SIGNAL_REG;
+ }
+
+ // Find a free file handle
+ uint handle = 1; // Ignore _fileHandles[0]
+ while ((handle < s->_fileHandles.size()) && s->_fileHandles[handle].isOpen())
+ handle++;
+
+ if (handle == s->_fileHandles.size()) {
+ // Hit size limit => Allocate more space
+ s->_fileHandles.resize(s->_fileHandles.size() + 1);
+ }
+
+ s->_fileHandles[handle]._in = inFile;
+ s->_fileHandles[handle]._out = outFile;
+ s->_fileHandles[handle]._name = englishName;
+
+ debugC(kDebugLevelFile, " -> opened file '%s' with handle %d", englishName.c_str(), handle);
+ return make_reg(0, handle);
+}
+
+FileHandle *getFileFromHandle(EngineState *s, uint handle) {
+ if (handle == 0 || handle == VIRTUALFILE_HANDLE) {
+ error("Attempt to use invalid file handle (%d)", handle);
+ return 0;
+ }
+
+ if ((handle >= s->_fileHandles.size()) || !s->_fileHandles[handle].isOpen()) {
+ warning("Attempt to use invalid/unused file handle %d", handle);
+ return 0;
+ }
+
+ return &s->_fileHandles[handle];
+}
+
+int fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle) {
+ FileHandle *f = getFileFromHandle(s, handle);
+ if (!f)
+ return 0;
+
+ if (!f->_in) {
+ error("fgets_wrapper: Trying to read from file '%s' opened for writing", f->_name.c_str());
+ return 0;
+ }
+ int readBytes = 0;
+ if (maxsize > 1) {
+ memset(dest, 0, maxsize);
+ f->_in->readLine(dest, maxsize);
+ readBytes = strlen(dest); // FIXME: sierra sci returned byte count and didn't react on NUL characters
+ // The returned string must not have an ending LF
+ if (readBytes > 0) {
+ if (dest[readBytes - 1] == 0x0A)
+ dest[readBytes - 1] = 0;
+ }
+ } else {
+ *dest = 0;
+ }
+
+ debugC(kDebugLevelFile, " -> FGets'ed \"%s\"", dest);
+ return readBytes;
+}
+
+static bool _savegame_sort_byDate(const SavegameDesc &l, const SavegameDesc &r) {
+ if (l.date != r.date)
+ return (l.date > r.date);
+ return (l.time > r.time);
+}
+
+// Create a sorted array containing all found savedgames
+void listSavegames(Common::Array<SavegameDesc> &saves) {
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
+
+ // Load all saves
+ Common::StringArray saveNames = saveFileMan->listSavefiles(g_sci->getSavegamePattern());
+
+ for (Common::StringArray::const_iterator iter = saveNames.begin(); iter != saveNames.end(); ++iter) {
+ Common::String filename = *iter;
+ Common::SeekableReadStream *in;
+ if ((in = saveFileMan->openForLoading(filename))) {
+ SavegameMetadata meta;
+ if (!get_savegame_metadata(in, &meta) || meta.name.empty()) {
+ // invalid
+ delete in;
+ continue;
+ }
+ delete in;
+
+ SavegameDesc desc;
+ desc.id = strtol(filename.end() - 3, NULL, 10);
+ desc.date = meta.saveDate;
+ // We need to fix date in here, because we save DDMMYYYY instead of
+ // YYYYMMDD, so sorting wouldn't work
+ desc.date = ((desc.date & 0xFFFF) << 16) | ((desc.date & 0xFF0000) >> 8) | ((desc.date & 0xFF000000) >> 24);
+ desc.time = meta.saveTime;
+ desc.version = meta.version;
+
+ if (meta.name.lastChar() == '\n')
+ meta.name.deleteLastChar();
+
+ Common::strlcpy(desc.name, meta.name.c_str(), SCI_MAX_SAVENAME_LENGTH);
+
+ debug(3, "Savegame in file %s ok, id %d", filename.c_str(), desc.id);
+
+ saves.push_back(desc);
+ }
+ }
+
+ // Sort the list by creation date of the saves
+ Common::sort(saves.begin(), saves.end(), _savegame_sort_byDate);
+}
+
+// Find a savedgame according to virtualId and return the position within our array
+int findSavegame(Common::Array<SavegameDesc> &saves, int16 savegameId) {
+ for (uint saveNr = 0; saveNr < saves.size(); saveNr++) {
+ if (saves[saveNr].id == savegameId)
+ return saveNr;
+ }
+ return -1;
+}
+
+
+FileHandle::FileHandle() : _in(0), _out(0) {
+}
+
+FileHandle::~FileHandle() {
+ close();
+}
+
+void FileHandle::close() {
+ delete _in;
+ delete _out;
+ _in = 0;
+ _out = 0;
+ _name.clear();
+}
+
+bool FileHandle::isOpen() const {
+ return _in || _out;
+}
+
+
+void DirSeeker::addAsVirtualFiles(Common::String title, Common::String fileMask) {
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
+ Common::StringArray foundFiles = saveFileMan->listSavefiles(fileMask);
+ if (!foundFiles.empty()) {
+ _files.push_back(title);
+ _virtualFiles.push_back("");
+ Common::StringArray::iterator it;
+ Common::StringArray::iterator it_end = foundFiles.end();
+
+ for (it = foundFiles.begin(); it != it_end; it++) {
+ Common::String regularFilename = *it;
+ Common::String wrappedFilename = Common::String(regularFilename.c_str() + fileMask.size() - 1);
+
+ Common::SeekableReadStream *testfile = saveFileMan->openForLoading(regularFilename);
+ int32 testfileSize = testfile->size();
+ delete testfile;
+ if (testfileSize > 1024) // check, if larger than 1k. in that case its a saved game.
+ continue; // and we dont want to have those in the list
+ // We need to remove the prefix for display purposes
+ _files.push_back(wrappedFilename);
+ // but remember the actual name as well
+ _virtualFiles.push_back(regularFilename);
+ }
+ }
+}
+
+Common::String DirSeeker::getVirtualFilename(uint fileNumber) {
+ if (fileNumber >= _virtualFiles.size())
+ error("invalid virtual filename access");
+ return _virtualFiles[fileNumber];
+}
+
+reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) {
+ // Verify that we are given a valid buffer
+ if (!buffer.segment) {
+ error("DirSeeker::firstFile('%s') invoked with invalid buffer", mask.c_str());
+ return NULL_REG;
+ }
+ _outbuffer = buffer;
+ _files.clear();
+ _virtualFiles.clear();
+
+ int QfGImport = g_sci->inQfGImportRoom();
+ if (QfGImport) {
+ _files.clear();
+ addAsVirtualFiles("-QfG1-", "qfg1-*");
+ addAsVirtualFiles("-QfG1VGA-", "qfg1vga-*");
+ if (QfGImport > 2)
+ addAsVirtualFiles("-QfG2-", "qfg2-*");
+ if (QfGImport > 3)
+ addAsVirtualFiles("-QfG3-", "qfg3-*");
+
+ if (QfGImport == 3) {
+ // QfG3 sorts the filelisting itself, we can't let that happen otherwise our
+ // virtual list would go out-of-sync
+ reg_t savedHeros = segMan->findObjectByName("savedHeros");
+ if (!savedHeros.isNull())
+ writeSelectorValue(segMan, savedHeros, SELECTOR(sort), 0);
+ }
+
+ } else {
+ // Prefix the mask
+ const Common::String wrappedMask = g_sci->wrapFilename(mask);
+
+ // Obtain a list of all files matching the given mask
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
+ _files = saveFileMan->listSavefiles(wrappedMask);
+ }
+
+ // Reset the list iterator and write the first match to the output buffer,
+ // if any.
+ _iter = _files.begin();
+ return nextFile(segMan);
+}
+
+reg_t DirSeeker::nextFile(SegManager *segMan) {
+ if (_iter == _files.end()) {
+ return NULL_REG;
+ }
+
+ Common::String string;
+
+ if (_virtualFiles.empty()) {
+ // Strip the prefix, if we don't got a virtual filelisting
+ const Common::String wrappedString = *_iter;
+ string = g_sci->unwrapFilename(wrappedString);
+ } else {
+ string = *_iter;
+ }
+ if (string.size() > 12)
+ string = Common::String(string.c_str(), 12);
+ segMan->strcpy(_outbuffer, string.c_str());
+
+ // Return the result and advance the list iterator :)
+ ++_iter;
+ return _outbuffer;
+}
+
+
+#ifdef ENABLE_SCI32
+
+VirtualIndexFile::VirtualIndexFile(Common::String fileName) : _fileName(fileName), _changed(false) {
+ Common::SeekableReadStream *inFile = g_sci->getSaveFileManager()->openForLoading(fileName);
+
+ _bufferSize = inFile->size();
+ _buffer = new char[_bufferSize];
+ inFile->read(_buffer, _bufferSize);
+ _ptr = _buffer;
+ delete inFile;
+}
+
+VirtualIndexFile::VirtualIndexFile(uint32 initialSize) : _changed(false) {
+ _bufferSize = initialSize;
+ _buffer = new char[_bufferSize];
+ _ptr = _buffer;
+}
+
+VirtualIndexFile::~VirtualIndexFile() {
+ close();
+
+ _bufferSize = 0;
+ delete[] _buffer;
+ _buffer = 0;
+}
+
+uint32 VirtualIndexFile::read(char *buffer, uint32 size) {
+ uint32 curPos = _ptr - _buffer;
+ uint32 finalSize = MIN<uint32>(size, _bufferSize - curPos);
+ char *localPtr = buffer;
+
+ for (uint32 i = 0; i < finalSize; i++)
+ *localPtr++ = *_ptr++;
+
+ return finalSize;
+}
+
+uint32 VirtualIndexFile::write(const char *buffer, uint32 size) {
+ _changed = true;
+ uint32 curPos = _ptr - _buffer;
+
+ // Check if the buffer needs to be resized
+ if (curPos + size >= _bufferSize) {
+ _bufferSize = curPos + size + 1;
+ char *tmp = _buffer;
+ _buffer = new char[_bufferSize];
+ _ptr = _buffer + curPos;
+ memcpy(_buffer, tmp, _bufferSize);
+ delete[] tmp;
+ }
+
+ for (uint32 i = 0; i < size; i++)
+ *_ptr++ = *buffer++;
+
+ return size;
+}
+
+uint32 VirtualIndexFile::readLine(char *buffer, uint32 size) {
+ uint32 startPos = _ptr - _buffer;
+ uint32 bytesRead = 0;
+ char *localPtr = buffer;
+
+ // This is not a full-blown implementation of readLine, but it
+ // suffices for Phantasmagoria
+ while (startPos + bytesRead < size) {
+ bytesRead++;
+
+ if (*_ptr == 0 || *_ptr == 0x0A) {
+ _ptr++;
+ *localPtr = 0;
+ return bytesRead;
+ } else {
+ *localPtr++ = *_ptr++;
+ }
+ }
+
+ return bytesRead;
+}
+
+bool VirtualIndexFile::seek(int32 offset, int whence) {
+ uint32 startPos = _ptr - _buffer;
+ assert(offset >= 0);
+
+ switch (whence) {
+ case SEEK_CUR:
+ assert(startPos + offset < _bufferSize);
+ _ptr += offset;
+ break;
+ case SEEK_SET:
+ assert(offset < (int32)_bufferSize);
+ _ptr = _buffer + offset;
+ break;
+ case SEEK_END:
+ assert(_bufferSize - offset >= 0);
+ _ptr = _buffer + (_bufferSize - offset);
+ break;
+ }
+
+ return true;
+}
+
+void VirtualIndexFile::close() {
+ if (_changed && !_fileName.empty()) {
+ Common::WriteStream *outFile = g_sci->getSaveFileManager()->openForSaving(_fileName);
+ outFile->write(_buffer, _bufferSize);
+ delete outFile;
+ }
+
+ // Maintain the buffer, and seek to the beginning of it
+ _ptr = _buffer;
+}
+
+#endif
+
+} // End of namespace Sci
diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h
new file mode 100644
index 0000000000..1c8e302d15
--- /dev/null
+++ b/engines/sci/engine/file.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 SCI_ENGINE_FILE_H
+#define SCI_ENGINE_FILE_H
+
+#include "common/str-array.h"
+#include "common/stream.h"
+
+namespace Sci {
+
+enum {
+ _K_FILE_MODE_OPEN_OR_CREATE = 0,
+ _K_FILE_MODE_OPEN_OR_FAIL = 1,
+ _K_FILE_MODE_CREATE = 2
+};
+
+/* Maximum length of a savegame name (including terminator character). */
+#define SCI_MAX_SAVENAME_LENGTH 0x24
+
+enum {
+ MAX_SAVEGAME_NR = 20 /**< Maximum number of savegames */
+};
+
+#define VIRTUALFILE_HANDLE 200
+#define PHANTASMAGORIA_SAVEGAME_INDEX "phantsg.dir"
+
+struct SavegameDesc {
+ int16 id;
+ int virtualId; // straight numbered, according to id but w/o gaps
+ int date;
+ int time;
+ int version;
+ char name[SCI_MAX_SAVENAME_LENGTH];
+};
+
+class FileHandle {
+public:
+ Common::String _name;
+ Common::SeekableReadStream *_in;
+ Common::WriteStream *_out;
+
+public:
+ FileHandle();
+ ~FileHandle();
+
+ void close();
+ bool isOpen() const;
+};
+
+
+class DirSeeker {
+protected:
+ reg_t _outbuffer;
+ Common::StringArray _files;
+ Common::StringArray _virtualFiles;
+ Common::StringArray::const_iterator _iter;
+
+public:
+ DirSeeker() {
+ _outbuffer = NULL_REG;
+ _iter = _files.begin();
+ }
+
+ reg_t firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan);
+ reg_t nextFile(SegManager *segMan);
+
+ Common::String getVirtualFilename(uint fileNumber);
+
+private:
+ void addAsVirtualFiles(Common::String title, Common::String fileMask);
+};
+
+
+#ifdef ENABLE_SCI32
+
+/**
+ * An implementation of a virtual file that supports basic read and write
+ * operations simultaneously.
+ *
+ * This class has been initially implemented for Phantasmagoria, which has its
+ * own custom save/load code. The load code keeps checking for the existence
+ * of the save index file and keeps closing and reopening it for each save
+ * slot. This is notoriously slow and clumsy, and introduces noticeable delays,
+ * especially for non-desktop systems. Also, its game scripts request to open
+ * the index file for reading and writing with the same parameters
+ * (SaveManager::setCurrentSave and SaveManager::getCurrentSave). Moreover,
+ * the game scripts reopen the index file for writing in order to update it
+ * and seek within it. We do not support seeking in writeable streams, and the
+ * fact that our saved games are ZIP files makes this operation even more
+ * expensive. Finally, the savegame index file is supposed to be expanded when
+ * a new save slot is added.
+ * For the aforementioned reasons, this class has been implemented, which offers
+ * the basic functionality needed by the game scripts in Phantasmagoria.
+ */
+class VirtualIndexFile {
+public:
+ VirtualIndexFile(Common::String fileName);
+ VirtualIndexFile(uint32 initialSize);
+ ~VirtualIndexFile();
+
+ uint32 read(char *buffer, uint32 size);
+ uint32 readLine(char *buffer, uint32 size);
+ uint32 write(const char *buffer, uint32 size);
+ bool seek(int32 offset, int whence);
+ void close();
+
+private:
+ char *_buffer;
+ uint32 _bufferSize;
+ char *_ptr;
+
+ Common::String _fileName;
+ bool _changed;
+};
+
+#endif
+
+} // End of namespace Sci
+
+#endif // SCI_ENGINE_FILE_H
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 664c97f7b5..677b790f93 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -276,9 +276,6 @@ private:
const Common::String _invalid;
};
-/* Maximum length of a savegame name (including terminator character). */
-#define SCI_MAX_SAVENAME_LENGTH 0x24
-
/******************** Kernel functions ********************/
reg_t kStrLen(EngineState *s, int argc, reg_t *argv);
@@ -326,10 +323,6 @@ reg_t kTimesCot(EngineState *s, int argc, reg_t *argv);
reg_t kCosDiv(EngineState *s, int argc, reg_t *argv);
reg_t kSinDiv(EngineState *s, int argc, reg_t *argv);
reg_t kValidPath(EngineState *s, int argc, reg_t *argv);
-reg_t kFOpen(EngineState *s, int argc, reg_t *argv);
-reg_t kFPuts(EngineState *s, int argc, reg_t *argv);
-reg_t kFGets(EngineState *s, int argc, reg_t *argv);
-reg_t kFClose(EngineState *s, int argc, reg_t *argv);
reg_t kMapKeyToDir(EngineState *s, int argc, reg_t *argv);
reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv);
reg_t kLocalToGlobal(EngineState *s, int argc, reg_t *argv);
@@ -464,6 +457,7 @@ reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv);
// SCI2.1 Kernel Functions
reg_t kText(EngineState *s, int argc, reg_t *argv);
reg_t kSave(EngineState *s, int argc, reg_t *argv);
+reg_t kAutoSave(EngineState *s, int argc, reg_t *argv);
reg_t kList(EngineState *s, int argc, reg_t *argv);
reg_t kRobot(EngineState *s, int argc, reg_t *argv);
reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv);
@@ -482,6 +476,9 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv);
reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv);
reg_t kFont(EngineState *s, int argc, reg_t *argv);
reg_t kBitmap(EngineState *s, int argc, reg_t *argv);
+reg_t kAddLine(EngineState *s, int argc, reg_t *argv);
+reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv);
+reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv);
// SCI3 Kernel functions
reg_t kPlayDuck(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 4ddf0534ea..6965a5da45 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -246,6 +246,20 @@ static const SciKernelMapSubEntry kFileIO_subops[] = {
};
#ifdef ENABLE_SCI32
+
+static const SciKernelMapSubEntry kSave_subops[] = {
+ { SIG_SCI32, 0, MAP_CALL(SaveGame), "[r0]i[r0](r)", NULL },
+ { SIG_SCI32, 1, MAP_CALL(RestoreGame), "[r0]i[r0]", NULL },
+ { SIG_SCI32, 2, MAP_CALL(GetSaveDir), "(r*)", NULL },
+ { SIG_SCI32, 3, MAP_CALL(CheckSaveGame), ".*", NULL },
+ // Subop 4 hasn't been encountered yet
+ { SIG_SCI32, 5, MAP_CALL(GetSaveFiles), "rrr", NULL },
+ { SIG_SCI32, 6, MAP_CALL(MakeSaveCatName), "rr", NULL },
+ { SIG_SCI32, 7, MAP_CALL(MakeSaveFileName), "rri", NULL },
+ { SIG_SCI32, 8, MAP_CALL(AutoSave), "[o0]", NULL },
+ SCI_SUBOPENTRY_TERMINATOR
+};
+
// version, subId, function-mapping, signature, workarounds
static const SciKernelMapSubEntry kList_subops[] = {
{ SIG_SCI21, 0, MAP_CALL(NewList), "", NULL },
@@ -338,10 +352,10 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(EditControl), SIG_EVERYWHERE, "[o0][o0]", NULL, NULL },
{ MAP_CALL(Empty), SIG_EVERYWHERE, "(.*)", NULL, NULL },
{ MAP_CALL(EmptyList), SIG_EVERYWHERE, "l", NULL, NULL },
- { MAP_CALL(FClose), SIG_EVERYWHERE, "i", NULL, NULL },
- { MAP_CALL(FGets), SIG_EVERYWHERE, "rii", NULL, NULL },
- { MAP_CALL(FOpen), SIG_EVERYWHERE, "ri", NULL, NULL },
- { MAP_CALL(FPuts), SIG_EVERYWHERE, "ir", NULL, NULL },
+ { "FClose", kFileIOClose, SIG_EVERYWHERE, "i", NULL, NULL },
+ { "FGets", kFileIOReadString, SIG_EVERYWHERE, "rii", NULL, NULL },
+ { "FOpen", kFileIOOpen, SIG_EVERYWHERE, "ri", NULL, NULL },
+ { "FPuts", kFileIOWriteString, SIG_EVERYWHERE, "ir", NULL, NULL },
{ MAP_CALL(FileIO), SIG_EVERYWHERE, "i(.*)", kFileIO_subops, NULL },
{ MAP_CALL(FindKey), SIG_EVERYWHERE, "l.", NULL, kFindKey_workarounds },
{ MAP_CALL(FirstNode), SIG_EVERYWHERE, "[l0]", NULL, NULL },
@@ -555,7 +569,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL },
{ MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", NULL, NULL },
{ MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", NULL, NULL },
- { MAP_CALL(Save), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_CALL(Save), SIG_EVERYWHERE, "i(.*)", kSave_subops, NULL },
{ MAP_CALL(Text), SIG_EVERYWHERE, "(.*)", NULL, NULL },
{ MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii", NULL, NULL },
{ MAP_CALL(GetWindowsOption), SIG_EVERYWHERE, "i", NULL, NULL },
@@ -564,10 +578,13 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(GetSierraProfileInt), SIG_EVERYWHERE, "rri", NULL, NULL },
{ MAP_CALL(CelInfo), SIG_EVERYWHERE, "iiiiii", NULL, NULL },
{ MAP_CALL(SetLanguage), SIG_EVERYWHERE, "r", NULL, NULL },
- { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "io(.*)", NULL, NULL },
{ MAP_CALL(SetFontRes), SIG_EVERYWHERE, "ii", NULL, NULL },
{ MAP_CALL(Font), SIG_EVERYWHERE, "i(.*)", NULL, NULL },
{ MAP_CALL(Bitmap), SIG_EVERYWHERE, "(.*)", NULL, NULL },
+ { MAP_CALL(AddLine), SIG_EVERYWHERE, "oiiiiiiiii", NULL, NULL },
+ { MAP_CALL(UpdateLine), SIG_EVERYWHERE, "roiiiiiiiii", NULL, NULL },
+ { MAP_CALL(DeleteLine), SIG_EVERYWHERE, "ro", NULL, NULL },
// SCI2.1 Empty Functions
@@ -613,9 +630,6 @@ static SciKernelMapEntry s_kernelMap[] = {
// SCI2.1 unmapped functions - TODO!
// MovePlaneItems - used by SQ6 to scroll through the inventory via the up/down buttons
- // AddLine - used by Torin's Passage to highlight the chapter buttons
- // DeleteLine - used by Torin's Passage to delete the highlight from the chapter buttons
- // UpdateLine - used by LSL6
// SetPalStyleRange - 2 integer parameters, start and end. All styles from start-end
// (inclusive) are set to 0
// MorphOn - used by SQ6, script 900, the datacorder reprogramming puzzle (from room 270)
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 8d1b078697..7a2f161829 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -33,6 +33,7 @@
#include "gui/saveload.h"
#include "sci/sci.h"
+#include "sci/engine/file.h"
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
#include "sci/engine/savegame.h"
@@ -40,209 +41,11 @@
namespace Sci {
-struct SavegameDesc {
- int16 id;
- int virtualId; // straight numbered, according to id but w/o gaps
- int date;
- int time;
- int version;
- char name[SCI_MAX_SAVENAME_LENGTH];
-};
-
-/*
- * Note on how file I/O is implemented: In ScummVM, one can not create/write
- * arbitrary data files, simply because many of our target platforms do not
- * support this. The only files one can create are savestates. But SCI has an
- * opcode to create and write to seemingly 'arbitrary' files. This is mainly
- * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver, used
- * for persisting the results of the "age quiz" across restarts) and in LSL5
- * for MEMORY.DRV (which is again a game data file and contains the game's
- * password, XOR encrypted).
- * To implement that opcode, we combine the SaveFileManager with regular file
- * code, similarly to how the SCUMM HE engine does it.
- *
- * To handle opening a file called "foobar", what we do is this: First, we
- * create an 'augmented file name', by prepending the game target and a dash,
- * so if we running game target sq1sci, the name becomes "sq1sci-foobar".
- * Next, we check if such a file is known to the SaveFileManager. If so, we
- * we use that for reading/writing, delete it, whatever.
- *
- * If no such file is present but we were only asked to *read* the file,
- * we fallback to looking for a regular file called "foobar", and open that
- * for reading only.
- */
-
-
-
-FileHandle::FileHandle() : _in(0), _out(0) {
-}
-
-FileHandle::~FileHandle() {
- close();
-}
-
-void FileHandle::close() {
- delete _in;
- delete _out;
- _in = 0;
- _out = 0;
- _name.clear();
-}
-
-bool FileHandle::isOpen() const {
- return _in || _out;
-}
-
-
-
-enum {
- _K_FILE_MODE_OPEN_OR_CREATE = 0,
- _K_FILE_MODE_OPEN_OR_FAIL = 1,
- _K_FILE_MODE_CREATE = 2
-};
-
-
-
-reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename) {
- Common::String englishName = g_sci->getSciLanguageString(filename, K_LANG_ENGLISH);
- Common::String wrappedName = unwrapFilename ? g_sci->wrapFilename(englishName) : englishName;
- Common::SeekableReadStream *inFile = 0;
- Common::WriteStream *outFile = 0;
- Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
-
- if (mode == _K_FILE_MODE_OPEN_OR_FAIL) {
- // Try to open file, abort if not possible
- inFile = saveFileMan->openForLoading(wrappedName);
- // If no matching savestate exists: fall back to reading from a regular
- // file
- if (!inFile)
- inFile = SearchMan.createReadStreamForMember(englishName);
-
- if (!inFile)
- debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str());
- } else if (mode == _K_FILE_MODE_CREATE) {
- // Create the file, destroying any content it might have had
- outFile = saveFileMan->openForSaving(wrappedName);
- if (!outFile)
- debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str());
- } else if (mode == _K_FILE_MODE_OPEN_OR_CREATE) {
- // Try to open file, create it if it doesn't exist
- outFile = saveFileMan->openForSaving(wrappedName);
- if (!outFile)
- debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str());
- // QfG1 opens the character export file with _K_FILE_MODE_CREATE first,
- // closes it immediately and opens it again with this here. Perhaps
- // other games use this for read access as well. I guess changing this
- // whole code into using virtual files and writing them after close
- // would be more appropriate.
- } else {
- error("file_open: unsupported mode %d (filename '%s')", mode, englishName.c_str());
- }
-
- if (!inFile && !outFile) { // Failed
- debugC(kDebugLevelFile, " -> file_open() failed");
- return SIGNAL_REG;
- }
-
- // Find a free file handle
- uint handle = 1; // Ignore _fileHandles[0]
- while ((handle < s->_fileHandles.size()) && s->_fileHandles[handle].isOpen())
- handle++;
-
- if (handle == s->_fileHandles.size()) {
- // Hit size limit => Allocate more space
- s->_fileHandles.resize(s->_fileHandles.size() + 1);
- }
-
- s->_fileHandles[handle]._in = inFile;
- s->_fileHandles[handle]._out = outFile;
- s->_fileHandles[handle]._name = englishName;
-
- debugC(kDebugLevelFile, " -> opened file '%s' with handle %d", englishName.c_str(), handle);
- return make_reg(0, handle);
-}
-
-reg_t kFOpen(EngineState *s, int argc, reg_t *argv) {
- Common::String name = s->_segMan->getString(argv[0]);
- int mode = argv[1].toUint16();
-
- debugC(kDebugLevelFile, "kFOpen(%s,0x%x)", name.c_str(), mode);
- return file_open(s, name, mode, true);
-}
-
-static FileHandle *getFileFromHandle(EngineState *s, uint handle) {
- if (handle == 0) {
- error("Attempt to use file handle 0");
- return 0;
- }
-
- if ((handle >= s->_fileHandles.size()) || !s->_fileHandles[handle].isOpen()) {
- warning("Attempt to use invalid/unused file handle %d", handle);
- return 0;
- }
-
- return &s->_fileHandles[handle];
-}
-
-reg_t kFClose(EngineState *s, int argc, reg_t *argv) {
- debugC(kDebugLevelFile, "kFClose(%d)", argv[0].toUint16());
- if (argv[0] != SIGNAL_REG) {
- FileHandle *f = getFileFromHandle(s, argv[0].toUint16());
- if (f)
- f->close();
- }
- return s->r_acc;
-}
-
-reg_t kFPuts(EngineState *s, int argc, reg_t *argv) {
- int handle = argv[0].toUint16();
- Common::String data = s->_segMan->getString(argv[1]);
-
- FileHandle *f = getFileFromHandle(s, handle);
- if (f)
- f->_out->write(data.c_str(), data.size());
-
- return s->r_acc;
-}
-
-static int fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle) {
- FileHandle *f = getFileFromHandle(s, handle);
- if (!f)
- return 0;
-
- if (!f->_in) {
- error("fgets_wrapper: Trying to read from file '%s' opened for writing", f->_name.c_str());
- return 0;
- }
- int readBytes = 0;
- if (maxsize > 1) {
- memset(dest, 0, maxsize);
- f->_in->readLine(dest, maxsize);
- readBytes = strlen(dest); // FIXME: sierra sci returned byte count and didn't react on NUL characters
- // The returned string must not have an ending LF
- if (readBytes > 0) {
- if (dest[readBytes - 1] == 0x0A)
- dest[readBytes - 1] = 0;
- }
- } else {
- *dest = 0;
- }
-
- debugC(kDebugLevelFile, " -> FGets'ed \"%s\"", dest);
- return readBytes;
-}
-
-reg_t kFGets(EngineState *s, int argc, reg_t *argv) {
- int maxsize = argv[1].toUint16();
- char *buf = new char[maxsize];
- int handle = argv[2].toUint16();
-
- debugC(kDebugLevelFile, "kFGets(%d, %d)", handle, maxsize);
- int readBytes = fgets_wrapper(s, buf, maxsize, handle);
- s->_segMan->memcpy(argv[0], (const byte*)buf, maxsize);
- delete[] buf;
- return readBytes ? argv[0] : NULL_REG;
-}
+extern reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename);
+extern FileHandle *getFileFromHandle(EngineState *s, uint handle);
+extern int fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle);
+extern void listSavegames(Common::Array<SavegameDesc> &saves);
+extern int findSavegame(Common::Array<SavegameDesc> &saves, int16 savegameId);
/**
* Writes the cwd to the supplied address and returns the address in acc.
@@ -258,9 +61,6 @@ reg_t kGetCWD(EngineState *s, int argc, reg_t *argv) {
return argv[0];
}
-static void listSavegames(Common::Array<SavegameDesc> &saves);
-static int findSavegame(Common::Array<SavegameDesc> &saves, int16 saveId);
-
enum {
K_DEVICE_INFO_GET_DEVICE = 0,
K_DEVICE_INFO_GET_CURRENT_DEVICE = 1,
@@ -352,18 +152,6 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {
return s->r_acc;
}
-reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) {
-#ifdef ENABLE_SCI32
- // SCI32 uses a parameter here. It is used to modify a string, stored in a
- // global variable, so that game scripts store the save directory. We
- // don't really set a save game directory, thus not setting the string to
- // anything is the correct thing to do here.
- //if (argc > 0)
- // warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0]));
-#endif
- return s->_segMan->getSaveDirPtr();
-}
-
reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) {
if (argc > 1) {
// SCI1.1/SCI32
@@ -394,354 +182,36 @@ reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, 1);
}
-static bool _savegame_sort_byDate(const SavegameDesc &l, const SavegameDesc &r) {
- if (l.date != r.date)
- return (l.date > r.date);
- return (l.time > r.time);
-}
-
-// Create a sorted array containing all found savedgames
-static void listSavegames(Common::Array<SavegameDesc> &saves) {
- Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
-
- // Load all saves
- Common::StringArray saveNames = saveFileMan->listSavefiles(g_sci->getSavegamePattern());
-
- for (Common::StringArray::const_iterator iter = saveNames.begin(); iter != saveNames.end(); ++iter) {
- Common::String filename = *iter;
- Common::SeekableReadStream *in;
- if ((in = saveFileMan->openForLoading(filename))) {
- SavegameMetadata meta;
- if (!get_savegame_metadata(in, &meta) || meta.name.empty()) {
- // invalid
- delete in;
- continue;
- }
- delete in;
-
- SavegameDesc desc;
- desc.id = strtol(filename.end() - 3, NULL, 10);
- desc.date = meta.saveDate;
- // We need to fix date in here, because we save DDMMYYYY instead of
- // YYYYMMDD, so sorting wouldn't work
- desc.date = ((desc.date & 0xFFFF) << 16) | ((desc.date & 0xFF0000) >> 8) | ((desc.date & 0xFF000000) >> 24);
- desc.time = meta.saveTime;
- desc.version = meta.version;
-
- if (meta.name.lastChar() == '\n')
- meta.name.deleteLastChar();
-
- Common::strlcpy(desc.name, meta.name.c_str(), SCI_MAX_SAVENAME_LENGTH);
-
- debug(3, "Savegame in file %s ok, id %d", filename.c_str(), desc.id);
-
- saves.push_back(desc);
- }
- }
-
- // Sort the list by creation date of the saves
- Common::sort(saves.begin(), saves.end(), _savegame_sort_byDate);
-}
-
-// Find a savedgame according to virtualId and return the position within our array
-static int findSavegame(Common::Array<SavegameDesc> &saves, int16 savegameId) {
- for (uint saveNr = 0; saveNr < saves.size(); saveNr++) {
- if (saves[saveNr].id == savegameId)
- return saveNr;
- }
- return -1;
-}
-
-// The scripts get IDs ranging from 100->199, because the scripts require us to assign unique ids THAT EVEN STAY BETWEEN
-// SAVES and the scripts also use "saves-count + 1" to create a new savedgame slot.
-// SCI1.1 actually recycles ids, in that case we will currently get "0".
-// This behavior is required especially for LSL6. In this game, it's possible to quick save. The scripts will use
-// the last-used id for that feature. If we don't assign sticky ids, the feature will overwrite different saves all the
-// time. And sadly we can't just use the actual filename ids directly, because of the creation method for new slots.
-
-bool Console::cmdListSaves(int argc, const char **argv) {
- Common::Array<SavegameDesc> saves;
- listSavegames(saves);
-
- for (uint i = 0; i < saves.size(); i++) {
- Common::String filename = g_sci->getSavegameName(saves[i].id);
- DebugPrintf("%s: '%s'\n", filename.c_str(), saves[i].name);
- }
-
- return true;
-}
-
-reg_t kCheckSaveGame(EngineState *s, int argc, reg_t *argv) {
- Common::String game_id = s->_segMan->getString(argv[0]);
- uint16 virtualId = argv[1].toUint16();
-
- debug(3, "kCheckSaveGame(%s, %d)", game_id.c_str(), virtualId);
-
- Common::Array<SavegameDesc> saves;
- listSavegames(saves);
-
- // we allow 0 (happens in QfG2 when trying to restore from an empty saved game list) and return false in that case
- if (virtualId == 0)
- return NULL_REG;
-
- // Find saved-game
- if ((virtualId < SAVEGAMEID_OFFICIALRANGE_START) || (virtualId > SAVEGAMEID_OFFICIALRANGE_END))
- error("kCheckSaveGame: called with invalid savegameId");
- uint savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START;
- int savegameNr = findSavegame(saves, savegameId);
- if (savegameNr == -1)
- return NULL_REG;
-
- // Check for compatible savegame version
- int ver = saves[savegameNr].version;
- if (ver < MINIMUM_SAVEGAME_VERSION || ver > CURRENT_SAVEGAME_VERSION)
- return NULL_REG;
-
- // Otherwise we assume the savegame is OK
- return TRUE_REG;
-}
-
-reg_t kGetSaveFiles(EngineState *s, int argc, reg_t *argv) {
- Common::String game_id = s->_segMan->getString(argv[0]);
-
- debug(3, "kGetSaveFiles(%s)", game_id.c_str());
-
- // Scripts ask for current save files, we can assume that if afterwards they ask us to create a new slot they really
- // mean new slot instead of overwriting the old one
- s->_lastSaveVirtualId = SAVEGAMEID_OFFICIALRANGE_START;
-
- Common::Array<SavegameDesc> saves;
- listSavegames(saves);
- uint totalSaves = MIN<uint>(saves.size(), MAX_SAVEGAME_NR);
-
- reg_t *slot = s->_segMan->derefRegPtr(argv[2], totalSaves);
-
- if (!slot) {
- warning("kGetSaveFiles: %04X:%04X invalid or too small to hold slot data", PRINT_REG(argv[2]));
- totalSaves = 0;
- }
-
- const uint bufSize = (totalSaves * SCI_MAX_SAVENAME_LENGTH) + 1;
- char *saveNames = new char[bufSize];
- char *saveNamePtr = saveNames;
-
- for (uint i = 0; i < totalSaves; i++) {
- *slot++ = make_reg(0, saves[i].id + SAVEGAMEID_OFFICIALRANGE_START); // Store the virtual savegame ID ffs. see above
- strcpy(saveNamePtr, saves[i].name);
- saveNamePtr += SCI_MAX_SAVENAME_LENGTH;
- }
-
- *saveNamePtr = 0; // Terminate list
-
- s->_segMan->memcpy(argv[1], (byte *)saveNames, bufSize);
- delete[] saveNames;
-
- return make_reg(0, totalSaves);
-}
-
-reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) {
- Common::String game_id;
- int16 virtualId = argv[1].toSint16();
- int16 savegameId = -1;
- Common::String game_description;
- Common::String version;
-
- if (argc > 3)
- version = s->_segMan->getString(argv[3]);
-
- // We check here, we don't want to delete a users save in case we are within a kernel function
- if (s->executionStackBase) {
- warning("kSaveGame - won't save from within kernel function");
- return NULL_REG;
- }
-
- if (argv[0].isNull()) {
- // Direct call, from a patched Game::save
- if ((argv[1] != SIGNAL_REG) || (!argv[2].isNull()))
- error("kSaveGame: assumed patched call isn't accurate");
-
- // we are supposed to show a dialog for the user and let him choose where to save
- g_sci->_soundCmd->pauseAll(true); // pause music
- const EnginePlugin *plugin = NULL;
- EngineMan.findGame(g_sci->getGameIdStr(), &plugin);
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"));
- dialog->setSaveMode(true);
- savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
- game_description = dialog->getResultString();
- if (game_description.empty()) {
- // create our own description for the saved game, the user didnt enter it
- #if defined(USE_SAVEGAME_TIMESTAMP)
- TimeDate curTime;
- g_system->getTimeAndDate(curTime);
- curTime.tm_year += 1900; // fixup year
- curTime.tm_mon++; // fixup month
- game_description = Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec);
- #else
- game_description = Common::String::format("Save %d", savegameId + 1);
- #endif
- }
- delete dialog;
- g_sci->_soundCmd->pauseAll(false); // unpause music ( we can't have it paused during save)
- if (savegameId < 0)
- return NULL_REG;
-
- } else {
- // Real call from script
- game_id = s->_segMan->getString(argv[0]);
- if (argv[2].isNull())
- error("kSaveGame: called with description being NULL");
- game_description = s->_segMan->getString(argv[2]);
-
- debug(3, "kSaveGame(%s,%d,%s,%s)", game_id.c_str(), virtualId, game_description.c_str(), version.c_str());
-
- Common::Array<SavegameDesc> saves;
- listSavegames(saves);
-
- if ((virtualId >= SAVEGAMEID_OFFICIALRANGE_START) && (virtualId <= SAVEGAMEID_OFFICIALRANGE_END)) {
- // savegameId is an actual Id, so search for it just to make sure
- savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START;
- if (findSavegame(saves, savegameId) == -1)
- return NULL_REG;
- } else if (virtualId < SAVEGAMEID_OFFICIALRANGE_START) {
- // virtualId is low, we assume that scripts expect us to create new slot
- if (virtualId == s->_lastSaveVirtualId) {
- // if last virtual id is the same as this one, we assume that caller wants to overwrite last save
- savegameId = s->_lastSaveNewId;
- } else {
- uint savegameNr;
- // savegameId is in lower range, scripts expect us to create a new slot
- for (savegameId = 0; savegameId < SAVEGAMEID_OFFICIALRANGE_START; savegameId++) {
- for (savegameNr = 0; savegameNr < saves.size(); savegameNr++) {
- if (savegameId == saves[savegameNr].id)
- break;
- }
- if (savegameNr == saves.size())
- break;
- }
- if (savegameId == SAVEGAMEID_OFFICIALRANGE_START)
- error("kSavegame: no more savegame slots available");
- }
- } else {
- error("kSaveGame: invalid savegameId used");
- }
-
- // Save in case caller wants to overwrite last newly created save
- s->_lastSaveVirtualId = virtualId;
- s->_lastSaveNewId = savegameId;
- }
-
- s->r_acc = NULL_REG;
-
- Common::String filename = g_sci->getSavegameName(savegameId);
- Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
- Common::OutSaveFile *out;
-
- out = saveFileMan->openForSaving(filename);
- if (!out) {
- warning("Error opening savegame \"%s\" for writing", filename.c_str());
- } else {
- if (!gamestate_save(s, out, game_description, version)) {
- warning("Saving the game failed");
- } else {
- s->r_acc = TRUE_REG; // save successful
- }
+reg_t kValidPath(EngineState *s, int argc, reg_t *argv) {
+ Common::String path = s->_segMan->getString(argv[0]);
- out->finalize();
- if (out->err()) {
- warning("Writing the savegame failed");
- s->r_acc = NULL_REG; // write failure
- }
- delete out;
- }
+ debug(3, "kValidPath(%s) -> %d", path.c_str(), s->r_acc.offset);
- return s->r_acc;
+ // Always return true
+ return make_reg(0, 1);
}
-reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
- Common::String game_id = !argv[0].isNull() ? s->_segMan->getString(argv[0]) : "";
- int16 savegameId = argv[1].toSint16();
- bool pausedMusic = false;
-
- debug(3, "kRestoreGame(%s,%d)", game_id.c_str(), savegameId);
-
- if (argv[0].isNull()) {
- // Direct call, either from launcher or from a patched Game::restore
- if (savegameId == -1) {
- // we are supposed to show a dialog for the user and let him choose a saved game
- g_sci->_soundCmd->pauseAll(true); // pause music
- const EnginePlugin *plugin = NULL;
- EngineMan.findGame(g_sci->getGameIdStr(), &plugin);
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"));
- dialog->setSaveMode(false);
- savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
- delete dialog;
- if (savegameId < 0) {
- g_sci->_soundCmd->pauseAll(false); // unpause music
- return s->r_acc;
- }
- pausedMusic = true;
- }
- // don't adjust ID of the saved game, it's already correct
- } else {
- if (argv[2].isNull())
- error("kRestoreGame: called with parameter 2 being NULL");
- // Real call from script, we need to adjust ID
- if ((savegameId < SAVEGAMEID_OFFICIALRANGE_START) || (savegameId > SAVEGAMEID_OFFICIALRANGE_END)) {
- warning("Savegame ID %d is not allowed", savegameId);
- return TRUE_REG;
- }
- savegameId -= SAVEGAMEID_OFFICIALRANGE_START;
- }
-
- s->r_acc = NULL_REG; // signals success
-
- Common::Array<SavegameDesc> saves;
- listSavegames(saves);
- if (findSavegame(saves, savegameId) == -1) {
- s->r_acc = TRUE_REG;
- warning("Savegame ID %d not found", savegameId);
- } else {
- Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
- Common::String filename = g_sci->getSavegameName(savegameId);
- Common::SeekableReadStream *in;
-
- in = saveFileMan->openForLoading(filename);
- if (in) {
- // found a savegame file
-
- gamestate_restore(s, in);
- delete in;
-
- if (g_sci->getGameId() == GID_MOTHERGOOSE256) {
- // WORKAROUND: Mother Goose SCI1/SCI1.1 does some weird things for
- // saving a previously restored game.
- // We set the current savedgame-id directly and remove the script
- // code concerning this via script patch.
- s->variables[VAR_GLOBAL][0xB3].offset = SAVEGAMEID_OFFICIALRANGE_START + savegameId;
- }
- } else {
- s->r_acc = TRUE_REG;
- warning("Savegame #%d not found", savegameId);
- }
- }
+#ifdef ENABLE_SCI32
- if (!s->r_acc.isNull()) {
- // no success?
- if (pausedMusic)
- g_sci->_soundCmd->pauseAll(false); // unpause music
+reg_t kCD(EngineState *s, int argc, reg_t *argv) {
+ // TODO: Stub
+ switch (argv[0].toUint16()) {
+ case 0:
+ // Return whether the contents of disc argv[1] is available.
+ return TRUE_REG;
+ case 1:
+ // Return the current CD number
+ return make_reg(0, 1);
+ default:
+ warning("CD(%d)", argv[0].toUint16());
}
- return s->r_acc;
+ return NULL_REG;
}
-reg_t kValidPath(EngineState *s, int argc, reg_t *argv) {
- Common::String path = s->_segMan->getString(argv[0]);
+#endif
- debug(3, "kValidPath(%s) -> %d", path.c_str(), s->r_acc.offset);
-
- // Always return true
- return make_reg(0, 1);
-}
+// ---- FileIO operations -----------------------------------------------------
reg_t kFileIO(EngineState *s, int argc, reg_t *argv) {
if (!s)
@@ -779,6 +249,73 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
}
debugC(kDebugLevelFile, "kFileIO(open): %s, 0x%x", name.c_str(), mode);
+#ifdef ENABLE_SCI32
+ if (name == PHANTASMAGORIA_SAVEGAME_INDEX) {
+ if (s->_virtualIndexFile) {
+ return make_reg(0, VIRTUALFILE_HANDLE);
+ } else {
+ Common::String englishName = g_sci->getSciLanguageString(name, K_LANG_ENGLISH);
+ Common::String wrappedName = g_sci->wrapFilename(englishName);
+ if (!g_sci->getSaveFileManager()->listSavefiles(wrappedName).empty()) {
+ s->_virtualIndexFile = new VirtualIndexFile(wrappedName);
+ return make_reg(0, VIRTUALFILE_HANDLE);
+ }
+ }
+ }
+
+ // Shivers is trying to store savegame descriptions and current spots in
+ // separate .SG files, which are hardcoded in the scripts.
+ // Essentially, there is a normal save file, created by the executable
+ // and an extra hardcoded save file, created by the game scripts, probably
+ // because they didn't want to modify the save/load code to add the extra
+ // information.
+ // Each slot in the book then has two strings, the save description and a
+ // description of the current spot that the player is at. Currently, the
+ // spot strings are always empty (probably related to the unimplemented
+ // kString subop 14, which gets called right before this call).
+ // For now, we don't allow the creation of these files, which means that
+ // all the spot descriptions next to each slot description will be empty
+ // (they are empty anyway). Until a viable solution is found to handle these
+ // extra files and until the spot description strings are initialized
+ // correctly, we resort to virtual files in order to make the load screen
+ // useable. Without this code it is unusable, as the extra information is
+ // always saved to 0.SG for some reason, but on restore the correct file is
+ // used. Perhaps the virtual ID is not taken into account when saving.
+ //
+ // Future TODO: maintain spot descriptions and show them too, ideally without
+ // having to return to this logic of extra hardcoded files.
+ if (g_sci->getGameId() == GID_SHIVERS && name.hasSuffix(".SG")) {
+ if (mode == _K_FILE_MODE_OPEN_OR_CREATE || mode == _K_FILE_MODE_CREATE) {
+ // Game scripts are trying to create a file with the save
+ // description, stop them here
+ debugC(kDebugLevelFile, "Not creating unused file %s", name.c_str());
+ return SIGNAL_REG;
+ } else if (mode == _K_FILE_MODE_OPEN_OR_FAIL) {
+ // Create a virtual file containing the save game description
+ // and slot number, as the game scripts expect.
+ int slotNumber;
+ sscanf(name.c_str(), "%d.SG", &slotNumber);
+
+ Common::Array<SavegameDesc> saves;
+ listSavegames(saves);
+ int savegameNr = findSavegame(saves, slotNumber - SAVEGAMEID_OFFICIALRANGE_START);
+
+ if (!s->_virtualIndexFile) {
+ // Make the virtual file buffer big enough to avoid having it grow dynamically.
+ // 50 bytes should be more than enough.
+ s->_virtualIndexFile = new VirtualIndexFile(50);
+ }
+
+ s->_virtualIndexFile->seek(0, SEEK_SET);
+ s->_virtualIndexFile->write(saves[savegameNr].name, strlen(saves[savegameNr].name));
+ s->_virtualIndexFile->write("\0", 1);
+ s->_virtualIndexFile->write("\0", 1); // Spot description (empty)
+ s->_virtualIndexFile->seek(0, SEEK_SET);
+ return make_reg(0, VIRTUALFILE_HANDLE);
+ }
+ }
+#endif
+
// QFG import rooms get a virtual filelisting instead of an actual one
if (g_sci->inQfGImportRoom()) {
// We need to find out what the user actually selected, "savedHeroes" is
@@ -794,48 +331,82 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) {
debugC(kDebugLevelFile, "kFileIO(close): %d", argv[0].toUint16());
- FileHandle *f = getFileFromHandle(s, argv[0].toUint16());
+ if (argv[0] == SIGNAL_REG)
+ return s->r_acc;
+
+ uint16 handle = argv[0].toUint16();
+
+#ifdef ENABLE_SCI32
+ if (handle == VIRTUALFILE_HANDLE) {
+ s->_virtualIndexFile->close();
+ return SIGNAL_REG;
+ }
+#endif
+
+ FileHandle *f = getFileFromHandle(s, handle);
if (f) {
f->close();
+ if (getSciVersion() <= SCI_VERSION_0_LATE)
+ return s->r_acc; // SCI0 semantics: no value returned
return SIGNAL_REG;
}
+
+ if (getSciVersion() <= SCI_VERSION_0_LATE)
+ return s->r_acc; // SCI0 semantics: no value returned
return NULL_REG;
}
reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv) {
- int handle = argv[0].toUint16();
- int size = argv[2].toUint16();
+ uint16 handle = argv[0].toUint16();
+ uint16 size = argv[2].toUint16();
int bytesRead = 0;
char *buf = new char[size];
debugC(kDebugLevelFile, "kFileIO(readRaw): %d, %d", handle, size);
- FileHandle *f = getFileFromHandle(s, handle);
- if (f) {
- bytesRead = f->_in->read(buf, size);
- // TODO: What happens if less bytes are read than what has
- // been requested? (i.e. if bytesRead is non-zero, but still
- // less than size)
- if (bytesRead > 0)
- s->_segMan->memcpy(argv[1], (const byte*)buf, size);
+#ifdef ENABLE_SCI32
+ if (handle == VIRTUALFILE_HANDLE) {
+ bytesRead = s->_virtualIndexFile->read(buf, size);
+ } else {
+#endif
+ FileHandle *f = getFileFromHandle(s, handle);
+ if (f)
+ bytesRead = f->_in->read(buf, size);
+#ifdef ENABLE_SCI32
}
+#endif
+
+ // TODO: What happens if less bytes are read than what has
+ // been requested? (i.e. if bytesRead is non-zero, but still
+ // less than size)
+ if (bytesRead > 0)
+ s->_segMan->memcpy(argv[1], (const byte*)buf, size);
delete[] buf;
return make_reg(0, bytesRead);
}
reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) {
- int handle = argv[0].toUint16();
- int size = argv[2].toUint16();
+ uint16 handle = argv[0].toUint16();
+ uint16 size = argv[2].toUint16();
char *buf = new char[size];
bool success = false;
s->_segMan->memcpy((byte *)buf, argv[1], size);
debugC(kDebugLevelFile, "kFileIO(writeRaw): %d, %d", handle, size);
- FileHandle *f = getFileFromHandle(s, handle);
- if (f) {
- f->_out->write(buf, size);
+#ifdef ENABLE_SCI32
+ if (handle == VIRTUALFILE_HANDLE) {
+ s->_virtualIndexFile->write(buf, size);
success = true;
+ } else {
+#endif
+ FileHandle *f = getFileFromHandle(s, handle);
+ if (f) {
+ f->_out->write(buf, size);
+ success = true;
+ }
+#ifdef ENABLE_SCI32
}
+#endif
delete[] buf;
if (success)
@@ -868,9 +439,19 @@ reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) {
name = g_sci->getSavegameName(savedir_nr);
result = saveFileMan->removeSavefile(name);
} else if (getSciVersion() >= SCI_VERSION_2) {
- // We don't need to wrap the filename in SCI32 games, as it's already
- // constructed here
+ // The file name may be already wrapped, so check both cases
result = saveFileMan->removeSavefile(name);
+ if (!result) {
+ const Common::String wrappedName = g_sci->wrapFilename(name);
+ result = saveFileMan->removeSavefile(wrappedName);
+ }
+
+#ifdef ENABLE_SCI32
+ if (name == PHANTASMAGORIA_SAVEGAME_INDEX) {
+ delete s->_virtualIndexFile;
+ s->_virtualIndexFile = 0;
+ }
+#endif
} else {
const Common::String wrappedName = g_sci->wrapFilename(name);
result = saveFileMan->removeSavefile(wrappedName);
@@ -883,15 +464,22 @@ reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) {
}
reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv) {
- int size = argv[1].toUint16();
- char *buf = new char[size];
- int handle = argv[2].toUint16();
- debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, size);
+ uint16 maxsize = argv[1].toUint16();
+ char *buf = new char[maxsize];
+ uint16 handle = argv[2].toUint16();
+ debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, maxsize);
+ uint32 bytesRead;
- int readBytes = fgets_wrapper(s, buf, size, handle);
- s->_segMan->memcpy(argv[0], (const byte*)buf, size);
+#ifdef ENABLE_SCI32
+ if (handle == VIRTUALFILE_HANDLE)
+ bytesRead = s->_virtualIndexFile->readLine(buf, maxsize);
+ else
+#endif
+ bytesRead = fgets_wrapper(s, buf, maxsize, handle);
+
+ s->_segMan->memcpy(argv[0], (const byte*)buf, maxsize);
delete[] buf;
- return readBytes ? argv[0] : NULL_REG;
+ return bytesRead ? argv[0] : NULL_REG;
}
reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) {
@@ -899,126 +487,55 @@ reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) {
Common::String str = s->_segMan->getString(argv[1]);
debugC(kDebugLevelFile, "kFileIO(writeString): %d", handle);
+#ifdef ENABLE_SCI32
+ if (handle == VIRTUALFILE_HANDLE) {
+ s->_virtualIndexFile->write(str.c_str(), str.size());
+ return NULL_REG;
+ }
+#endif
+
FileHandle *f = getFileFromHandle(s, handle);
if (f) {
f->_out->write(str.c_str(), str.size());
+ if (getSciVersion() <= SCI_VERSION_0_LATE)
+ return s->r_acc; // SCI0 semantics: no value returned
return NULL_REG;
}
+ if (getSciVersion() <= SCI_VERSION_0_LATE)
+ return s->r_acc; // SCI0 semantics: no value returned
return make_reg(0, 6); // DOS - invalid handle
}
reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) {
- int handle = argv[0].toUint16();
- int offset = argv[1].toUint16();
- int whence = argv[2].toUint16();
+ uint16 handle = argv[0].toUint16();
+ uint16 offset = ABS<int16>(argv[1].toSint16()); // can be negative
+ uint16 whence = argv[2].toUint16();
debugC(kDebugLevelFile, "kFileIO(seek): %d, %d, %d", handle, offset, whence);
- FileHandle *f = getFileFromHandle(s, handle);
-
- if (f)
- s->r_acc = make_reg(0, f->_in->seek(offset, whence));
-
- return SIGNAL_REG;
-}
-
-void DirSeeker::addAsVirtualFiles(Common::String title, Common::String fileMask) {
- Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
- Common::StringArray foundFiles = saveFileMan->listSavefiles(fileMask);
- if (!foundFiles.empty()) {
- _files.push_back(title);
- _virtualFiles.push_back("");
- Common::StringArray::iterator it;
- Common::StringArray::iterator it_end = foundFiles.end();
-
- for (it = foundFiles.begin(); it != it_end; it++) {
- Common::String regularFilename = *it;
- Common::String wrappedFilename = Common::String(regularFilename.c_str() + fileMask.size() - 1);
-
- Common::SeekableReadStream *testfile = saveFileMan->openForLoading(regularFilename);
- int32 testfileSize = testfile->size();
- delete testfile;
- if (testfileSize > 1024) // check, if larger than 1k. in that case its a saved game.
- continue; // and we dont want to have those in the list
- // We need to remove the prefix for display purposes
- _files.push_back(wrappedFilename);
- // but remember the actual name as well
- _virtualFiles.push_back(regularFilename);
- }
- }
-}
+#ifdef ENABLE_SCI32
+ if (handle == VIRTUALFILE_HANDLE)
+ return make_reg(0, s->_virtualIndexFile->seek(offset, whence));
+#endif
-Common::String DirSeeker::getVirtualFilename(uint fileNumber) {
- if (fileNumber >= _virtualFiles.size())
- error("invalid virtual filename access");
- return _virtualFiles[fileNumber];
-}
+ FileHandle *f = getFileFromHandle(s, handle);
-reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) {
- // Verify that we are given a valid buffer
- if (!buffer.segment) {
- error("DirSeeker::firstFile('%s') invoked with invalid buffer", mask.c_str());
- return NULL_REG;
- }
- _outbuffer = buffer;
- _files.clear();
- _virtualFiles.clear();
-
- int QfGImport = g_sci->inQfGImportRoom();
- if (QfGImport) {
- _files.clear();
- addAsVirtualFiles("-QfG1-", "qfg1-*");
- addAsVirtualFiles("-QfG1VGA-", "qfg1vga-*");
- if (QfGImport > 2)
- addAsVirtualFiles("-QfG2-", "qfg2-*");
- if (QfGImport > 3)
- addAsVirtualFiles("-QfG3-", "qfg3-*");
-
- if (QfGImport == 3) {
- // QfG3 sorts the filelisting itself, we can't let that happen otherwise our
- // virtual list would go out-of-sync
- reg_t savedHeros = segMan->findObjectByName("savedHeros");
- if (!savedHeros.isNull())
- writeSelectorValue(segMan, savedHeros, SELECTOR(sort), 0);
+ if (f && f->_in) {
+ // Backward seeking isn't supported in zip file streams, thus adapt the
+ // parameters accordingly if games ask for such a seek mode. A known
+ // case where this is requested is the save file manager in Phantasmagoria
+ if (whence == SEEK_END) {
+ whence = SEEK_SET;
+ offset = f->_in->size() - offset;
}
- } else {
- // Prefix the mask
- const Common::String wrappedMask = g_sci->wrapFilename(mask);
-
- // Obtain a list of all files matching the given mask
- Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
- _files = saveFileMan->listSavefiles(wrappedMask);
- }
-
- // Reset the list iterator and write the first match to the output buffer,
- // if any.
- _iter = _files.begin();
- return nextFile(segMan);
-}
-
-reg_t DirSeeker::nextFile(SegManager *segMan) {
- if (_iter == _files.end()) {
- return NULL_REG;
+ return make_reg(0, f->_in->seek(offset, whence));
+ } else if (f && f->_out) {
+ error("kFileIOSeek: Unsupported seek operation on a writeable stream (offset: %d, whence: %d)", offset, whence);
}
- Common::String string;
-
- if (_virtualFiles.empty()) {
- // Strip the prefix, if we don't got a virtual filelisting
- const Common::String wrappedString = *_iter;
- string = g_sci->unwrapFilename(wrappedString);
- } else {
- string = *_iter;
- }
- if (string.size() > 12)
- string = Common::String(string.c_str(), 12);
- segMan->strcpy(_outbuffer, string.c_str());
-
- // Return the result and advance the list iterator :)
- ++_iter;
- return _outbuffer;
+ return SIGNAL_REG;
}
reg_t kFileIOFindFirst(EngineState *s, int argc, reg_t *argv) {
@@ -1041,6 +558,14 @@ reg_t kFileIOFindNext(EngineState *s, int argc, reg_t *argv) {
reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) {
Common::String name = s->_segMan->getString(argv[0]);
+#ifdef ENABLE_SCI32
+ // Cache the file existence result for the Phantasmagoria
+ // save index file, as the game scripts keep checking for
+ // its existence.
+ if (name == PHANTASMAGORIA_SAVEGAME_INDEX && s->_virtualIndexFile)
+ return TRUE_REG;
+#endif
+
bool exists = false;
// Check for regular file
@@ -1163,19 +688,283 @@ reg_t kFileIOCreateSaveSlot(EngineState *s, int argc, reg_t *argv) {
return TRUE_REG; // slot creation was successful
}
-reg_t kCD(EngineState *s, int argc, reg_t *argv) {
- // TODO: Stub
- switch (argv[0].toUint16()) {
- case 0:
- // Return whether the contents of disc argv[1] is available.
- return TRUE_REG;
- default:
- warning("CD(%d)", argv[0].toUint16());
+#endif
+
+// ---- Save operations -------------------------------------------------------
+
+#ifdef ENABLE_SCI32
+
+reg_t kSave(EngineState *s, int argc, reg_t *argv) {
+ if (!s)
+ return make_reg(0, getSciVersion());
+ error("not supposed to call this");
+}
+
+#endif
+
+reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) {
+ Common::String game_id;
+ int16 virtualId = argv[1].toSint16();
+ int16 savegameId = -1;
+ Common::String game_description;
+ Common::String version;
+
+ if (argc > 3)
+ version = s->_segMan->getString(argv[3]);
+
+ // We check here, we don't want to delete a users save in case we are within a kernel function
+ if (s->executionStackBase) {
+ warning("kSaveGame - won't save from within kernel function");
+ return NULL_REG;
}
- return NULL_REG;
+ if (argv[0].isNull()) {
+ // Direct call, from a patched Game::save
+ if ((argv[1] != SIGNAL_REG) || (!argv[2].isNull()))
+ error("kSaveGame: assumed patched call isn't accurate");
+
+ // we are supposed to show a dialog for the user and let him choose where to save
+ g_sci->_soundCmd->pauseAll(true); // pause music
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
+ savegameId = dialog->runModalWithCurrentTarget();
+ game_description = dialog->getResultString();
+ if (game_description.empty()) {
+ // create our own description for the saved game, the user didnt enter it
+ game_description = dialog->createDefaultSaveDescription(savegameId);
+ }
+ delete dialog;
+ g_sci->_soundCmd->pauseAll(false); // unpause music ( we can't have it paused during save)
+ if (savegameId < 0)
+ return NULL_REG;
+
+ } else {
+ // Real call from script
+ game_id = s->_segMan->getString(argv[0]);
+ if (argv[2].isNull())
+ error("kSaveGame: called with description being NULL");
+ game_description = s->_segMan->getString(argv[2]);
+
+ debug(3, "kSaveGame(%s,%d,%s,%s)", game_id.c_str(), virtualId, game_description.c_str(), version.c_str());
+
+ Common::Array<SavegameDesc> saves;
+ listSavegames(saves);
+
+ if ((virtualId >= SAVEGAMEID_OFFICIALRANGE_START) && (virtualId <= SAVEGAMEID_OFFICIALRANGE_END)) {
+ // savegameId is an actual Id, so search for it just to make sure
+ savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START;
+ if (findSavegame(saves, savegameId) == -1)
+ return NULL_REG;
+ } else if (virtualId < SAVEGAMEID_OFFICIALRANGE_START) {
+ // virtualId is low, we assume that scripts expect us to create new slot
+ if (virtualId == s->_lastSaveVirtualId) {
+ // if last virtual id is the same as this one, we assume that caller wants to overwrite last save
+ savegameId = s->_lastSaveNewId;
+ } else {
+ uint savegameNr;
+ // savegameId is in lower range, scripts expect us to create a new slot
+ for (savegameId = 0; savegameId < SAVEGAMEID_OFFICIALRANGE_START; savegameId++) {
+ for (savegameNr = 0; savegameNr < saves.size(); savegameNr++) {
+ if (savegameId == saves[savegameNr].id)
+ break;
+ }
+ if (savegameNr == saves.size())
+ break;
+ }
+ if (savegameId == SAVEGAMEID_OFFICIALRANGE_START)
+ error("kSavegame: no more savegame slots available");
+ }
+ } else {
+ error("kSaveGame: invalid savegameId used");
+ }
+
+ // Save in case caller wants to overwrite last newly created save
+ s->_lastSaveVirtualId = virtualId;
+ s->_lastSaveNewId = savegameId;
+ }
+
+ s->r_acc = NULL_REG;
+
+ Common::String filename = g_sci->getSavegameName(savegameId);
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
+ Common::OutSaveFile *out;
+
+ out = saveFileMan->openForSaving(filename);
+ if (!out) {
+ warning("Error opening savegame \"%s\" for writing", filename.c_str());
+ } else {
+ if (!gamestate_save(s, out, game_description, version)) {
+ warning("Saving the game failed");
+ } else {
+ s->r_acc = TRUE_REG; // save successful
+ }
+
+ out->finalize();
+ if (out->err()) {
+ warning("Writing the savegame failed");
+ s->r_acc = NULL_REG; // write failure
+ }
+ delete out;
+ }
+
+ return s->r_acc;
}
+reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
+ Common::String game_id = !argv[0].isNull() ? s->_segMan->getString(argv[0]) : "";
+ int16 savegameId = argv[1].toSint16();
+ bool pausedMusic = false;
+
+ debug(3, "kRestoreGame(%s,%d)", game_id.c_str(), savegameId);
+
+ if (argv[0].isNull()) {
+ // Direct call, either from launcher or from a patched Game::restore
+ if (savegameId == -1) {
+ // we are supposed to show a dialog for the user and let him choose a saved game
+ g_sci->_soundCmd->pauseAll(true); // pause music
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
+ savegameId = dialog->runModalWithCurrentTarget();
+ delete dialog;
+ if (savegameId < 0) {
+ g_sci->_soundCmd->pauseAll(false); // unpause music
+ return s->r_acc;
+ }
+ pausedMusic = true;
+ }
+ // don't adjust ID of the saved game, it's already correct
+ } else {
+ if (argv[2].isNull())
+ error("kRestoreGame: called with parameter 2 being NULL");
+ // Real call from script, we need to adjust ID
+ if ((savegameId < SAVEGAMEID_OFFICIALRANGE_START) || (savegameId > SAVEGAMEID_OFFICIALRANGE_END)) {
+ warning("Savegame ID %d is not allowed", savegameId);
+ return TRUE_REG;
+ }
+ savegameId -= SAVEGAMEID_OFFICIALRANGE_START;
+ }
+
+ s->r_acc = NULL_REG; // signals success
+
+ Common::Array<SavegameDesc> saves;
+ listSavegames(saves);
+ if (findSavegame(saves, savegameId) == -1) {
+ s->r_acc = TRUE_REG;
+ warning("Savegame ID %d not found", savegameId);
+ } else {
+ Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager();
+ Common::String filename = g_sci->getSavegameName(savegameId);
+ Common::SeekableReadStream *in;
+
+ in = saveFileMan->openForLoading(filename);
+ if (in) {
+ // found a savegame file
+
+ gamestate_restore(s, in);
+ delete in;
+
+ if (g_sci->getGameId() == GID_MOTHERGOOSE256) {
+ // WORKAROUND: Mother Goose SCI1/SCI1.1 does some weird things for
+ // saving a previously restored game.
+ // We set the current savedgame-id directly and remove the script
+ // code concerning this via script patch.
+ s->variables[VAR_GLOBAL][0xB3].offset = SAVEGAMEID_OFFICIALRANGE_START + savegameId;
+ }
+ } else {
+ s->r_acc = TRUE_REG;
+ warning("Savegame #%d not found", savegameId);
+ }
+ }
+
+ if (!s->r_acc.isNull()) {
+ // no success?
+ if (pausedMusic)
+ g_sci->_soundCmd->pauseAll(false); // unpause music
+ }
+
+ return s->r_acc;
+}
+
+reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) {
+#ifdef ENABLE_SCI32
+ // SCI32 uses a parameter here. It is used to modify a string, stored in a
+ // global variable, so that game scripts store the save directory. We
+ // don't really set a save game directory, thus not setting the string to
+ // anything is the correct thing to do here.
+ //if (argc > 0)
+ // warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0]));
+#endif
+ return s->_segMan->getSaveDirPtr();
+}
+
+reg_t kCheckSaveGame(EngineState *s, int argc, reg_t *argv) {
+ Common::String game_id = s->_segMan->getString(argv[0]);
+ uint16 virtualId = argv[1].toUint16();
+
+ debug(3, "kCheckSaveGame(%s, %d)", game_id.c_str(), virtualId);
+
+ Common::Array<SavegameDesc> saves;
+ listSavegames(saves);
+
+ // we allow 0 (happens in QfG2 when trying to restore from an empty saved game list) and return false in that case
+ if (virtualId == 0)
+ return NULL_REG;
+
+ // Find saved-game
+ if ((virtualId < SAVEGAMEID_OFFICIALRANGE_START) || (virtualId > SAVEGAMEID_OFFICIALRANGE_END))
+ error("kCheckSaveGame: called with invalid savegameId");
+ uint savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START;
+ int savegameNr = findSavegame(saves, savegameId);
+ if (savegameNr == -1)
+ return NULL_REG;
+
+ // Check for compatible savegame version
+ int ver = saves[savegameNr].version;
+ if (ver < MINIMUM_SAVEGAME_VERSION || ver > CURRENT_SAVEGAME_VERSION)
+ return NULL_REG;
+
+ // Otherwise we assume the savegame is OK
+ return TRUE_REG;
+}
+
+reg_t kGetSaveFiles(EngineState *s, int argc, reg_t *argv) {
+ Common::String game_id = s->_segMan->getString(argv[0]);
+
+ debug(3, "kGetSaveFiles(%s)", game_id.c_str());
+
+ // Scripts ask for current save files, we can assume that if afterwards they ask us to create a new slot they really
+ // mean new slot instead of overwriting the old one
+ s->_lastSaveVirtualId = SAVEGAMEID_OFFICIALRANGE_START;
+
+ Common::Array<SavegameDesc> saves;
+ listSavegames(saves);
+ uint totalSaves = MIN<uint>(saves.size(), MAX_SAVEGAME_NR);
+
+ reg_t *slot = s->_segMan->derefRegPtr(argv[2], totalSaves);
+
+ if (!slot) {
+ warning("kGetSaveFiles: %04X:%04X invalid or too small to hold slot data", PRINT_REG(argv[2]));
+ totalSaves = 0;
+ }
+
+ const uint bufSize = (totalSaves * SCI_MAX_SAVENAME_LENGTH) + 1;
+ char *saveNames = new char[bufSize];
+ char *saveNamePtr = saveNames;
+
+ for (uint i = 0; i < totalSaves; i++) {
+ *slot++ = make_reg(0, saves[i].id + SAVEGAMEID_OFFICIALRANGE_START); // Store the virtual savegame ID ffs. see above
+ strcpy(saveNamePtr, saves[i].name);
+ saveNamePtr += SCI_MAX_SAVENAME_LENGTH;
+ }
+
+ *saveNamePtr = 0; // Terminate list
+
+ s->_segMan->memcpy(argv[1], (byte *)saveNames, bufSize);
+ delete[] saveNames;
+
+ return make_reg(0, totalSaves);
+}
+
+#ifdef ENABLE_SCI32
+
reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv) {
// Normally, this creates the name of the save catalogue/directory to save into.
// First parameter is the string to save the result into. Second is a string
@@ -1205,35 +994,15 @@ reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv) {
return argv[0];
}
-reg_t kSave(EngineState *s, int argc, reg_t *argv) {
- switch (argv[0].toUint16()) {
- case 0:
- return kSaveGame(s, argc - 1,argv + 1);
- case 1:
- return kRestoreGame(s, argc - 1,argv + 1);
- case 2:
- return kGetSaveDir(s, argc - 1, argv + 1);
- case 3:
- return kCheckSaveGame(s, argc - 1, argv + 1);
- case 5:
- return kGetSaveFiles(s, argc - 1, argv + 1);
- case 6:
- return kMakeSaveCatName(s, argc - 1, argv + 1);
- case 7:
- return kMakeSaveFileName(s, argc - 1, argv + 1);
- case 8:
- // TODO
- // This is a timer callback, with 1 parameter: the timer object
- // (e.g. "timers").
- // It's used for auto-saving (i.e. save every X minutes, by checking
- // the elapsed time from the timer object)
-
- // This function has to return something other than 0 to proceed
- return s->r_acc;
- default:
- kStub(s, argc, argv);
- return NULL_REG;
- }
+reg_t kAutoSave(EngineState *s, int argc, reg_t *argv) {
+ // TODO
+ // This is a timer callback, with 1 parameter: the timer object
+ // (e.g. "timers").
+ // It's used for auto-saving (i.e. save every X minutes, by checking
+ // the elapsed time from the timer object)
+
+ // This function has to return something other than 0 to proceed
+ return s->r_acc;
}
#endif
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index 2bb8288cb7..53cf8ada75 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -308,103 +308,91 @@ reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) {
}
reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) {
- // Used by Phantasmagoria 1 and SQ6. In SQ6, it is used for the messages
- // shown in the scroll window at the bottom of the screen.
-
- // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now
- kStub(s, argc, argv);
-
- switch (argv[0].toUint16()) {
+ // Used by SQ6 and LSL6 hires for the text area in the bottom of the
+ // screen. The relevant scripts also exist in Phantasmagoria 1, but they're
+ // unused. This is always called by scripts 64906 (ScrollerWindow) and
+ // 64907 (ScrollableWindow).
+
+ reg_t kWindow = argv[1];
+ uint16 op = argv[0].toUint16();
+ switch (op) {
case 0: // Init
- // 2 parameters
- // argv[1] points to the scroll object (e.g. textScroller in SQ6)
- // argv[2] is an integer (e.g. 0x32)
- break;
- case 1: // Show message
+ g_sci->_gfxFrameout->initScrollText(argv[2].toUint16()); // maxItems
+ g_sci->_gfxFrameout->clearScrollTexts();
+ return argv[1]; // kWindow
+ case 1: // Show message, called by ScrollableWindow::addString
+ case 14: // Modify message, called by ScrollableWindow::modifyString
// 5 or 6 parameters
// Seems to be called with 5 parameters when the narrator speaks, and
// with 6 when Roger speaks
- // argv[1] unknown (usually 0)
- // argv[2] the text to show
- // argv[3] a small integer (e.g. 0x32)
- // argv[4] a small integer (e.g. 0x54)
- // argv[5] optional, unknown (usually 0)
- warning("kScrollWindow: '%s'", s->_segMan->getString(argv[2]).c_str());
- break;
- case 2: // Clear
- // 2 parameters
- // TODO
- break;
- case 3: // Page up
- // 2 parameters
- // TODO
+ {
+ Common::String text = s->_segMan->getString(argv[2]);
+ uint16 x = 0;//argv[3].toUint16(); // TODO: can't be x (values are all wrong)
+ uint16 y = 0;//argv[4].toUint16(); // TODO: can't be y (values are all wrong)
+ // TODO: argv[5] is an optional unknown parameter (an integer set to 0)
+ g_sci->_gfxFrameout->addScrollTextEntry(text, kWindow, x, y, (op == 14));
+ }
break;
- case 4: // Page down
- // 2 parameters
- // TODO
+ case 2: // Clear, called by ScrollableWindow::erase
+ g_sci->_gfxFrameout->clearScrollTexts();
break;
- case 5: // Up arrow
- // 2 parameters
+ case 3: // Page up, called by ScrollableWindow::scrollTo
// TODO
+ kStub(s, argc, argv);
break;
- case 6: // Down arrow
- // 2 parameters
+ case 4: // Page down, called by ScrollableWindow::scrollTo
// TODO
+ kStub(s, argc, argv);
break;
- case 7: // Home
- // 2 parameters
- // TODO
+ case 5: // Up arrow, called by ScrollableWindow::scrollTo
+ g_sci->_gfxFrameout->prevScrollText();
break;
- case 8: // End
- // 2 parameters
- // TODO
+ case 6: // Down arrow, called by ScrollableWindow::scrollTo
+ g_sci->_gfxFrameout->nextScrollText();
break;
- case 9: // Resize
- // 3 parameters
- // TODO
+ case 7: // Home, called by ScrollableWindow::scrollTo
+ g_sci->_gfxFrameout->firstScrollText();
break;
- case 10: // Where
- // 3 parameters
- // TODO
+ case 8: // End, called by ScrollableWindow::scrollTo
+ g_sci->_gfxFrameout->lastScrollText();
break;
- case 11: // Go
- // 4 parameters
+ case 9: // Resize, called by ScrollableWindow::resize and ScrollerWindow::resize
// TODO
+ kStub(s, argc, argv);
break;
- case 12: // Insert
- // 7 parameters
+ case 10: // Where, called by ScrollableWindow::where
// TODO
+ // argv[2] is an unknown integer
+ kStub(s, argc, argv);
break;
- case 13: // Delete
- // 3 parameters
+ case 11: // Go, called by ScrollableWindow::scrollTo
+ // 2 extra parameters here
// TODO
+ kStub(s, argc, argv);
break;
- case 14: // Modify
- // 7 or 8 parameters
+ case 12: // Insert, called by ScrollableWindow::insertString
+ // 3 extra parameters here
// TODO
+ kStub(s, argc, argv);
break;
- case 15: // Hide
- // 2 parameters
- // TODO
+ // case 13 (Delete) is handled below
+ // case 14 (Modify) is handled above
+ case 15: // Hide, called by ScrollableWindow::hide
+ g_sci->_gfxFrameout->toggleScrollText(false);
break;
- case 16: // Show
- // 2 parameters
- // TODO
+ case 16: // Show, called by ScrollableWindow::show
+ g_sci->_gfxFrameout->toggleScrollText(true);
break;
- case 17: // Destroy
- // 2 parameters
- // TODO
+ case 17: // Destroy, called by ScrollableWindow::dispose
+ g_sci->_gfxFrameout->clearScrollTexts();
break;
- case 18: // Text
- // 2 parameters
- // TODO
- break;
- case 19: // Reconstruct
- // 3 parameters
- // TODO
+ case 13: // Delete, unused
+ case 18: // Text, unused
+ case 19: // Reconstruct, unused
+ error("kScrollWindow: Unused subop %d invoked", op);
break;
default:
- error("kScrollWindow: unknown subop %d", argv[0].toUint16());
+ error("kScrollWindow: unknown subop %d", op);
break;
}
@@ -617,6 +605,38 @@ reg_t kEditText(EngineState *s, int argc, reg_t *argv) {
return s->r_acc;
}
+reg_t kAddLine(EngineState *s, int argc, reg_t *argv) {
+ reg_t plane = argv[0];
+ Common::Point startPoint(argv[1].toUint16(), argv[2].toUint16());
+ Common::Point endPoint(argv[3].toUint16(), argv[4].toUint16());
+ // argv[5] is unknown (a number, usually 200)
+ byte color = (byte)argv[6].toUint16();
+ byte priority = (byte)argv[7].toUint16();
+ byte control = (byte)argv[8].toUint16();
+ // argv[9] is unknown (usually a small number, 1 or 2). Thickness, perhaps?
+ return g_sci->_gfxFrameout->addPlaneLine(plane, startPoint, endPoint, color, priority, control);
+}
+
+reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv) {
+ reg_t hunkId = argv[0];
+ reg_t plane = argv[1];
+ Common::Point startPoint(argv[2].toUint16(), argv[3].toUint16());
+ Common::Point endPoint(argv[4].toUint16(), argv[5].toUint16());
+ // argv[6] is unknown (a number, usually 200)
+ byte color = (byte)argv[7].toUint16();
+ byte priority = (byte)argv[8].toUint16();
+ byte control = (byte)argv[9].toUint16();
+ // argv[10] is unknown (usually a small number, 1 or 2). Thickness, perhaps?
+ g_sci->_gfxFrameout->updatePlaneLine(plane, hunkId, startPoint, endPoint, color, priority, control);
+ return s->r_acc;
+}
+reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv) {
+ reg_t hunkId = argv[0];
+ reg_t plane = argv[1];
+ g_sci->_gfxFrameout->deletePlaneLine(plane, hunkId);
+ return s->r_acc;
+}
+
#endif
} // End of namespace Sci
diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp
index 2a33df26bc..5a608af034 100644
--- a/engines/sci/engine/klists.cpp
+++ b/engines/sci/engine/klists.cpp
@@ -575,8 +575,11 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) {
// First, check if the target selector is a variable
if (lookupSelector(s->_segMan, curObject, slc, &address, NULL) == kSelectorVariable) {
- // Can this happen with variable selectors?
- error("kListFirstTrue: Attempted to access a variable selector");
+ // If it's a variable selector, check its value.
+ // Example: script 64893 in Torin, MenuHandler::isHilited checks
+ // all children for variable selector 0x03ba (bHilited).
+ if (!readSelector(s->_segMan, curObject, slc).isNull())
+ return curObject;
} else {
invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2);
@@ -609,16 +612,16 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) {
// First, check if the target selector is a variable
if (lookupSelector(s->_segMan, curObject, slc, &address, NULL) == kSelectorVariable) {
- // Can this happen with variable selectors?
- error("kListAllTrue: Attempted to access a variable selector");
+ // If it's a variable selector, check its value
+ s->r_acc = readSelector(s->_segMan, curObject, slc);
} else {
invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2);
-
- // Check if the result isn't true
- if (s->r_acc.isNull())
- break;
}
+ // Check if the result isn't true
+ if (s->r_acc.isNull())
+ break;
+
curNode = s->_segMan->lookupNode(nextNode);
}
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index 9a113bc5f9..2e80764d01 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -384,6 +384,16 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) {
} else if (setting == "language") {
Common::String languageId = Common::String::format("%d", g_sci->getSciLanguage());
s->_segMan->strcpy(data, languageId.c_str());
+ } else if (setting == "torindebug") {
+ // Used to enable the debug mode in Torin's Passage (French).
+ // If true, the debug mode is enabled.
+ s->_segMan->strcpy(data, "");
+ } else if (setting == "leakdump") {
+ // An unknown setting in LSL7. Likely used for debugging.
+ s->_segMan->strcpy(data, "");
+ } else if (setting == "startroom") {
+ // Debug setting in LSL7, specifies the room to start from.
+ s->_segMan->strcpy(data, "");
} else {
error("GetConfig: Unknown configuration setting %s", setting.c_str());
}
@@ -391,22 +401,22 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) {
return argv[1];
}
+// Likely modelled after the Windows 3.1 function GetPrivateProfileInt:
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724345%28v=vs.85%29.aspx
reg_t kGetSierraProfileInt(EngineState *s, int argc, reg_t *argv) {
Common::String category = s->_segMan->getString(argv[0]); // always "config"
category.toLowercase();
- if (category != "config")
- error("GetSierraProfileInt: category isn't 'config', it's '%s'", category.c_str());
-
Common::String setting = s->_segMan->getString(argv[1]);
setting.toLowercase();
- if (setting != "videospeed")
- error("GetSierraProfileInt: setting isn't 'videospeed', it's '%s'", setting.c_str());
+ // The third parameter is the default value returned if the configuration key is missing
- // The game scripts pass 425 as the third parameter for some unknown reason,
- // as after the call they compare the result to 425 anyway...
+ if (category == "config" && setting == "videospeed") {
+ // We return the same fake value for videospeed as with kGetConfig
+ return make_reg(0, 500);
+ }
- // We return the same fake value for videospeed as with kGetConfig
- return make_reg(0, 500);
+ warning("kGetSierraProfileInt: Returning default value %d for unknown setting %s.%s", argv[2].toSint16(), category.c_str(), setting.c_str());
+ return argv[2];
}
#endif
diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp
index c469f775f9..b378b4d58b 100644
--- a/engines/sci/engine/ksound.cpp
+++ b/engines/sci/engine/ksound.cpp
@@ -140,8 +140,12 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {
((argv[3].toUint16() & 0xff) << 16) |
((argv[4].toUint16() & 0xff) << 8) |
(argv[5].toUint16() & 0xff);
- if (argc == 8)
- warning("kDoAudio: Play called with SQ6 extra parameters");
+ if (argc == 8) {
+ // argv[6] is always 1
+ // argv[7] is the contents of global 229 (0xE5)
+ warning("kDoAudio: Play called with SCI2.1 extra parameters: %04x:%04x and %04x:%04x",
+ PRINT_REG(argv[6]), PRINT_REG(argv[7]));
+ }
} else {
warning("kDoAudio: Play called with an unknown number of parameters (%d)", argc);
return NULL_REG;
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index fe8d631497..33b8c15e9f 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -653,10 +653,16 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
case 1: // Size
return make_reg(0, s->_segMan->getString(argv[1]).size());
case 2: { // At (return value at an index)
- if (argv[1].segment == s->_segMan->getStringSegmentId())
- return make_reg(0, s->_segMan->lookupString(argv[1])->getRawData()[argv[2].toUint16()]);
-
- return make_reg(0, s->_segMan->getString(argv[1])[argv[2].toUint16()]);
+ // Note that values are put in bytes to avoid sign extension
+ if (argv[1].segment == s->_segMan->getStringSegmentId()) {
+ SciString *string = s->_segMan->lookupString(argv[1]);
+ byte val = string->getRawData()[argv[2].toUint16()];
+ return make_reg(0, val);
+ } else {
+ Common::String string = s->_segMan->getString(argv[1]);
+ byte val = string[argv[2].toUint16()];
+ return make_reg(0, val);
+ }
}
case 3: { // Atput (put value at an index)
SciString *string = s->_segMan->lookupString(argv[1]);
diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp
index c9cf652013..f176a13721 100644
--- a/engines/sci/engine/kvideo.cpp
+++ b/engines/sci/engine/kvideo.cpp
@@ -259,6 +259,7 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv) {
warning("kRobot(%d)", subop);
break;
case 8: // sync
+ //if (false) { // debug: automatically skip all robot videos
if ((uint32)g_sci->_robotDecoder->getCurFrame() != g_sci->_robotDecoder->getFrameCount() - 1) {
writeSelector(s->_segMan, argv[1], SELECTOR(signal), NULL_REG);
} else {
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 404bea799d..7c41e18bec 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -467,7 +467,7 @@ void Script::syncStringHeap(Common::Serializer &s) {
break;
} while (1);
- } else {
+ } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){
// Strings in SCI1.1 come after the object instances
byte *buf = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2;
@@ -477,6 +477,8 @@ void Script::syncStringHeap(Common::Serializer &s) {
// Now, sync everything till the end of the buffer
s.syncBytes(buf, _heapSize - (buf - _heapStart));
+ } else if (getSciVersion() == SCI_VERSION_3) {
+ warning("TODO: syncStringHeap(): Implement SCI3 variant");
}
}
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 8b26969f4a..5f0118b5b6 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -115,6 +115,13 @@ void Script::init(int script_nr, ResourceManager *resMan) {
// scheme. We need an overlaying mechanism, or a mechanism to split script parts
// in different segments to handle these. For now, simply stop when such a script
// is found.
+ //
+ // Known large SCI 3 scripts are:
+ // Lighthouse: 9, 220, 270, 351, 360, 490, 760, 765, 800
+ // LSL7: 240, 511, 550
+ // Phantasmagoria 2: none (hooray!)
+ // RAMA: 70
+ //
// TODO: Remove this once such a mechanism is in place
if (script->size > 65535)
error("TODO: SCI script %d is over 64KB - it's %d bytes long. This can't "
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 1ebae3b7a8..a180579d2f 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -57,7 +57,7 @@ private:
int _lockers; /**< Number of classes and objects that require this script */
size_t _scriptSize;
size_t _heapSize;
- uint16 _bufSize;
+ size_t _bufSize;
const uint16 *_exportTable; /**< Abs. offset of the export table or 0 if not present */
uint16 _numExports; /**< Number of entries in the exports table */
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 28818cddef..237c6b54a6 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -26,6 +26,7 @@
#include "sci/debug.h" // for g_debug_sleeptime_factor
#include "sci/event.h"
+#include "sci/engine/file.h"
#include "sci/engine/kernel.h"
#include "sci/engine/state.h"
#include "sci/engine/selector.h"
@@ -68,21 +69,26 @@ static const uint16 s_halfWidthSJISMap[256] = {
};
EngineState::EngineState(SegManager *segMan)
-: _segMan(segMan), _dirseeker() {
+: _segMan(segMan),
+#ifdef ENABLE_SCI32
+ _virtualIndexFile(0),
+#endif
+ _dirseeker() {
reset(false);
}
EngineState::~EngineState() {
delete _msgState;
+#ifdef ENABLE_SCI32
+ delete _virtualIndexFile;
+#endif
}
void EngineState::reset(bool isRestoring) {
if (!isRestoring) {
_memorySegmentSize = 0;
-
_fileHandles.resize(5);
-
abortScriptProcessing = kAbortNone;
}
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index dcffe6dbb3..78a8a5b0a2 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -34,6 +34,7 @@ class WriteStream;
}
#include "sci/sci.h"
+#include "sci/engine/file.h"
#include "sci/engine/seg_manager.h"
#include "sci/parser/vocabulary.h"
@@ -42,9 +43,12 @@ class WriteStream;
namespace Sci {
+class FileHandle;
+class DirSeeker;
class EventManager;
class MessageState;
class SoundCommandParser;
+class VirtualIndexFile;
enum AbortGameState {
kAbortNone = 0,
@@ -53,32 +57,6 @@ enum AbortGameState {
kAbortQuitGame = 3
};
-class DirSeeker {
-protected:
- reg_t _outbuffer;
- Common::StringArray _files;
- Common::StringArray _virtualFiles;
- Common::StringArray::const_iterator _iter;
-
-public:
- DirSeeker() {
- _outbuffer = NULL_REG;
- _iter = _files.begin();
- }
-
- reg_t firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan);
- reg_t nextFile(SegManager *segMan);
-
- Common::String getVirtualFilename(uint fileNumber);
-
-private:
- void addAsVirtualFiles(Common::String title, Common::String fileMask);
-};
-
-enum {
- MAX_SAVEGAME_NR = 20 /**< Maximum number of savegames */
-};
-
// We assume that scripts give us savegameId 0->99 for creating a new save slot
// and savegameId 100->199 for existing save slots ffs. kfile.cpp
enum {
@@ -92,20 +70,6 @@ enum {
GAMEISRESTARTING_RESTORE = 2
};
-class FileHandle {
-public:
- Common::String _name;
- Common::SeekableReadStream *_in;
- Common::WriteStream *_out;
-
-public:
- FileHandle();
- ~FileHandle();
-
- void close();
- bool isOpen() const;
-};
-
enum VideoFlags {
kNone = 0,
kDoubled = 1 << 0,
@@ -163,6 +127,10 @@ public:
int16 _lastSaveVirtualId; // last virtual id fed to kSaveGame, if no kGetSaveFiles was called inbetween
int16 _lastSaveNewId; // last newly created filename-id by kSaveGame
+#ifdef ENABLE_SCI32
+ VirtualIndexFile *_virtualIndexFile;
+#endif
+
uint _chosenQfGImportItem; // Remembers the item selected in QfG import rooms
bool _cursorWorkaroundActive; // ffs. GfxCursor::setPosition()
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index c1d4a3d9f9..ecb1e4c2d5 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -167,6 +167,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_SQ6, -1, 0, 0, "SQ6", "init", -1, 2, { WORKAROUND_FAKE, 0 } }, // Demo and full version: called when the game starts (demo: room 0, full: room 100)
{ GID_SQ6, 100, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu
{ GID_SQ6, -1, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // during the game
+ { GID_TORIN, -1, 64017, 0, "oFlags", "clear", -1, 0, { WORKAROUND_FAKE, 0 } }, // entering Torin's home in the French version
SCI_WORKAROUNDENTRY_TERMINATOR
};
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index 378e88b7df..14443db1e2 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -102,8 +102,8 @@ const MouseEventConversion mouseEventMappings[] = {
{ Common::EVENT_RBUTTONDOWN, SCI_EVENT_MOUSE_PRESS, 2 },
{ Common::EVENT_MBUTTONDOWN, SCI_EVENT_MOUSE_PRESS, 3 },
{ Common::EVENT_LBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 1 },
- { Common::EVENT_LBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 2 },
- { Common::EVENT_LBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 3 }
+ { Common::EVENT_RBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 2 },
+ { Common::EVENT_MBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 3 }
};
EventManager::EventManager(bool fontIsExtended) : _fontIsExtended(fontIsExtended) {
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index 709a708d8b..db49497b6b 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -53,12 +53,20 @@ namespace Sci {
// TODO/FIXME: This is all guesswork
+enum SciSpeciaPlanelPictureCodes {
+ kPlaneTranslucent = 0xfffe, // -2
+ kPlanePlainColored = 0xffff // -1
+};
+
GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxCache *cache, GfxScreen *screen, GfxPalette *palette, GfxPaint32 *paint32)
: _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) {
_coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster;
_scriptsRunningWidth = 320;
_scriptsRunningHeight = 200;
+ _curScrollText = -1;
+ _showScrollText = false;
+ _maxScrollTexts = 0;
}
GfxFrameout::~GfxFrameout() {
@@ -69,6 +77,46 @@ void GfxFrameout::clear() {
deletePlaneItems(NULL_REG);
_planes.clear();
deletePlanePictures(NULL_REG);
+ clearScrollTexts();
+}
+
+void GfxFrameout::clearScrollTexts() {
+ _scrollTexts.clear();
+ _curScrollText = -1;
+}
+
+void GfxFrameout::addScrollTextEntry(Common::String &text, reg_t kWindow, uint16 x, uint16 y, bool replace) {
+ //reg_t bitmapHandle = g_sci->_gfxText32->createScrollTextBitmap(text, kWindow);
+ // HACK: We set the container dimensions manually
+ reg_t bitmapHandle = g_sci->_gfxText32->createScrollTextBitmap(text, kWindow, 480, 70);
+ ScrollTextEntry textEntry;
+ textEntry.bitmapHandle = bitmapHandle;
+ textEntry.kWindow = kWindow;
+ textEntry.x = x;
+ textEntry.y = y;
+ if (!replace || _scrollTexts.size() == 0) {
+ if (_scrollTexts.size() > _maxScrollTexts) {
+ _scrollTexts.remove_at(0);
+ _curScrollText--;
+ }
+ _scrollTexts.push_back(textEntry);
+ _curScrollText++;
+ } else {
+ _scrollTexts.pop_back();
+ _scrollTexts.push_back(textEntry);
+ }
+}
+
+void GfxFrameout::showCurrentScrollText() {
+ if (!_showScrollText || _curScrollText < 0)
+ return;
+
+ uint16 size = (uint16)_scrollTexts.size();
+ if (size > 0) {
+ assert(_curScrollText < size);
+ ScrollTextEntry textEntry = _scrollTexts[_curScrollText];
+ g_sci->_gfxText32->drawScrollTextBitmap(textEntry.kWindow, textEntry.bitmapHandle, textEntry.x, textEntry.y);
+ }
}
void GfxFrameout::kernelAddPlane(reg_t object) {
@@ -94,7 +142,7 @@ void GfxFrameout::kernelAddPlane(reg_t object) {
newPlane.lastPriority = 0xFFFF; // hidden
newPlane.planeOffsetX = 0;
newPlane.planeOffsetY = 0;
- newPlane.pictureId = 0xFFFF;
+ newPlane.pictureId = kPlanePlainColored;
newPlane.planePictureMirrored = false;
newPlane.planeBack = 0;
_planes.push_back(newPlane);
@@ -112,7 +160,8 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {
if (lastPictureId != it->pictureId) {
// picture got changed, load new picture
deletePlanePictures(object);
- if ((it->pictureId != 0xFFFF) && (it->pictureId != 0xFFFE)) {
+ // Draw the plane's picture if it's not a translucent/plane colored frame
+ if ((it->pictureId != kPlanePlainColored) && (it->pictureId != kPlaneTranslucent)) {
// SQ6 gives us a bad picture number for the control menu
if (_resMan->testResource(ResourceId(kResourceTypePic, it->pictureId)))
addPlanePicture(object, it->pictureId, 0);
@@ -205,6 +254,9 @@ void GfxFrameout::kernelDeletePlane(reg_t object) {
}
void GfxFrameout::addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX, uint16 startY) {
+ if (pictureId == kPlanePlainColored || pictureId == kPlaneTranslucent) // sanity check
+ return;
+
PlanePictureEntry newPicture;
newPicture.object = object;
newPicture.pictureId = pictureId;
@@ -229,6 +281,56 @@ void GfxFrameout::deletePlanePictures(reg_t object) {
}
}
+// Provides the same functionality as kGraph(DrawLine)
+reg_t GfxFrameout::addPlaneLine(reg_t object, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control) {
+ for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) {
+ if (it->object == object) {
+ PlaneLineEntry line;
+ line.hunkId = _segMan->allocateHunkEntry("PlaneLine()", 1); // we basically use this for a unique ID
+ line.startPoint = startPoint;
+ line.endPoint = endPoint;
+ line.color = color;
+ line.priority = priority;
+ line.control = control;
+ it->lines.push_back(line);
+ return line.hunkId;
+ }
+ }
+
+ return NULL_REG;
+}
+
+void GfxFrameout::updatePlaneLine(reg_t object, reg_t hunkId, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control) {
+ for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) {
+ if (it->object == object) {
+ for (PlaneLineList::iterator it2 = it->lines.begin(); it2 != it->lines.end(); ++it2) {
+ if (it2->hunkId == hunkId) {
+ it2->startPoint = startPoint;
+ it2->endPoint = endPoint;
+ it2->color = color;
+ it2->priority = priority;
+ it2->control = control;
+ return;
+ }
+ }
+ }
+ }
+}
+
+void GfxFrameout::deletePlaneLine(reg_t object, reg_t hunkId) {
+ for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) {
+ if (it->object == object) {
+ for (PlaneLineList::iterator it2 = it->lines.begin(); it2 != it->lines.end(); ++it2) {
+ if (it2->hunkId == hunkId) {
+ _segMan->freeHunkEntry(hunkId);
+ it2 = it->lines.erase(it2);
+ return;
+ }
+ }
+ }
+ }
+}
+
void GfxFrameout::kernelAddScreenItem(reg_t object) {
// Ignore invalid items
if (!_segMan->isObject(object))
@@ -515,6 +617,19 @@ void GfxFrameout::kernelFrameout() {
for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
reg_t planeObject = it->object;
+
+ // Draw any plane lines, if they exist
+ // These are drawn on invisible planes as well. (e.g. "invisiblePlane" in LSL6 hires)
+ // FIXME: Lines aren't always drawn (e.g. when the narrator speaks in LSL6 hires).
+ // Perhaps something is painted over them?
+ for (PlaneLineList::iterator it2 = it->lines.begin(); it2 != it->lines.end(); ++it2) {
+ Common::Point startPoint = it2->startPoint;
+ Common::Point endPoint = it2->endPoint;
+ _coordAdjuster->kernelLocalToGlobal(startPoint.x, startPoint.y, it->object);
+ _coordAdjuster->kernelLocalToGlobal(endPoint.x, endPoint.y, it->object);
+ _screen->drawLine(startPoint, endPoint, it2->color, it2->priority, it2->control);
+ }
+
uint16 planeLastPriority = it->lastPriority;
// Update priority here, sq6 sets it w/o UpdatePlane
@@ -531,21 +646,17 @@ void GfxFrameout::kernelFrameout() {
// There is a race condition lurking in SQ6, which causes the game to hang in the intro, when teleporting to Polysorbate LX.
// Since I first wrote the patch, the race has stopped occurring for me though.
// I'll leave this for investigation later, when someone can reproduce.
- //if (it->pictureId == 0xffff) // FIXME: This is what SSCI does, and fixes the intro of LSL7, but breaks the dialogs in GK1 (adds black boxes)
- if (it->planeBack)
+ //if (it->pictureId == kPlanePlainColored) // FIXME: This is what SSCI does, and fixes the intro of LSL7, but breaks the dialogs in GK1 (adds black boxes)
+ if (it->pictureId == kPlanePlainColored && it->planeBack)
_paint32->fillRect(it->planeRect, it->planeBack);
- GuiResourceId planeMainPictureId = it->pictureId;
-
_coordAdjuster->pictureSetDisplayArea(it->planeRect);
- _palette->drewPicture(planeMainPictureId);
+ _palette->drewPicture(it->pictureId);
FrameoutList itemList;
createPlaneItemList(planeObject, itemList);
-// warning("Plane %s", _segMan->getObjectName(planeObject));
-
for (FrameoutList::iterator listIterator = itemList.begin(); listIterator != itemList.end(); listIterator++) {
FrameoutEntry *itemEntry = *listIterator;
@@ -673,6 +784,8 @@ void GfxFrameout::kernelFrameout() {
}
}
+ showCurrentScrollText();
+
_screen->copyToScreen();
g_sci->getEngineState()->_throttleTrigger = true;
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index ec4de62c0a..0d80a68f1d 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -27,6 +27,17 @@ namespace Sci {
class GfxPicture;
+struct PlaneLineEntry {
+ reg_t hunkId;
+ Common::Point startPoint;
+ Common::Point endPoint;
+ byte color;
+ byte priority;
+ byte control;
+};
+
+typedef Common::List<PlaneLineEntry> PlaneLineList;
+
struct PlaneEntry {
reg_t object;
uint16 priority;
@@ -40,6 +51,7 @@ struct PlaneEntry {
Common::Rect upscaledPlaneClipRect;
bool planePictureMirrored;
byte planeBack;
+ PlaneLineList lines;
};
typedef Common::List<PlaneEntry> PlaneList;
@@ -76,6 +88,15 @@ struct PlanePictureEntry {
typedef Common::List<PlanePictureEntry> PlanePictureList;
+struct ScrollTextEntry {
+ reg_t bitmapHandle;
+ reg_t kWindow;
+ uint16 x;
+ uint16 y;
+};
+
+typedef Common::Array<ScrollTextEntry> ScrollTextList;
+
class GfxCache;
class GfxCoordAdjuster32;
class GfxPaint32;
@@ -103,7 +124,22 @@ public:
void addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX, uint16 startY = 0);
void deletePlanePictures(reg_t object);
+ reg_t addPlaneLine(reg_t object, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control);
+ void updatePlaneLine(reg_t object, reg_t hunkId, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control);
+ void deletePlaneLine(reg_t object, reg_t hunkId);
void clear();
+
+ // Scroll text functions
+ void addScrollTextEntry(Common::String &text, reg_t kWindow, uint16 x, uint16 y, bool replace);
+ void showCurrentScrollText();
+ void initScrollText(uint16 maxItems) { _maxScrollTexts = maxItems; }
+ void clearScrollTexts();
+ void firstScrollText() { if (_scrollTexts.size() > 0) _curScrollText = 0; }
+ void lastScrollText() { if (_scrollTexts.size() > 0) _curScrollText = _scrollTexts.size() - 1; }
+ void prevScrollText() { if (_curScrollText > 0) _curScrollText--; }
+ void nextScrollText() { if (_curScrollText + 1 < (uint16)_scrollTexts.size()) _curScrollText++; }
+ void toggleScrollText(bool show) { _showScrollText = show; }
+
void printPlaneList(Console *con);
void printPlaneItemList(Console *con, reg_t planeObject);
@@ -127,6 +163,10 @@ private:
FrameoutList _screenItems;
PlaneList _planes;
PlanePictureList _planePictures;
+ ScrollTextList _scrollTexts;
+ int16 _curScrollText;
+ bool _showScrollText;
+ uint16 _maxScrollTexts;
void sortPlanes();
diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp
index 47d1647c6c..ea154c5037 100644
--- a/engines/sci/graphics/palette.cpp
+++ b/engines/sci/graphics/palette.cpp
@@ -698,7 +698,7 @@ void GfxPalette::palVaryInit() {
}
bool GfxPalette::palVaryLoadTargetPalette(GuiResourceId resourceId) {
- _palVaryResourceId = resourceId;
+ _palVaryResourceId = (resourceId != 65535) ? resourceId : -1;
Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, resourceId), false);
if (palResource) {
// Load and initialize destination palette
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index cd24ca5a99..7907809c91 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -49,9 +49,12 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen)
GfxText32::~GfxText32() {
}
+reg_t GfxText32::createScrollTextBitmap(Common::String text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
+ return createTextBitmapInternal(text, textObject, maxWidth, maxHeight, prevHunk);
+
+}
reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text));
-
// The object in the text selector of the item can be either a raw string
// or a Str object. In the latter case, we need to access the object's data
// selector to get the raw string.
@@ -59,6 +62,11 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
stringObject = readSelector(_segMan, stringObject, SELECTOR(data));
Common::String text = _segMan->getString(stringObject);
+
+ return createTextBitmapInternal(text, textObject, maxWidth, maxHeight, prevHunk);
+}
+
+reg_t GfxText32::createTextBitmapInternal(Common::String &text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
// HACK: The character offsets of the up and down arrow buttons are off by one
// in GK1, for some unknown reason. Fix them here.
if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) {
@@ -91,7 +99,11 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
reg_t memoryId = NULL_REG;
if (prevHunk.isNull()) {
memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
- writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
+
+ // Scroll text objects have no bitmap selector!
+ ObjVarRef varp;
+ if (lookupSelector(_segMan, textObject, SELECTOR(bitmap), &varp, NULL) == kSelectorVariable)
+ writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
} else {
memoryId = prevHunk;
}
@@ -175,7 +187,25 @@ void GfxText32::disposeTextBitmap(reg_t hunkId) {
void GfxText32::drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t textObject) {
reg_t hunkId = readSelector(_segMan, textObject, SELECTOR(bitmap));
- uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));
+ drawTextBitmapInternal(x, y, planeRect, textObject, hunkId);
+}
+
+void GfxText32::drawScrollTextBitmap(reg_t textObject, reg_t hunkId, uint16 x, uint16 y) {
+ /*reg_t plane = readSelector(_segMan, textObject, SELECTOR(plane));
+ Common::Rect planeRect;
+ planeRect.top = readSelectorValue(_segMan, plane, SELECTOR(top));
+ planeRect.left = readSelectorValue(_segMan, plane, SELECTOR(left));
+ planeRect.bottom = readSelectorValue(_segMan, plane, SELECTOR(bottom));
+ planeRect.right = readSelectorValue(_segMan, plane, SELECTOR(right));
+
+ drawTextBitmapInternal(x, y, planeRect, textObject, hunkId);*/
+
+ // HACK: we pretty much ignore the plane rect and x, y...
+ drawTextBitmapInternal(0, 0, Common::Rect(20, 390, 600, 460), textObject, hunkId);
+}
+
+void GfxText32::drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, reg_t textObject, reg_t hunkId) {
+ int16 backColor = (int16)readSelectorValue(_segMan, textObject, SELECTOR(back));
// Sanity check: Check if the hunk is set. If not, either the game scripts
// didn't set it, or an old saved game has been loaded, where it wasn't set.
if (hunkId.isNull())
@@ -188,15 +218,16 @@ void GfxText32::drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t t
byte *memoryPtr = _segMan->getHunkPointer(hunkId);
if (!memoryPtr) {
- // Happens when restoring in some SCI32 games
- warning("Attempt to draw an invalid text bitmap");
+ // Happens when restoring in some SCI32 games (e.g. SQ6).
+ // Commented out to reduce console spam
+ //warning("Attempt to draw an invalid text bitmap");
return;
}
byte *surface = memoryPtr + BITMAP_HEADER_SIZE;
int curByte = 0;
- uint16 skipColor = readSelectorValue(_segMan, textObject, SELECTOR(skip));
+ int16 skipColor = (int16)readSelectorValue(_segMan, textObject, SELECTOR(skip));
uint16 textX = planeRect.left + x;
uint16 textY = planeRect.top + y;
// Get totalWidth, totalHeight
@@ -209,10 +240,13 @@ void GfxText32::drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t t
textY = textY * _screen->getDisplayHeight() / _screen->getHeight();
}
+ bool translucent = (skipColor == -1 && backColor == -1);
+
for (int curY = 0; curY < height; curY++) {
for (int curX = 0; curX < width; curX++) {
byte pixel = surface[curByte++];
- if (pixel != skipColor && pixel != backColor)
+ if ((!translucent && pixel != skipColor && pixel != backColor) ||
+ (translucent && pixel != 0xFF))
_screen->putFontPixel(textY, curX + textX, curY, pixel);
}
}
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index 3505de85eb..ce78003fdf 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -33,13 +33,17 @@ public:
GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen);
~GfxText32();
reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG);
- void disposeTextBitmap(reg_t hunkId);
+ reg_t createScrollTextBitmap(Common::String text, reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG);
void drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t textObject);
+ void drawScrollTextBitmap(reg_t textObject, reg_t hunkId, uint16 x, uint16 y);
+ void disposeTextBitmap(reg_t hunkId);
int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font);
void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
private:
+ reg_t createTextBitmapInternal(Common::String &text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t hunkId);
+ void drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, reg_t textObject, reg_t hunkId);
int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth);
void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont);
void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index b6d5837b31..6b6058c819 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS := \
sci.o \
util.o \
engine/features.o \
+ engine/file.o \
engine/gc.o \
engine/kernel.o \
engine/kevent.o \
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 42f11498d9..88681898f5 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -121,13 +121,13 @@ void ScummEngine::updateCursor() {
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
_cursor.hotspotX, _cursor.hotspotY,
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
- (_game.heversion == 70 ? 2 : 1),
+ (_game.heversion == 70 ? true : false),
&format);
#else
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
_cursor.hotspotX, _cursor.hotspotY,
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
- (_game.heversion == 70 ? 2 : 1));
+ (_game.heversion == 70 ? true : false));
#endif
}
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 95de1a8706..ebf1a2675c 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -1135,6 +1135,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co
case 200:
*engine = new ScummEngine_vCUPhe(syst, res);
break;
+ case 101:
case 100:
*engine = new ScummEngine_v100he(syst, res);
break;
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 452a6f0960..be1b90e356 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -382,14 +382,16 @@ static const GameSettings gameVariantsTable[] = {
{"pjgames", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added the use of bink videos
- {"Baseball2003", 0, 0, GID_BASEBALL2003, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"football2002", 0, 0, GID_FOOTBALL, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// U32 code required, for testing only
{"moonbase", 0, 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"moonbase", "Demo", 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR | GF_DEMO, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+
+ // HE100 games, which use older o72_debugInput code
+ {"Baseball2003", 0, 0, GID_BASEBALL2003, 6, 101, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"basketball", 0, 0, GID_BASKETBALL, 6, 101, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"football2002", 0, 0, GID_FOOTBALL2002, 6, 101, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
#endif
// The following are meant to be generic HE game variants and as such do
@@ -407,6 +409,7 @@ static const GameSettings gameVariantsTable[] = {
{"", "HE 98.5", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"", "HE 99", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
{"", "HE 100", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"", "HE 101", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
#endif
{NULL, NULL, 0, 0, 0, MDT_NONE, 0, 0, UNK, 0}
};
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index cdc5faa084..fc5e4bcdf0 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -187,6 +187,8 @@ public:
Wiz *_wiz;
+ virtual int setupStringArray(int size);
+
protected:
virtual void setupOpcodes();
@@ -201,7 +203,6 @@ protected:
virtual void clearDrawQueues();
int getStringCharWidth(byte chr);
- virtual int setupStringArray(int size);
void appendSubstring(int dst, int src, int len2, int len);
void adjustRect(Common::Rect &rect);
@@ -258,6 +259,9 @@ public:
virtual void resetScumm();
+ virtual byte *getStringAddress(ResId idx);
+ virtual int setupStringArray(int size);
+
protected:
virtual void setupOpcodes();
@@ -265,7 +269,6 @@ protected:
virtual void resetScummVars();
virtual void readArrayFromIndexFile();
- virtual byte *getStringAddress(ResId idx);
virtual void readMAXS(int blockSize);
virtual void redrawBGAreas();
@@ -280,7 +283,6 @@ protected:
void copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end,
int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end);
void copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num);
- virtual int setupStringArray(int size);
int readFileToArray(int slot, int32 size);
void writeFileFromArray(int slot, int32 resID);
diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp
index 5a0d423508..f67e07c475 100644
--- a/engines/scumm/he/logic/football.cpp
+++ b/engines/scumm/he/logic/football.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "common/savefile.h"
+
#include "scumm/he/intern_he.h"
#include "scumm/he/logic_he.h"
@@ -35,17 +37,16 @@ public:
LogicHEfootball(ScummEngine_v90he *vm) : LogicHE(vm) {}
int versionID();
- int32 dispatch(int op, int numArgs, int32 *args);
-
-private:
- int op_1004(int32 *args);
- int op_1006(int32 *args);
- int op_1007(int32 *args);
- int op_1010(int32 *args);
- int op_1022(int32 *args);
- int op_1023(int32 *args);
- int op_1024(int32 *args);
- int op_1028();
+ virtual int32 dispatch(int op, int numArgs, int32 *args);
+
+protected:
+ int lineEquation3D(int32 *args);
+ virtual int translateWorldToScreen(int32 *args);
+ int fieldGoalScreenTranslation(int32 *args);
+ virtual int translateScreenToWorld(int32 *args);
+ int nextPoint(int32 *args);
+ int computePlayerBallIntercepts(int32 *args);
+ int computeTwoCircleIntercepts(int32 *args);
};
int LogicHEfootball::versionID() {
@@ -57,36 +58,31 @@ int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) {
switch (op) {
case 1004:
- res = op_1004(args);
+ res = lineEquation3D(args);
break;
case 1006:
- res = op_1006(args);
+ res = translateWorldToScreen(args);
break;
case 1007:
- res = op_1007(args);
+ res = fieldGoalScreenTranslation(args);
break;
case 1010:
- res = op_1010(args);
+ res = translateScreenToWorld(args);
break;
case 1022:
- res = op_1022(args);
+ res = nextPoint(args);
break;
case 1023:
- res = op_1023(args);
+ res = computePlayerBallIntercepts(args);
break;
case 1024:
- res = op_1024(args);
- break;
-
- case 1028:
- // Backyard Football 2002 only
- res = op_1028();
+ res = computeTwoCircleIntercepts(args);
break;
case 8221968:
@@ -129,8 +125,8 @@ int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) {
return res;
}
-int LogicHEfootball::op_1004(int32 *args) {
- // Identical to LogicHEsoccer::op_1004
+int LogicHEfootball::lineEquation3D(int32 *args) {
+ // Identical to soccer's 1004 opcode
double res, a2, a4, a5;
a5 = ((double)args[4] - (double)args[1]) / ((double)args[5] - (double)args[2]);
@@ -147,8 +143,8 @@ int LogicHEfootball::op_1004(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1006(int32 *args) {
- // This seems to be more or less the inverse of op_1010
+int LogicHEfootball::translateWorldToScreen(int32 *args) {
+ // This is more or less the inverse of translateScreenToWorld
const double a1 = args[1];
double res;
@@ -173,7 +169,7 @@ int LogicHEfootball::op_1006(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1007(int32 *args) {
+int LogicHEfootball::fieldGoalScreenTranslation(int32 *args) {
double res, temp;
temp = (double)args[1] * 0.32;
@@ -194,8 +190,8 @@ int LogicHEfootball::op_1007(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1010(int32 *args) {
- // This seems to be more or less the inverse of op_1006
+int LogicHEfootball::translateScreenToWorld(int32 *args) {
+ // This is more or less the inverse of translateWorldToScreen
double a1 = (640.0 - (double)args[1] - 26.0) / 1.1588235e-1;
// 2.9411764e-4 = 1/3400
@@ -211,7 +207,7 @@ int LogicHEfootball::op_1010(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1022(int32 *args) {
+int LogicHEfootball::nextPoint(int32 *args) {
double res;
double var10 = args[4] - args[1];
double var8 = args[5] - args[2];
@@ -232,7 +228,7 @@ int LogicHEfootball::op_1022(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1023(int32 *args) {
+int LogicHEfootball::computePlayerBallIntercepts(int32 *args) {
double var10, var18, var20, var28, var30, var30_;
double argf[7];
@@ -278,7 +274,8 @@ int LogicHEfootball::op_1023(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1024(int32 *args) {
+int LogicHEfootball::computeTwoCircleIntercepts(int32 *args) {
+ // Looks like this was just dummied out
writeScummVar(108, 0);
writeScummVar(109, 0);
writeScummVar(110, 0);
@@ -287,8 +284,110 @@ int LogicHEfootball::op_1024(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1028() {
- // Backyard Football 2002 only
+class LogicHEfootball2002 : public LogicHEfootball {
+public:
+ LogicHEfootball2002(ScummEngine_v90he *vm) : LogicHEfootball(vm) {}
+
+ int32 dispatch(int op, int numArgs, int32 *args);
+
+private:
+ int translateWorldToScreen(int32 *args);
+ int translateScreenToWorld(int32 *args);
+ int getDayOfWeek();
+ int initScreenTranslations();
+ int getPlaybookFiles(int32 *args);
+ int largestFreeBlock();
+};
+
+int32 LogicHEfootball2002::dispatch(int op, int numArgs, int32 *args) {
+ int32 res = 0;
+
+ switch (op) {
+ case 1025:
+ res = getDayOfWeek();
+ break;
+
+ case 1026:
+ res = initScreenTranslations();
+ break;
+
+ case 1027:
+ res = getPlaybookFiles(args);
+ break;
+
+ case 1028:
+ res = largestFreeBlock();
+ break;
+
+ case 1029:
+ // Clean-up off heap
+ // Dummied in the Windows U32
+ res = 1;
+ break;
+
+ case 1516:
+ // Start auto LAN game
+ break;
+
+ default:
+ res = LogicHEfootball::dispatch(op, numArgs, args);
+ break;
+ }
+
+ return res;
+}
+
+int LogicHEfootball2002::translateWorldToScreen(int32 *args) {
+ // TODO: Implement modified 2002 version
+ return LogicHEfootball::translateWorldToScreen(args);
+}
+
+int LogicHEfootball2002::translateScreenToWorld(int32 *args) {
+ // TODO: Implement modified 2002 version
+ return LogicHEfootball::translateScreenToWorld(args);
+}
+
+int LogicHEfootball2002::getDayOfWeek() {
+ // TODO: Get day of week, store in var 108
+ return 1;
+}
+
+int LogicHEfootball2002::initScreenTranslations() {
+ // TODO: Set values used by translateWorldToScreen/translateScreenToWorld
+ return 1;
+}
+
+int LogicHEfootball2002::getPlaybookFiles(int32 *args) {
+ // Get the pattern and then skip over the directory prefix ("*\" or "*:")
+ Common::String pattern = (const char *)_vm->getStringAddress(args[0] & ~0x33539000) + 2;
+
+ // Prepare a buffer to hold the file names
+ char buffer[1000];
+ buffer[0] = 0;
+
+ // Get the list of file names that match the pattern and iterate over it
+ Common::StringArray fileList = _vm->getSaveFileManager()->listSavefiles(pattern);
+
+ for (uint32 i = 0; i < fileList.size() && strlen(buffer) < 970; i++) {
+ // Isolate the base part of the filename and concatenate it to our buffer
+ Common::String fileName = Common::String(fileList[i].c_str(), fileList[i].size() - (pattern.size() - 1));
+ strcat(buffer, fileName.c_str());
+ strcat(buffer, ">"); // names separated by '>'
+ }
+
+ // Now store the result in an array
+ int array = _vm->setupStringArray(strlen(buffer));
+ strcpy((char *)_vm->getStringAddress(array), buffer);
+
+ // And store the array index in variable 108
+ writeScummVar(108, array);
+
+ return 1;
+}
+
+int LogicHEfootball2002::largestFreeBlock() {
+ // The Windows version always sets the variable to this
+ // The Mac version actually checks for the largest free block
writeScummVar(108, 100000000);
return 1;
}
@@ -297,4 +396,8 @@ LogicHE *makeLogicHEfootball(ScummEngine_v90he *vm) {
return new LogicHEfootball(vm);
}
+LogicHE *makeLogicHEfootball2002(ScummEngine_v90he *vm) {
+ return new LogicHEfootball2002(vm);
+}
+
} // End of namespace Scumm
diff --git a/engines/scumm/he/logic_he.cpp b/engines/scumm/he/logic_he.cpp
index a76c393e13..0f9454ba28 100644
--- a/engines/scumm/he/logic_he.cpp
+++ b/engines/scumm/he/logic_he.cpp
@@ -87,6 +87,9 @@ LogicHE *LogicHE::makeLogicHE(ScummEngine_v90he *vm) {
case GID_FOOTBALL:
return makeLogicHEfootball(vm);
+ case GID_FOOTBALL2002:
+ return makeLogicHEfootball2002(vm);
+
case GID_SOCCER:
case GID_SOCCERMLS:
case GID_SOCCER2004:
diff --git a/engines/scumm/he/logic_he.h b/engines/scumm/he/logic_he.h
index 893dc81b87..93c0569a4f 100644
--- a/engines/scumm/he/logic_he.h
+++ b/engines/scumm/he/logic_he.h
@@ -61,6 +61,7 @@ protected:
LogicHE *makeLogicHErace(ScummEngine_v90he *vm);
LogicHE *makeLogicHEfunshop(ScummEngine_v90he *vm);
LogicHE *makeLogicHEfootball(ScummEngine_v90he *vm);
+LogicHE *makeLogicHEfootball2002(ScummEngine_v90he *vm);
LogicHE *makeLogicHEsoccer(ScummEngine_v90he *vm);
LogicHE *makeLogicHEbaseball2001(ScummEngine_v90he *vm);
LogicHE *makeLogicHEbasketball(ScummEngine_v90he *vm);
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index d2e01a6564..3e2053790e 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -2339,8 +2339,9 @@ void ScummEngine_v100he::o100_writeFile() {
}
void ScummEngine_v100he::o100_debugInput() {
- // Backyard Basketball uses older code for this opcode
- if (_game.id == GID_BASKETBALL) {
+ // Backyard Baseball 2003 / Basketball / Football 2002
+ // use older o72_debugInput code
+ if (_game.heversion == 101) {
ScummEngine_v72he::o72_debugInput();
return;
}
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index dbeee567bf..5e359385b6 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -124,8 +124,6 @@ int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) {
} else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
// The default game data path is set to './' by ScummVM
r = 2;
- } else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI
- r = 13;
} else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (Windows HE72 - HE100)
// The default save game path is set to '*/' by ScummVM
r = 2;
diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp
index 1007d2a7b0..f94b74ac45 100644
--- a/engines/scumm/he/sound_he.cpp
+++ b/engines/scumm/he/sound_he.cpp
@@ -65,7 +65,7 @@ void SoundHE::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlag
if (_vm->VAR_LAST_SOUND != 0xFF)
_vm->VAR(_vm->VAR_LAST_SOUND) = sound;
- if ((_vm->_game.heversion <= 99 && (heFlags & 16)) || (_vm->_game.heversion == 100 && (heFlags & 8))) {
+ if ((_vm->_game.heversion <= 99 && (heFlags & 16)) || (_vm->_game.heversion >= 100 && (heFlags & 8))) {
playHESound(sound, heOffset, heChannel, heFlags);
return;
} else {
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 8c0070b5f5..c8cf096a19 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -241,6 +241,7 @@ enum ScummGameId {
GID_PUTTRACE,
GID_FUNSHOP, // Used for all three funshops
GID_FOOTBALL,
+ GID_FOOTBALL2002,
GID_SOCCER,
GID_SOCCERMLS,
GID_SOCCER2004,
diff --git a/engines/sword25/gfx/image/art.cpp b/engines/sword25/gfx/image/art.cpp
index 3944a207c8..9c4b9fe8bd 100644
--- a/engines/sword25/gfx/image/art.cpp
+++ b/engines/sword25/gfx/image/art.cpp
@@ -2367,38 +2367,30 @@ ArtSVPRenderAAIter *art_svp_render_aa_iter(const ArtSVP *svp,
return iter;
}
-#define ADD_STEP(xpos, xdelta) \
+#define ADD_STEP(xpos, xdelta) \
/* stereotype code fragment for adding a step */ \
- if (n_steps == 0 || steps[n_steps - 1].x < xpos) \
- { \
+ if (n_steps == 0 || steps[n_steps - 1].x < xpos) { \
sx = n_steps; \
steps[sx].x = xpos; \
steps[sx].delta = xdelta; \
n_steps++; \
- } \
- else \
- { \
- for (sx = n_steps; sx > 0; sx--) \
- { \
- if (steps[sx - 1].x == xpos) \
- { \
+ } else { \
+ for (sx = n_steps; sx > 0; sx--) { \
+ if (steps[sx - 1].x == xpos) { \
steps[sx - 1].delta += xdelta; \
sx = n_steps; \
break; \
- } \
- else if (steps[sx - 1].x < xpos) \
- { \
+ } else if (steps[sx - 1].x < xpos) { \
break; \
- } \
- } \
- if (sx < n_steps) \
- { \
+ } \
+ } \
+ if (sx < n_steps) { \
memmove (&steps[sx + 1], &steps[sx], \
(n_steps - sx) * sizeof(steps[0])); \
steps[sx].x = xpos; \
steps[sx].delta = xdelta; \
n_steps++; \
- } \
+ } \
}
void art_svp_render_aa_iter_step(ArtSVPRenderAAIter *iter, int *p_start,
diff --git a/engines/sword25/gfx/image/art.h b/engines/sword25/gfx/image/art.h
index 8c9c97bc57..40bcb55aa7 100644
--- a/engines/sword25/gfx/image/art.h
+++ b/engines/sword25/gfx/image/art.h
@@ -50,7 +50,7 @@ namespace Sword25 {
be variables. They can also be pstruct->el lvalues. */
#define art_expand(p, type, max) \
do { \
- if(max) {\
+ if (max) {\
type *tmp = art_renew(p, type, max <<= 1); \
if (!tmp) error("Cannot reallocate memory for art data"); \
p = tmp; \
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 59344c44f4..bac7ef6efb 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -53,7 +53,6 @@ class Config;
class MidiDriver;
class MidiMusicPlayer;
class PCMMusicPlayer;
-class Scheduler;
class SoundManager;
typedef Common::List<Common::Rect> RectList;
@@ -154,7 +153,6 @@ class TinselEngine : public Engine {
Common::Point _mousePos;
uint8 _dosPlayerDir;
Console *_console;
- Scheduler *_scheduler;
static const char *const _sampleIndices[][3];
static const char *const _sampleFiles[][3];
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index dd3c32b5bf..416daa1fe8 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -2955,15 +2955,12 @@ Common::String ToonEngine::getSavegameName(int nr) {
}
bool ToonEngine::saveGame(int32 slot, const Common::String &saveGameDesc) {
- const EnginePlugin *plugin = NULL;
int16 savegameId;
Common::String savegameDescription;
- EngineMan.findGame(_gameDescription->gameid, &plugin);
if (slot == -1) {
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save");
- dialog->setSaveMode(true);
- savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true);
+ savegameId = dialog->runModalWithCurrentTarget();
savegameDescription = dialog->getResultString();
delete dialog;
} else {
@@ -3051,14 +3048,11 @@ bool ToonEngine::saveGame(int32 slot, const Common::String &saveGameDesc) {
}
bool ToonEngine::loadGame(int32 slot) {
- const EnginePlugin *plugin = NULL;
int16 savegameId;
- EngineMan.findGame(_gameDescription->gameid, &plugin);
if (slot == -1) {
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore");
- dialog->setSaveMode(false);
- savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false);
+ savegameId = dialog->runModalWithCurrentTarget();
delete dialog;
} else {
savegameId = slot;
diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp
index 0756d71d4c..774a5277dc 100644
--- a/engines/tsage/scenes.cpp
+++ b/engines/tsage/scenes.cpp
@@ -569,17 +569,13 @@ void Game::quitGame() {
}
void Game::handleSaveLoad(bool saveFlag, int &saveSlot, Common::String &saveName) {
- const EnginePlugin *plugin = 0;
- EngineMan.findGame(g_vm->getGameId(), &plugin);
GUI::SaveLoadChooser *dialog;
if (saveFlag)
- dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"));
+ dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), saveFlag);
else
- dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"));
+ dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), saveFlag);
- dialog->setSaveMode(saveFlag);
-
- saveSlot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+ saveSlot = dialog->runModalWithCurrentTarget();
saveName = dialog->getResultString();
delete dialog;
diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
index 425714ea34..825b5c2e19 100644
--- a/graphics/cursorman.cpp
+++ b/graphics/cursorman.cpp
@@ -55,14 +55,14 @@ bool CursorManager::showMouse(bool visible) {
return g_system->showMouse(visible);
}
-void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) {
- Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
+void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
+ Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
cur->_visible = isVisible();
_cursorStack.push(cur);
if (buf) {
- g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
+ g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
}
}
@@ -75,7 +75,7 @@ void CursorManager::popCursor() {
if (!_cursorStack.empty()) {
cur = _cursorStack.top();
- g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale, &cur->_format);
+ g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_dontScale, &cur->_format);
}
g_system->showMouse(isVisible());
@@ -98,10 +98,10 @@ void CursorManager::popAllCursors() {
g_system->showMouse(isVisible());
}
-void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) {
+void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
if (_cursorStack.empty()) {
- pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
+ pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
return;
}
@@ -131,7 +131,7 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX,
cur->_hotspotX = hotspotX;
cur->_hotspotY = hotspotY;
cur->_keycolor = keycolor;
- cur->_targetScale = targetScale;
+ cur->_dontScale = dontScale;
#ifdef USE_RGB_COLOR
if (format)
cur->_format = *format;
@@ -139,7 +139,7 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX,
cur->_format = Graphics::PixelFormat::createFormatCLUT8();
#endif
- g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format);
+ g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
}
bool CursorManager::supportsCursorPalettes() {
@@ -225,7 +225,7 @@ void CursorManager::replaceCursorPalette(const byte *colors, uint start, uint nu
}
}
-CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) {
+CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
#ifdef USE_RGB_COLOR
if (!format)
_format = Graphics::PixelFormat::createFormatCLUT8();
@@ -245,7 +245,7 @@ CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, in
_height = h;
_hotspotX = hotspotX;
_hotspotY = hotspotY;
- _targetScale = targetScale;
+ _dontScale = dontScale;
}
CursorManager::Cursor::~Cursor() {
diff --git a/graphics/cursorman.h b/graphics/cursorman.h
index 543a5d0a5c..852109d7e6 100644
--- a/graphics/cursorman.h
+++ b/graphics/cursorman.h
@@ -63,14 +63,15 @@ public:
* @param hotspotY the hotspot Y coordinate
* @param keycolor the color value for the transparent color. This may not exceed
* the maximum color value as defined by format.
- * @param targetScale the scale for which the cursor is designed
+ * @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor
+ * would be too small to notice otherwise, these are allowed to scale the cursor anyway.
* @param format a pointer to the pixel format which the cursor graphic uses,
* CLUT8 will be used if this is NULL or not specified.
* @note It is ok for the buffer to be a NULL pointer. It is sometimes
* useful to push a "dummy" cursor and modify it later. The
* cursor will be added to the stack, but not to the backend.
*/
- void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL);
+ void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
/**
* Pop a cursor from the stack, and restore the previous one to the
@@ -90,11 +91,12 @@ public:
* @param hotspotY the hotspot Y coordinate
* @param keycolor the color value for the transparent color. This may not exceed
* the maximum color value as defined by format.
- * @param targetScale the scale for which the cursor is designed
+ * @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor
+ * would be too small to notice otherwise, these are allowed to scale the cursor anyway.
* @param format a pointer to the pixel format which the cursor graphic uses,
* CLUT8 will be used if this is NULL or not specified.
*/
- void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL);
+ void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
/**
* Pop all of the cursors and cursor palettes from their respective stacks.
@@ -175,11 +177,11 @@ private:
int _hotspotY;
uint32 _keycolor;
Graphics::PixelFormat _format;
- int _targetScale;
+ bool _dontScale;
uint _size;
- Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL);
+ Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
~Cursor();
};
diff --git a/graphics/scaler.cpp b/graphics/scaler.cpp
index 9ade0e6c57..b81e8937a8 100644
--- a/graphics/scaler.cpp
+++ b/graphics/scaler.cpp
@@ -167,12 +167,12 @@ void DestroyScalers(){
void Normal1x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
int width, int height) {
// Spot the case when it can all be done in 1 hit
- if ((srcPitch == sizeof(OverlayColor) * (uint)width) && (dstPitch == sizeof(OverlayColor) * (uint)width)) {
- memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width * height);
+ if ((srcPitch == sizeof(uint16) * (uint)width) && (dstPitch == sizeof(uint16) * (uint)width)) {
+ memcpy(dstPtr, srcPtr, sizeof(uint16) * width * height);
return;
}
while (height--) {
- memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width);
+ memcpy(dstPtr, srcPtr, sizeof(uint16) * width);
srcPtr += srcPitch;
dstPtr += dstPitch;
}
@@ -207,11 +207,10 @@ void Normal2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPit
uint8 *r;
assert(IS_ALIGNED(dstPtr, 4));
- assert(sizeof(OverlayColor) == 2);
while (height--) {
r = dstPtr;
for (int i = 0; i < width; ++i, r += 4) {
- uint32 color = *(((const OverlayColor *)srcPtr) + i);
+ uint32 color = *(((const uint16 *)srcPtr) + i);
color |= color << 16;
diff --git a/graphics/scaler/aspect.cpp b/graphics/scaler/aspect.cpp
index 7ad37b1ba8..f0ae732a40 100644
--- a/graphics/scaler/aspect.cpp
+++ b/graphics/scaler/aspect.cpp
@@ -160,14 +160,14 @@ int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, i
#if ASPECT_MODE == kSuperFastAndUglyAspectMode
if (srcPtr == dstPtr)
break;
- memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width);
+ memcpy(dstPtr, srcPtr, sizeof(uint16) * width);
#else
// Bilinear filter
switch (y % 6) {
case 0:
case 5:
if (srcPtr != dstPtr)
- memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width);
+ memcpy(dstPtr, srcPtr, sizeof(uint16) * width);
break;
case 1:
interpolate5Line<ColorMask, 1>((uint16 *)dstPtr, (const uint16 *)(srcPtr - pitch), (const uint16 *)srcPtr, width);
@@ -206,13 +206,13 @@ void Normal1xAspectTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr,
#if ASPECT_MODE == kSuperFastAndUglyAspectMode
if ((y % 6) == 5)
srcPtr -= srcPitch;
- memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width);
+ memcpy(dstPtr, srcPtr, sizeof(uint16) * width);
#else
// Bilinear filter five input lines onto six output lines
switch (y % 6) {
case 0:
// First output line is copied from first input line
- memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width);
+ memcpy(dstPtr, srcPtr, sizeof(uint16) * width);
break;
case 1:
// Second output line is mixed from first and second input line
@@ -233,7 +233,7 @@ void Normal1xAspectTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr,
case 5:
// Sixth (and last) output line is copied from fifth (and last) input line
srcPtr -= srcPitch;
- memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width);
+ memcpy(dstPtr, srcPtr, sizeof(uint16) * width);
break;
}
#endif
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index be0a5db601..1bf7ad3c85 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -454,7 +454,7 @@ void ThemeEngine::refresh() {
if (_useCursor) {
CursorMan.replaceCursorPalette(_cursorPal, 0, _cursorPalSize);
- CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
+ CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true);
}
}
}
@@ -465,7 +465,7 @@ void ThemeEngine::enable() {
if (_useCursor) {
CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize);
- CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
+ CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true);
CursorMan.showMouse(true);
}
@@ -1287,7 +1287,7 @@ void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) {
_vectorRenderer->setSurface(&_screen);
}
-bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale) {
+bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY) {
if (!_system->hasFeature(OSystem::kFeatureCursorPalette))
return true;
@@ -1305,7 +1305,6 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
// Set up the cursor parameters
_cursorHotspotX = hotspotX;
_cursorHotspotY = hotspotY;
- _cursorTargetScale = scale;
_cursorWidth = cursor->w;
_cursorHeight = cursor->h;
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index acded085f5..21711e2955 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -35,7 +35,7 @@
#include "graphics/pixelformat.h"
-#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.12"
+#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.13"
class OSystem;
@@ -276,6 +276,11 @@ public:
void disable();
/**
+ * Query the set up pixel format.
+ */
+ const Graphics::PixelFormat getPixelFormat() const { return _overlayFormat; }
+
+ /**
* Implementation of the GUI::Theme API. Called when a
* new dialog is opened. Note that the boolean parameter
* meaning has been changed.
@@ -495,9 +500,8 @@ public:
* @param filename File name of the bitmap to load.
* @param hotspotX X Coordinate of the bitmap which does the cursor click.
* @param hotspotY Y Coordinate of the bitmap which does the cursor click.
- * @param scale Scale at which the bitmap is supposed to be used.
*/
- bool createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale);
+ bool createCursor(const Common::String &filename, int hotspotX, int hotspotY);
/**
* Wrapper for restoring data from the Back Buffer to the screen.
@@ -669,7 +673,6 @@ protected:
bool _useCursor;
int _cursorHotspotX, _cursorHotspotY;
- int _cursorTargetScale;
enum {
MAX_CURS_COLORS = 255
};
diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp
index 9ccdedd564..9a85399ed1 100644
--- a/gui/ThemeParser.cpp
+++ b/gui/ThemeParser.cpp
@@ -218,15 +218,12 @@ bool ThemeParser::parserCallback_cursor(ParserNode *node) {
return true;
}
- int spotx, spoty, scale;
+ int spotx, spoty;
if (!parseIntegerKey(node->values["hotspot"], 2, &spotx, &spoty))
return parserError("Error parsing cursor Hot Spot coordinates.");
- if (!parseIntegerKey(node->values["scale"], 1, &scale))
- return parserError("Error parsing cursor scale.");
-
- if (!_theme->createCursor(node->values["file"], spotx, spoty, scale))
+ if (!_theme->createCursor(node->values["file"], spotx, spoty))
return parserError("Error creating Bitmap Cursor.");
return true;
diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h
index 4b7e88cbf3..82f774b803 100644
--- a/gui/ThemeParser.h
+++ b/gui/ThemeParser.h
@@ -85,7 +85,6 @@ protected:
XML_KEY(cursor)
XML_PROP(file, true)
XML_PROP(hotspot, true)
- XML_PROP(scale, true)
XML_PROP(resolution, false)
KEY_END()
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index c8ed3126c4..26fafa5279 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -677,7 +677,7 @@ LauncherDialog::LauncherDialog()
_browser = new BrowserDialog(_("Select directory with game data"), true);
// Create Load dialog
- _loadDialog = new SaveLoadChooser(_("Load game:"), _("Load"));
+ _loadDialog = new SaveLoadChooser(_("Load game:"), _("Load"), false);
}
void LauncherDialog::selectTarget(const String &target) {
diff --git a/gui/saveload.cpp b/gui/saveload.cpp
index 3dc9961906..67d871e133 100644
--- a/gui/saveload.cpp
+++ b/gui/saveload.cpp
@@ -21,6 +21,7 @@
#include "common/config-manager.h"
#include "common/translation.h"
+#include "common/system.h"
#include "gui/widgets/list.h"
#include "gui/message.h"
@@ -40,7 +41,7 @@ enum {
};
-SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
+SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode)
: Dialog("SaveLoadChooser"), _delSupport(0), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) {
_delSupport = _metaInfoSupport = _thumbnailSupport = _saveDateSupport = _playTimeSupport = false;
@@ -51,7 +52,7 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
// Add choice list
_list = new GUI::ListWidget(this, "SaveLoadChooser.List");
_list->setNumberingMode(GUI::kListNumberingZero);
- setSaveMode(false);
+ _list->setEditable(saveMode);
_gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10);
@@ -76,6 +77,15 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
SaveLoadChooser::~SaveLoadChooser() {
}
+int SaveLoadChooser::runModalWithCurrentTarget() {
+ const Common::String gameId = ConfMan.get("gameid");
+
+ const EnginePlugin *plugin = 0;
+ EngineMan.findGame(gameId, &plugin);
+
+ return runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+}
+
int SaveLoadChooser::runModalWithPluginAndTarget(const EnginePlugin *plugin, const String &target) {
if (_gfxWidget)
_gfxWidget->setGfx(0);
@@ -117,8 +127,16 @@ const Common::String &SaveLoadChooser::getResultString() const {
return (selItem >= 0) ? _list->getSelectedString() : _resultString;
}
-void SaveLoadChooser::setSaveMode(bool saveMode) {
- _list->setEditable(saveMode);
+Common::String SaveLoadChooser::createDefaultSaveDescription(const int slot) const {
+#if defined(USE_SAVEGAME_TIMESTAMP)
+ TimeDate curTime;
+ g_system->getTimeAndDate(curTime);
+ curTime.tm_year += 1900; // fixup year
+ curTime.tm_mon++; // fixup month
+ return Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec);
+#else
+ return Common::String::format("Save %d", slot + 1);
+#endif
}
void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
diff --git a/gui/saveload.h b/gui/saveload.h
index adaf311fd2..a19f5ab083 100644
--- a/gui/saveload.h
+++ b/gui/saveload.h
@@ -62,16 +62,37 @@ protected:
void updateSaveList();
void updateSelection(bool redraw);
public:
- SaveLoadChooser(const String &title, const String &buttonLabel);
+ SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode);
~SaveLoadChooser();
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
- void setList(const StringArray& list);
+
+ /**
+ * Runs the save/load chooser with the currently active config manager
+ * domain as target.
+ *
+ * @return The selcted save slot. -1 in case none is selected.
+ */
+ int runModalWithCurrentTarget();
int runModalWithPluginAndTarget(const EnginePlugin *plugin, const String &target);
void open();
const Common::String &getResultString() const;
- void setSaveMode(bool saveMode);
+
+ /**
+ * Creates a default save description for the specified slot. Depending
+ * on the ScummVM configuration this might be a simple "Slot #" description
+ * or the current date and time.
+ *
+ * TODO: This might not be the best place to put this, since engines not
+ * using this class might want to mimic the same behavior. Check whether
+ * moving this to a better place makes sense and find what this place would
+ * be.
+ *
+ * @param slot The slot number (must be >= 0).
+ * @return The slot description.
+ */
+ Common::String createDefaultSaveDescription(const int slot) const;
virtual void reflowLayout();
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 5ee9b9202a..86d0061e1b 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -610,50 +610,48 @@
"/> "
"</drawdata> "
"</render_info> "
-"<layout_info resolution='y>399'> "
+"<layout_info resolution='y<400'> "
"<globals> "
-"<def var='Line.Height' value='16' /> "
-"<def var='Font.Height' value='16' /> "
-"<def var='About.OuterBorder' value='80'/> "
-"<def var='Layout.Spacing' value='8' /> "
+"<def var='Line.Height' value='12' /> "
+"<def var='Font.Height' value='10' /> "
+"<def var='About.OuterBorder' value='10'/> "
+"<def var='Layout.Spacing' value='8'/> "
"<def var='ShowLauncherLogo' value='0'/> "
"<def var='ShowGlobalMenuLogo' value='0'/> "
"<def var='ShowSearchPic' value='0'/> "
-"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> "
-"<def var='KeyMapper.Spacing' value='10'/> "
-"<def var='KeyMapper.LabelWidth' value='100'/> "
-"<def var='KeyMapper.ButtonWidth' value='80'/> "
-"<def var='Tooltip.MaxWidth' value='200'/> "
-"<def var='Tooltip.XDelta' value='16'/> "
-"<def var='Tooltip.YDelta' value='16'/> "
-"<def var='Predictive.Button.Width' value='60' /> "
+"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> "
+"<def var='KeyMapper.Spacing' value='5'/> "
+"<def var='KeyMapper.LabelWidth' value='80'/> "
+"<def var='KeyMapper.ButtonWidth' value='60'/> "
+"<def var='Tooltip.MaxWidth' value='70'/> "
+"<def var='Tooltip.XDelta' value='8'/> "
+"<def var='Tooltip.YDelta' value='8'/> "
+"<def var='Predictive.Button.Width' value='45' /> "
+"<def var='Predictive.Button.Height' value='15' /> "
+"<widget name='Button' "
+"size='72,16' "
+"/> "
+"<widget name='Slider' "
+"size='85,12' "
+"/> "
"<widget name='OptionsLabel' "
"size='110,Globals.Line.Height' "
"textalign='right' "
"/> "
"<widget name='SmallLabel' "
-"size='24,Globals.Line.Height' "
-"/> "
-"<widget name='ShortOptionsLabel' "
-"size='60,Globals.Line.Height' "
-"/> "
-"<widget name='Button' "
-"size='108,24' "
-"/> "
-"<widget name='Slider' "
-"size='128,18' "
+"size='18,Globals.Line.Height' "
"/> "
"<widget name='PopUp' "
-"size='-1,19' "
+"size='-1,15' "
"/> "
"<widget name='Checkbox' "
-"size='-1,14' "
+"size='-1,Globals.Line.Height' "
"/> "
"<widget name='Radiobutton' "
"size='-1,Globals.Line.Height' "
"/> "
"<widget name='ListWidget' "
-"padding='5,0,8,0' "
+"padding='5,0,0,0' "
"/> "
"<widget name='PopUpWidget' "
"padding='7,5,0,0' "
@@ -665,28 +663,28 @@
"padding='7,5,5,5' "
"/> "
"<widget name='Scrollbar' "
-"size='15,0' "
+"size='9,0' "
"/> "
"<widget name='TabWidget.Tab' "
-"size='75,27' "
-"padding='0,0,8,0' "
+"size='45,16' "
+"padding='0,0,2,0' "
"/> "
"<widget name='TabWidget.Body' "
-"padding='0,0,0,0' "
+"padding='0,0,0,-8' "
"/> "
"<widget name='TabWidget.NavButton' "
-"size='15,18' "
-"padding='0,3,4,0' "
+"size='32,18' "
+"padding='0,0,1,0' "
"/> "
"</globals> "
"<dialog name='Launcher' overlays='screen'> "
-"<layout type='vertical' center='true' padding='16,16,8,8'> "
+"<layout type='vertical' center='true' padding='6,6,2,2'> "
"<widget name='Version' "
"height='Globals.Line.Height' "
"/> "
-"<layout type='horizontal' spacing='5' padding='10,0,0,0'> "
+"<layout type='horizontal' spacing='5' padding='0,0,0,0'> "
"<widget name='SearchDesc' "
-"width='60' "
+"width='50' "
"height='Globals.Line.Height' "
"textalign='right' "
"/> "
@@ -701,39 +699,38 @@
"<space /> "
"</layout> "
"<widget name='GameList'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='LoadGameButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='AddGameButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='EditGameButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='RemoveGameButton' "
-"height='20' "
+"height='12' "
"/> "
"</layout> "
-"<space size='4'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='QuitButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='AboutButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='OptionsButton' "
-"height='20' "
+"height='12' "
"/> "
"<widget name='StartButton' "
-"height='20' "
+"height='12' "
"/> "
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> "
+"<layout type='vertical' padding='8,8,0,4'> "
"<widget name='Headline' "
"height='Globals.Line.Height' "
"/> "
@@ -741,7 +738,7 @@
"height='Globals.Line.Height' "
"/> "
"<widget name='List'/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"<layout type='horizontal' padding='0,0,8,0'> "
"<widget name='Up' "
"type='Button' "
"/> "
@@ -755,10 +752,10 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
+"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> "
"<layout type='vertical' padding='0,0,0,0'> "
"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,16'> "
+"<layout type='horizontal' padding='8,8,8,8'> "
"<space/> "
"<widget name='Cancel' "
"type='Button' "
@@ -771,7 +768,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='grModePopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -779,7 +776,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='grRenderPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -797,7 +794,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auMidiPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -805,7 +802,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auOPLPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -813,7 +810,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auSampleRatePopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -821,7 +818,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> "
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
"/> "
@@ -835,7 +832,7 @@
"type='Radiobutton' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
"/> "
@@ -849,9 +846,8 @@
"</layout> "
"</dialog> "
"<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='horizontal' padding='16,16,16,16' spacing='8'> "
-"<layout type='vertical' padding='0,0,0,0' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcMusicText' "
"type='OptionsLabel' "
"/> "
@@ -862,7 +858,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcSfxText' "
"type='OptionsLabel' "
"/> "
@@ -873,7 +869,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
"/> "
@@ -884,8 +880,8 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"</layout> "
-"<layout type='vertical' padding='24,0,24,0' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<space size='110' /> "
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
"/> "
@@ -894,7 +890,7 @@
"</dialog> "
"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auPrefGmPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -902,7 +898,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
"<widget name='mcFontButton' "
"type='Button' "
"/> "
@@ -917,7 +913,7 @@
"<widget name='mcMixedCheckbox' "
"type='Checkbox' "
"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='mcMidiGainText' "
"type='OptionsLabel' "
"/> "
@@ -933,7 +929,7 @@
"</dialog> "
"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='auPrefMt32PopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -951,7 +947,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='SaveButton' "
"type='Button' "
"/> "
@@ -963,7 +959,7 @@
"width='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='ThemeButton' "
"type='Button' "
"/> "
@@ -975,7 +971,7 @@
"width='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='ExtraButton' "
"type='Button' "
"/> "
@@ -999,7 +995,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
"<widget name='ThemeButton' "
"type='Button' "
"/> "
@@ -1007,25 +1003,31 @@
"height='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='RendererPopupDesc' "
-"type='OptionsLabel' "
+"width='80' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='RendererPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='AutosavePeriodPopupDesc' "
-"type='OptionsLabel' "
+"width='80' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='AutosavePeriodPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='GuiLanguagePopupDesc' "
-"type='OptionsLabel' "
+"width='80' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='GuiLanguagePopup' "
"type='PopUp' "
@@ -1060,10 +1062,10 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
+"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> "
"<layout type='vertical' padding='0,0,0,0' spacing='16'> "
"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,4'> "
+"<layout type='horizontal' padding='8,8,8,8'> "
"<space/> "
"<widget name='Cancel' "
"type='Button' "
@@ -1075,7 +1077,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1083,7 +1085,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1091,7 +1093,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1099,7 +1101,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1107,7 +1109,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -1115,34 +1117,43 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='vertical' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='Id' "
-"type='OptionsLabel' "
+"width='35' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='Domain' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='Name' "
-"type='OptionsLabel' "
+"width='35' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='Desc' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<space size='8'/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='LangPopupDesc' "
-"type='OptionsLabel' "
+"width='60' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='LangPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='PlatformPopupDesc' "
-"type='OptionsLabel' "
+"width='60' "
+"height='Globals.Line.Height' "
+"textalign='right' "
"/> "
"<widget name='PlatformPopup' "
"type='PopUp' "
@@ -1151,8 +1162,8 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='vertical' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
"<widget name='Savepath' "
"type='Button' "
"/> "
@@ -1164,7 +1175,7 @@
"width='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
"<widget name='Extrapath' "
"type='Button' "
"/> "
@@ -1176,7 +1187,7 @@
"width='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
"<widget name='Gamepath' "
"type='Button' "
"/> "
@@ -1187,7 +1198,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
+"<layout type='vertical' padding='8,8,8,8'> "
"<widget name='customOption1Checkbox' "
"type='Checkbox' "
"/> "
@@ -1212,57 +1223,55 @@
"</layout> "
"</dialog> "
"<dialog name='GlobalMenu' overlays='screen_center'> "
-"<layout type='vertical' padding='16,16,16,16' center='true'> "
+"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> "
"<widget name='Title' "
-"width='210' "
-"height='Globals.Line.Height' "
+"width='160' "
+"height='4' "
"/> "
"<widget name='Version' "
-"width='210' "
-"height='Globals.Line.Height' "
-"/> "
-"<widget name='Resume' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='160' "
+"height='4' "
"/> "
-"<space size='10'/> "
+"<space size='1'/> "
"<widget name='Load' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"<widget name='Save' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
-"<space size='10'/> "
+"<space size='1'/> "
"<widget name='Options' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"<widget name='Help' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"<widget name='About' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
+"/> "
+"<space size='1'/> "
+"<widget name='Resume' "
+"width='120' "
+"height='12' "
"/> "
-"<space size='10'/> "
"<widget name='RTL' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"<widget name='Quit' "
-"width='150' "
-"height='Globals.Button.Height' "
+"width='120' "
+"height='12' "
"/> "
"</layout> "
"</dialog> "
"<dialog name='GlobalConfig' overlays='screen_center'> "
"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0'> "
-"<layout type='vertical' padding='0,0,0,0' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcMusicText' "
"type='OptionsLabel' "
"/> "
@@ -1273,7 +1282,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcSfxText' "
"type='OptionsLabel' "
"/> "
@@ -1284,7 +1293,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
"/> "
@@ -1295,33 +1304,34 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"</layout> "
-"<layout type='vertical' padding='24,24,24,24' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<space size='110' /> "
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
-"width='80' "
+"width='80' "
"/> "
"</layout> "
-"</layout> "
-"<space size='8' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> "
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
"/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
-"width='100' "
+"width='90' "
"/> "
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
-"width='100' "
+"width='90' "
"/> "
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
-"width='100' "
+"width='90' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"</layout> "
+"<space size='2' /> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
"/> "
@@ -1332,8 +1342,8 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<space size='60'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"<space size='16'/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='4'> "
"<widget name='Keys' "
"type='Button' "
"/> "
@@ -1348,23 +1358,15 @@
"</layout> "
"</dialog> "
"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,32' center='true'> "
-"<widget name='Title' "
-"height='Globals.Line.Height' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,16' spacing='16'> "
+"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"<widget name='Title' height='Globals.Line.Height'/> "
"<widget name='List' /> "
-"<widget name='Thumbnail' "
-"width='180' "
-"height='200' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,16,0'> "
"<space/> "
"<widget name='Delete' "
"type='Button' "
"/> "
-"<space size='32'/> "
+"<space size='16'/> "
"<widget name='Cancel' "
"type='Button' "
"/> "
@@ -1374,16 +1376,16 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='ScummHelp' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"<dialog name='ScummHelp' overlays='screen'> "
+"<layout type='vertical' padding='8,8,8,8'> "
"<widget name='Title' "
-"width='320' "
+"width='180' "
"height='Globals.Line.Height' "
"/> "
"<widget name='HelpText' "
-"height='200' "
+"height='140' "
"/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='Prev' "
"type='Button' "
"/> "
@@ -1400,7 +1402,7 @@
"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
"<layout type='vertical' padding='8,8,8,8' center='true'> "
"<widget name='Description1' "
-"width='320' "
+"width='280' "
"height='Globals.Line.Height' "
"/> "
"<widget name='Description2' "
@@ -1418,20 +1420,20 @@
"</layout> "
"</dialog> "
"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,32,8' center='true'> "
+"<layout type='vertical' padding='4,4,16,4' center='true'> "
"<widget name='DirProgressText' "
-"width='480' "
+"width='280' "
"height='Globals.Line.Height' "
"/> "
"<widget name='GameProgressText' "
-"width='480' "
+"width='280' "
"height='Globals.Line.Height' "
"/> "
"<widget name='GameList' "
-"width='480' "
-"height='250' "
+"width='280' "
+"height='100' "
"/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='4,4,4,4'> "
"<widget name='Ok' "
"type='Button' "
"/> "
@@ -1442,20 +1444,20 @@
"</layout> "
"</dialog> "
"<dialog name='KeyMapper' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> "
+"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> "
"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='PopupDesc' "
"type='OptionsLabel' "
"/> "
"<widget name='Popup' "
"type='PopUp' "
-"width='400' "
+"width='150' "
"height='Globals.Line.Height' "
"/> "
"</layout> "
"<widget name='KeymapArea' "
-"width='600' "
-"height='280' "
+"width='300' "
+"height='120' "
"/> "
"<widget name='Close' "
"type='Button' "
@@ -1463,140 +1465,140 @@
"</layout> "
"</dialog> "
"<dialog name='Predictive' overlays='screen_center'> "
-"<layout type='vertical' padding='5,5,5,5' center='true'> "
+"<layout type='vertical' padding='1,1,1,1' center='true'> "
"<widget name='Headline' "
"height='Globals.Line.Height' "
-"width='210' "
+"width='150' "
"textalign='center' "
"/> "
-"<layout type='horizontal' padding='5,5,5,5'> "
+"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Word' "
-"width='190' "
+"width='120' "
"height='Globals.Button.Height' "
"/> "
"<widget name='Delete' "
"width='20' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"</layout> "
-"<space size='5' /> "
"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Button1' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='Button2' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='Button3' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"</layout> "
"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Button4' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='Button5' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='Button6' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"</layout> "
"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Button7' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='Button8' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='Button9' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"<layout type='horizontal' padding='3,3,3,0'> "
"<widget name='Pre' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='Button0' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='Next' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"</layout> "
-"<space size='5' /> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"<space size='3' /> "
+"<layout type='horizontal' padding='3,3,0,3'> "
"<widget name='Add' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
-"<space size='22'/> "
"<widget name='Cancel' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"<widget name='OK' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Button.Height' "
+"height='Globals.Predictive.Button.Height' "
"/> "
"</layout> "
"</layout> "
"</dialog> "
"</layout_info> "
-"<layout_info resolution='y<400'> "
+"<layout_info resolution='y>399'> "
"<globals> "
-"<def var='Line.Height' value='12' /> "
-"<def var='Font.Height' value='10' /> "
-"<def var='About.OuterBorder' value='10'/> "
-"<def var='Layout.Spacing' value='8'/> "
+"<def var='Line.Height' value='16' /> "
+"<def var='Font.Height' value='16' /> "
+"<def var='About.OuterBorder' value='80'/> "
+"<def var='Layout.Spacing' value='8' /> "
"<def var='ShowLauncherLogo' value='0'/> "
"<def var='ShowGlobalMenuLogo' value='0'/> "
"<def var='ShowSearchPic' value='0'/> "
-"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> "
-"<def var='KeyMapper.Spacing' value='5'/> "
-"<def var='KeyMapper.LabelWidth' value='80'/> "
-"<def var='KeyMapper.ButtonWidth' value='60'/> "
-"<def var='Tooltip.MaxWidth' value='70'/> "
-"<def var='Tooltip.XDelta' value='8'/> "
-"<def var='Tooltip.YDelta' value='8'/> "
-"<def var='Predictive.Button.Width' value='45' /> "
-"<def var='Predictive.Button.Height' value='15' /> "
-"<widget name='Button' "
-"size='72,16' "
-"/> "
-"<widget name='Slider' "
-"size='85,12' "
-"/> "
+"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> "
+"<def var='KeyMapper.Spacing' value='10'/> "
+"<def var='KeyMapper.LabelWidth' value='100'/> "
+"<def var='KeyMapper.ButtonWidth' value='80'/> "
+"<def var='Tooltip.MaxWidth' value='200'/> "
+"<def var='Tooltip.XDelta' value='16'/> "
+"<def var='Tooltip.YDelta' value='16'/> "
+"<def var='Predictive.Button.Width' value='60' /> "
"<widget name='OptionsLabel' "
"size='110,Globals.Line.Height' "
"textalign='right' "
"/> "
"<widget name='SmallLabel' "
-"size='18,Globals.Line.Height' "
+"size='24,Globals.Line.Height' "
+"/> "
+"<widget name='ShortOptionsLabel' "
+"size='60,Globals.Line.Height' "
+"/> "
+"<widget name='Button' "
+"size='108,24' "
+"/> "
+"<widget name='Slider' "
+"size='128,18' "
"/> "
"<widget name='PopUp' "
-"size='-1,15' "
+"size='-1,19' "
"/> "
"<widget name='Checkbox' "
-"size='-1,Globals.Line.Height' "
+"size='-1,14' "
"/> "
"<widget name='Radiobutton' "
"size='-1,Globals.Line.Height' "
"/> "
"<widget name='ListWidget' "
-"padding='5,0,0,0' "
+"padding='5,0,8,0' "
"/> "
"<widget name='PopUpWidget' "
"padding='7,5,0,0' "
@@ -1608,28 +1610,28 @@
"padding='7,5,5,5' "
"/> "
"<widget name='Scrollbar' "
-"size='9,0' "
+"size='15,0' "
"/> "
"<widget name='TabWidget.Tab' "
-"size='45,16' "
-"padding='0,0,2,0' "
+"size='75,27' "
+"padding='0,0,8,0' "
"/> "
"<widget name='TabWidget.Body' "
-"padding='0,0,0,-8' "
+"padding='0,0,0,0' "
"/> "
"<widget name='TabWidget.NavButton' "
-"size='32,18' "
-"padding='0,0,1,0' "
+"size='15,18' "
+"padding='0,3,4,0' "
"/> "
"</globals> "
"<dialog name='Launcher' overlays='screen'> "
-"<layout type='vertical' center='true' padding='6,6,2,2'> "
+"<layout type='vertical' center='true' padding='16,16,8,8'> "
"<widget name='Version' "
"height='Globals.Line.Height' "
"/> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,0'> "
+"<layout type='horizontal' spacing='5' padding='10,0,0,0'> "
"<widget name='SearchDesc' "
-"width='50' "
+"width='60' "
"height='Globals.Line.Height' "
"textalign='right' "
"/> "
@@ -1644,38 +1646,39 @@
"<space /> "
"</layout> "
"<widget name='GameList'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='LoadGameButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='AddGameButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='EditGameButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='RemoveGameButton' "
-"height='12' "
+"height='20' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"<space size='4'/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='QuitButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='AboutButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='OptionsButton' "
-"height='12' "
+"height='20' "
"/> "
"<widget name='StartButton' "
-"height='12' "
+"height='20' "
"/> "
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,0,4'> "
+"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> "
+"<layout type='vertical' padding='8,8,8,8'> "
"<widget name='Headline' "
"height='Globals.Line.Height' "
"/> "
@@ -1683,7 +1686,7 @@
"height='Globals.Line.Height' "
"/> "
"<widget name='List'/> "
-"<layout type='horizontal' padding='0,0,8,0'> "
+"<layout type='horizontal' padding='0,0,16,0'> "
"<widget name='Up' "
"type='Button' "
"/> "
@@ -1697,10 +1700,10 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> "
+"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
"<layout type='vertical' padding='0,0,0,0'> "
"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='16,16,16,16'> "
"<space/> "
"<widget name='Cancel' "
"type='Button' "
@@ -1713,7 +1716,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='grModePopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1721,7 +1724,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='grRenderPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1739,7 +1742,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auMidiPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1747,7 +1750,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auOPLPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1755,7 +1758,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auSampleRatePopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1763,7 +1766,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
"/> "
@@ -1777,7 +1780,7 @@
"type='Radiobutton' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
"/> "
@@ -1791,8 +1794,9 @@
"</layout> "
"</dialog> "
"<dialog name='GlobalOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='16,16,16,16' spacing='8'> "
+"<layout type='vertical' padding='0,0,0,0' spacing='8'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='vcMusicText' "
"type='OptionsLabel' "
"/> "
@@ -1803,7 +1807,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='vcSfxText' "
"type='OptionsLabel' "
"/> "
@@ -1814,7 +1818,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
"/> "
@@ -1825,8 +1829,8 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
-"<space size='110' /> "
+"</layout> "
+"<layout type='vertical' padding='24,0,24,0' center='true'> "
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
"/> "
@@ -1835,7 +1839,7 @@
"</dialog> "
"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auPrefGmPopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1843,7 +1847,7 @@
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='mcFontButton' "
"type='Button' "
"/> "
@@ -1858,7 +1862,7 @@
"<widget name='mcMixedCheckbox' "
"type='Checkbox' "
"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<widget name='mcMidiGainText' "
"type='OptionsLabel' "
"/> "
@@ -1874,7 +1878,7 @@
"</dialog> "
"<dialog name='GlobalOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='auPrefMt32PopupDesc' "
"type='OptionsLabel' "
"/> "
@@ -1892,7 +1896,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Paths' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='SaveButton' "
"type='Button' "
"/> "
@@ -1904,7 +1908,7 @@
"width='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='ThemeButton' "
"type='Button' "
"/> "
@@ -1916,7 +1920,7 @@
"width='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='ExtraButton' "
"type='Button' "
"/> "
@@ -1940,7 +1944,7 @@
"</dialog> "
"<dialog name='GlobalOptions_Misc' overlays='Dialog.GlobalOptions.TabWidget'> "
"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='ThemeButton' "
"type='Button' "
"/> "
@@ -1948,31 +1952,25 @@
"height='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='RendererPopupDesc' "
-"width='80' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='RendererPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='AutosavePeriodPopupDesc' "
-"width='80' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='AutosavePeriodPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='GuiLanguagePopupDesc' "
-"width='80' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='GuiLanguagePopup' "
"type='PopUp' "
@@ -2007,10 +2005,10 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='GameOptions' overlays='screen' inset='16' shading='dim'> "
+"<dialog name='GameOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
"<layout type='vertical' padding='0,0,0,0' spacing='16'> "
"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
+"<layout type='horizontal' padding='16,16,16,4'> "
"<space/> "
"<widget name='Cancel' "
"type='Button' "
@@ -2022,7 +2020,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -2030,7 +2028,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -2038,7 +2036,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -2046,7 +2044,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -2054,7 +2052,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
"/> "
@@ -2062,43 +2060,34 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Game' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='vertical' padding='16,16,16,16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Id' "
-"width='35' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='Domain' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Name' "
-"width='35' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='Desc' "
"type='PopUp' "
"/> "
"</layout> "
-"<space size='8'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='LangPopupDesc' "
-"width='60' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='LangPopup' "
"type='PopUp' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='PlatformPopupDesc' "
-"width='60' "
-"height='Globals.Line.Height' "
-"textalign='right' "
+"type='OptionsLabel' "
"/> "
"<widget name='PlatformPopup' "
"type='PopUp' "
@@ -2107,8 +2096,8 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Paths' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"<layout type='vertical' padding='16,16,16,16'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Savepath' "
"type='Button' "
"/> "
@@ -2120,7 +2109,7 @@
"width='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Extrapath' "
"type='Button' "
"/> "
@@ -2132,7 +2121,7 @@
"width='Globals.Line.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='Gamepath' "
"type='Button' "
"/> "
@@ -2143,7 +2132,7 @@
"</layout> "
"</dialog> "
"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"<layout type='vertical' padding='16,16,16,16'> "
"<widget name='customOption1Checkbox' "
"type='Checkbox' "
"/> "
@@ -2168,55 +2157,57 @@
"</layout> "
"</dialog> "
"<dialog name='GlobalMenu' overlays='screen_center'> "
-"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> "
+"<layout type='vertical' padding='16,16,16,16' center='true'> "
"<widget name='Title' "
-"width='160' "
-"height='4' "
+"width='210' "
+"height='Globals.Line.Height' "
"/> "
"<widget name='Version' "
-"width='160' "
-"height='4' "
+"width='210' "
+"height='Globals.Line.Height' "
"/> "
-"<space size='1'/> "
+"<widget name='Resume' "
+"width='150' "
+"height='Globals.Button.Height' "
+"/> "
+"<space size='10'/> "
"<widget name='Load' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Save' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
-"<space size='1'/> "
+"<space size='10'/> "
"<widget name='Options' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Help' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='About' "
-"width='120' "
-"height='12' "
-"/> "
-"<space size='1'/> "
-"<widget name='Resume' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
+"<space size='10'/> "
"<widget name='RTL' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Quit' "
-"width='120' "
-"height='12' "
+"width='150' "
+"height='Globals.Button.Height' "
"/> "
"</layout> "
"</dialog> "
"<dialog name='GlobalConfig' overlays='screen_center'> "
"<layout type='vertical' padding='8,8,8,8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='vertical' padding='0,0,0,0' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='vcMusicText' "
"type='OptionsLabel' "
"/> "
@@ -2227,7 +2218,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='vcSfxText' "
"type='OptionsLabel' "
"/> "
@@ -2238,7 +2229,7 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
"/> "
@@ -2249,34 +2240,33 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
-"<space size='110' /> "
+"</layout> "
+"<layout type='vertical' padding='24,24,24,24' center='true'> "
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
-"width='80' "
+"width='80' "
"/> "
"</layout> "
-"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> "
+"</layout> "
+"<space size='8' /> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
-"width='90' "
+"width='100' "
"/> "
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
-"width='90' "
+"width='100' "
"/> "
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
-"width='90' "
+"width='100' "
"/> "
"</layout> "
-"</layout> "
-"<space size='2' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
"/> "
@@ -2287,8 +2277,8 @@
"type='SmallLabel' "
"/> "
"</layout> "
-"<space size='16'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='4'> "
+"<space size='60'/> "
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
"<widget name='Keys' "
"type='Button' "
"/> "
@@ -2303,15 +2293,23 @@
"</layout> "
"</dialog> "
"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
-"<widget name='Title' height='Globals.Line.Height'/> "
+"<layout type='vertical' padding='8,8,8,32' center='true'> "
+"<widget name='Title' "
+"height='Globals.Line.Height' "
+"/> "
+"<layout type='horizontal' padding='0,0,0,16' spacing='16'> "
"<widget name='List' /> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"<widget name='Thumbnail' "
+"width='180' "
+"height='200' "
+"/> "
+"</layout> "
+"<layout type='horizontal' padding='0,0,0,0'> "
"<space/> "
"<widget name='Delete' "
"type='Button' "
"/> "
-"<space size='16'/> "
+"<space size='32'/> "
"<widget name='Cancel' "
"type='Button' "
"/> "
@@ -2321,16 +2319,16 @@
"</layout> "
"</layout> "
"</dialog> "
-"<dialog name='ScummHelp' overlays='screen'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"<dialog name='ScummHelp' overlays='screen_center'> "
+"<layout type='vertical' padding='8,8,8,8' center='true'> "
"<widget name='Title' "
-"width='180' "
+"width='320' "
"height='Globals.Line.Height' "
"/> "
"<widget name='HelpText' "
-"height='140' "
+"height='200' "
"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"<layout type='horizontal' padding='0,0,16,0'> "
"<widget name='Prev' "
"type='Button' "
"/> "
@@ -2347,7 +2345,7 @@
"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
"<layout type='vertical' padding='8,8,8,8' center='true'> "
"<widget name='Description1' "
-"width='280' "
+"width='320' "
"height='Globals.Line.Height' "
"/> "
"<widget name='Description2' "
@@ -2365,20 +2363,20 @@
"</layout> "
"</dialog> "
"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='4,4,16,4' center='true'> "
+"<layout type='vertical' padding='8,8,32,8' center='true'> "
"<widget name='DirProgressText' "
-"width='280' "
+"width='480' "
"height='Globals.Line.Height' "
"/> "
"<widget name='GameProgressText' "
-"width='280' "
+"width='480' "
"height='Globals.Line.Height' "
"/> "
"<widget name='GameList' "
-"width='280' "
-"height='100' "
+"width='480' "
+"height='250' "
"/> "
-"<layout type='horizontal' padding='4,4,4,4'> "
+"<layout type='horizontal' padding='8,8,8,8'> "
"<widget name='Ok' "
"type='Button' "
"/> "
@@ -2389,20 +2387,20 @@
"</layout> "
"</dialog> "
"<dialog name='KeyMapper' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> "
+"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> "
"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
"<widget name='PopupDesc' "
"type='OptionsLabel' "
"/> "
"<widget name='Popup' "
"type='PopUp' "
-"width='150' "
+"width='400' "
"height='Globals.Line.Height' "
"/> "
"</layout> "
"<widget name='KeymapArea' "
-"width='300' "
-"height='120' "
+"width='600' "
+"height='280' "
"/> "
"<widget name='Close' "
"type='Button' "
@@ -2410,91 +2408,93 @@
"</layout> "
"</dialog> "
"<dialog name='Predictive' overlays='screen_center'> "
-"<layout type='vertical' padding='1,1,1,1' center='true'> "
+"<layout type='vertical' padding='5,5,5,5' center='true'> "
"<widget name='Headline' "
"height='Globals.Line.Height' "
-"width='150' "
+"width='210' "
"textalign='center' "
"/> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"<layout type='horizontal' padding='5,5,5,5'> "
"<widget name='Word' "
-"width='120' "
+"width='190' "
"height='Globals.Button.Height' "
"/> "
"<widget name='Delete' "
"width='20' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"</layout> "
+"<space size='5' /> "
"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Button1' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Button2' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Button3' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"</layout> "
"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Button4' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Button5' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Button6' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"</layout> "
"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Button7' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Button8' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Button9' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"</layout> "
-"<layout type='horizontal' padding='3,3,3,0'> "
+"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Pre' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Button0' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='Next' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"</layout> "
-"<space size='3' /> "
-"<layout type='horizontal' padding='3,3,0,3'> "
+"<space size='5' /> "
+"<layout type='horizontal' padding='3,3,3,3'> "
"<widget name='Add' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
+"<space size='22'/> "
"<widget name='Cancel' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"<widget name='OK' "
"width='Globals.Predictive.Button.Width' "
-"height='Globals.Predictive.Button.Height' "
+"height='Globals.Button.Height' "
"/> "
"</layout> "
"</layout> "
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index ec1728b778..d126ed0774 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC
index 7cbed97e40..d4bed29cf8 100644
--- a/gui/themes/scummclassic/THEMERC
+++ b/gui/themes/scummclassic/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.12:ScummVM Classic Theme:No Author]
+[SCUMMVM_STX0.8.13:ScummVM Classic Theme:No Author]
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index deae315e30..db116325e2 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC
index 326993e98d..60744d386f 100644
--- a/gui/themes/scummmodern/THEMERC
+++ b/gui/themes/scummmodern/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.8.12:ScummVM Modern Theme:No Author]
+[SCUMMVM_STX0.8.13:ScummVM Modern Theme:No Author]
diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx
index 970d78a5ae..037c327235 100644
--- a/gui/themes/scummmodern/scummmodern_gfx.stx
+++ b/gui/themes/scummmodern/scummmodern_gfx.stx
@@ -187,8 +187,8 @@
<!-- <defaults fill = 'gradient' fg_color = 'white'/> -->
- <cursor file = 'cursor.bmp' hotspot = '0, 0' scale = '3'/>
- <cursor resolution = 'y<400' file = 'cursor_small.bmp' hotspot = '0, 0' scale = '3'/>
+ <cursor file = 'cursor.bmp' hotspot = '0, 0'/>
+ <cursor resolution = 'y<400' file = 'cursor_small.bmp' hotspot = '0, 0'/>
<!-- Selection (text or list items) -->
<drawdata id = 'text_selection' cache = 'false'>
diff --git a/gui/widget.cpp b/gui/widget.cpp
index fc6510b976..1b68e36ea8 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -376,7 +376,7 @@ void ButtonWidget::wantTickle(bool tickled) {
PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)
: ButtonWidget(boss, x, y, w, h, "", tooltip, cmd, hotkey),
- _gfx(), _alpha(256), _transparency(false) {
+ _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) {
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
_type = kButtonWidget;
@@ -384,38 +384,54 @@ PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, co
PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd, uint8 hotkey)
: ButtonWidget(boss, name, "", tooltip, cmd, hotkey),
- _alpha(256), _transparency(false) {
+ _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) {
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
_type = kButtonWidget;
}
PicButtonWidget::~PicButtonWidget() {
- _gfx.free();
+ _gfx->free();
+ delete _gfx;
}
void PicButtonWidget::setGfx(const Graphics::Surface *gfx) {
- _gfx.free();
+ _gfx->free();
if (!gfx || !gfx->pixels)
return;
+ if (gfx->format.bytesPerPixel == 1) {
+ warning("PicButtonWidget::setGfx got paletted surface passed");
+ return;
+ }
+
+
if (gfx->w > _w || gfx->h > _h) {
warning("PicButtonWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h);
return;
}
- // TODO: add conversion to OverlayColor
- _gfx.copyFrom(*gfx);
+ _gfx->copyFrom(*gfx);
}
void PicButtonWidget::drawWidget() {
g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags());
- if (sizeof(OverlayColor) == _gfx.format.bytesPerPixel && _gfx.pixels) {
- const int x = _x + (_w - _gfx.w) / 2;
- const int y = _y + (_h - _gfx.h) / 2;
+ if (_gfx->pixels) {
+ // Check whether the set up surface needs to be converted to the GUI
+ // color format.
+ const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
+ if (_gfx->format != requiredFormat) {
+ Graphics::Surface *converted = _gfx->convertTo(requiredFormat);
+ _gfx->free();
+ delete _gfx;
+ _gfx = converted;
+ }
+
+ const int x = _x + (_w - _gfx->w) / 2;
+ const int y = _y + (_h - _gfx->h) / 2;
- g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency);
+ g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx->w, y + _gfx->h), *_gfx, _state, _alpha, _transparency);
}
}
@@ -603,34 +619,39 @@ int SliderWidget::posToValue(int pos) {
#pragma mark -
GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
- : Widget(boss, x, y, w, h, tooltip), _gfx(), _alpha(256), _transparency(false) {
+ : Widget(boss, x, y, w, h, tooltip), _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
_type = kGraphicsWidget;
}
GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip)
- : Widget(boss, name, tooltip), _gfx(), _alpha(256), _transparency(false) {
+ : Widget(boss, name, tooltip), _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
_type = kGraphicsWidget;
}
GraphicsWidget::~GraphicsWidget() {
- _gfx.free();
+ _gfx->free();
+ delete _gfx;
}
void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
- _gfx.free();
+ _gfx->free();
if (!gfx || !gfx->pixels)
return;
+ if (gfx->format.bytesPerPixel == 1) {
+ warning("GraphicsWidget::setGfx got paletted surface passed");
+ return;
+ }
+
if (gfx->w > _w || gfx->h > _h) {
warning("GraphicsWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h);
return;
}
- // TODO: add conversion to OverlayColor
- _gfx.copyFrom(*gfx);
+ _gfx->copyFrom(*gfx);
}
void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
@@ -639,26 +660,29 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
if (h == -1)
h = _h;
- Graphics::PixelFormat overlayFormat = g_system->getOverlayFormat();
+ const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
- _gfx.free();
- _gfx.create(w, h, overlayFormat);
-
- OverlayColor *dst = (OverlayColor *)_gfx.pixels;
- OverlayColor fillCol = overlayFormat.RGBToColor(r, g, b);
- while (h--) {
- for (int i = 0; i < w; ++i) {
- *dst++ = fillCol;
- }
- }
+ _gfx->free();
+ _gfx->create(w, h, requiredFormat);
+ _gfx->fillRect(Common::Rect(0, 0, w, h), _gfx->format.RGBToColor(r, g, b));
}
void GraphicsWidget::drawWidget() {
- if (sizeof(OverlayColor) == _gfx.format.bytesPerPixel && _gfx.pixels) {
- const int x = _x + (_w - _gfx.w) / 2;
- const int y = _y + (_h - _gfx.h) / 2;
+ if (_gfx->pixels) {
+ // Check whether the set up surface needs to be converted to the GUI
+ // color format.
+ const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
+ if (_gfx->format != requiredFormat) {
+ Graphics::Surface *converted = _gfx->convertTo(requiredFormat);
+ _gfx->free();
+ delete _gfx;
+ _gfx = converted;
+ }
+
+ const int x = _x + (_w - _gfx->w) / 2;
+ const int y = _y + (_h - _gfx->h) / 2;
- g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency);
+ g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx->w, y + _gfx->h), *_gfx, _state, _alpha, _transparency);
}
}
diff --git a/gui/widget.h b/gui/widget.h
index 6a6c67ced9..6de56862c3 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -227,7 +227,7 @@ public:
protected:
void drawWidget();
- Graphics::Surface _gfx;
+ Graphics::Surface *_gfx;
int _alpha;
bool _transparency;
};
@@ -355,7 +355,7 @@ public:
protected:
void drawWidget();
- Graphics::Surface _gfx;
+ Graphics::Surface *_gfx;
int _alpha;
bool _transparency;
};
diff --git a/video/codecs/qtrle.cpp b/video/codecs/qtrle.cpp
index f01720ec86..d2cdea27de 100644
--- a/video/codecs/qtrle.cpp
+++ b/video/codecs/qtrle.cpp
@@ -37,28 +37,25 @@ namespace Video {
QTRLEDecoder::QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel) : Codec() {
_bitsPerPixel = bitsPerPixel;
- _pixelFormat = g_system->getScreenFormat();
- // We need to increase the surface size to a multiple of 4
+ // We need to ensure the width is a multiple of 4
uint16 wMod = width % 4;
- if(wMod != 0)
+ if (wMod != 0)
width += 4 - wMod;
- debug(2, "QTRLE corrected width: %d", width);
-
_surface = new Graphics::Surface();
- _surface->create(width, height, _bitsPerPixel <= 8 ? Graphics::PixelFormat::createFormatCLUT8() : _pixelFormat);
+ _surface->create(width, height, getPixelFormat());
}
#define CHECK_STREAM_PTR(n) \
if ((stream->pos() + n) > stream->size()) { \
- warning ("Problem: stream out of bounds (%d >= %d)", stream->pos() + n, stream->size()); \
+ warning("QTRLE Problem: stream out of bounds (%d > %d)", stream->pos() + n, stream->size()); \
return; \
}
#define CHECK_PIXEL_PTR(n) \
if ((int32)pixelPtr + n > _surface->w * _surface->h) { \
- warning ("Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _surface->w * _surface->h); \
+ warning("QTRLE Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _surface->w * _surface->h); \
return; \
} \
@@ -132,8 +129,6 @@ void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr,
for (int8 i = numPixels - 1; i >= 0; i--) {
pi[numPixels - 1 - i] = (stream->readByte() >> ((i * bpp) & 0x07)) & ((1 << bpp) - 1);
- // FIXME: Is this right?
- //stream_ptr += ((i & ((num_pixels>>2)-1)) == 0);
if ((i & ((numPixels >> 2) - 1)) == 0)
stream->readByte();
}
@@ -215,7 +210,7 @@ void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, ui
void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+ uint16 *rgb = (uint16 *)_surface->pixels;
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -235,25 +230,15 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u
CHECK_PIXEL_PTR(rleCode);
- while (rleCode--) {
- // Convert from RGB555 to the format specified by the Overlay
- byte r = 0, g = 0, b = 0;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(rgb16, r, g, b);
- rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
- }
+ while (rleCode--)
+ rgb[pixelPtr++] = rgb16;
} else {
CHECK_STREAM_PTR(rleCode * 2);
CHECK_PIXEL_PTR(rleCode);
// copy pixels directly to output
- while (rleCode--) {
- uint16 rgb16 = stream->readUint16BE();
-
- // Convert from RGB555 to the format specified by the Overlay
- byte r = 0, g = 0, b = 0;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(rgb16, r, g, b);
- rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
- }
+ while (rleCode--)
+ rgb[pixelPtr++] = stream->readUint16BE();
}
}
@@ -263,7 +248,7 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u
void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+ uint32 *rgb = (uint32 *)_surface->pixels;
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -283,11 +268,12 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
byte r = stream->readByte();
byte g = stream->readByte();
byte b = stream->readByte();
+ uint32 color = _surface->format.RGBToColor(r, g, b);
CHECK_PIXEL_PTR(rleCode);
while (rleCode--)
- rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
+ rgb[pixelPtr++] = color;
} else {
CHECK_STREAM_PTR(rleCode * 3);
CHECK_PIXEL_PTR(rleCode);
@@ -297,7 +283,7 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
byte r = stream->readByte();
byte g = stream->readByte();
byte b = stream->readByte();
- rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
+ rgb[pixelPtr++] = _surface->format.RGBToColor(r, g, b);
}
}
}
@@ -308,7 +294,7 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+ uint32 *rgb = (uint32 *)_surface->pixels;
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -329,11 +315,12 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u
byte r = stream->readByte();
byte g = stream->readByte();
byte b = stream->readByte();
+ uint32 color = _surface->format.ARGBToColor(a, r, g, b);
CHECK_PIXEL_PTR(rleCode);
while (rleCode--)
- rgb[pixelPtr++] = _pixelFormat.ARGBToColor(a, r, g, b);
+ rgb[pixelPtr++] = color;
} else {
CHECK_STREAM_PTR(rleCode * 4);
CHECK_PIXEL_PTR(rleCode);
@@ -344,7 +331,7 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u
byte r = stream->readByte();
byte g = stream->readByte();
byte b = stream->readByte();
- rgb[pixelPtr++] = _pixelFormat.ARGBToColor(a, r, g, b);
+ rgb[pixelPtr++] = _surface->format.ARGBToColor(a, r, g, b);
}
}
}
@@ -354,7 +341,7 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u
}
const Graphics::Surface *QTRLEDecoder::decodeImage(Common::SeekableReadStream *stream) {
- uint16 start_line = 0;
+ uint16 startLine = 0;
uint16 height = _surface->h;
// check if this frame is even supposed to change
@@ -369,44 +356,45 @@ const Graphics::Surface *QTRLEDecoder::decodeImage(Common::SeekableReadStream *s
// if a header is present, fetch additional decoding parameters
if (header & 8) {
- if(stream->size() < 14)
+ if (stream->size() < 14)
return _surface;
- start_line = stream->readUint16BE();
+
+ startLine = stream->readUint16BE();
stream->readUint16BE(); // Unknown
height = stream->readUint16BE();
stream->readUint16BE(); // Unknown
}
- uint32 row_ptr = _surface->w * start_line;
+ uint32 rowPtr = _surface->w * startLine;
switch (_bitsPerPixel) {
- case 1:
- case 33:
- decode1(stream, row_ptr, height);
- break;
- case 2:
- case 34:
- decode2_4(stream, row_ptr, height, 2);
- break;
- case 4:
- case 36:
- decode2_4(stream, row_ptr, height, 4);
- break;
- case 8:
- case 40:
- decode8(stream, row_ptr, height);
- break;
- case 16:
- decode16(stream, row_ptr, height);
- break;
- case 24:
- decode24(stream, row_ptr, height);
- break;
- case 32:
- decode32(stream, row_ptr, height);
- break;
- default:
- error ("Unsupported bits per pixel %d", _bitsPerPixel);
+ case 1:
+ case 33:
+ decode1(stream, rowPtr, height);
+ break;
+ case 2:
+ case 34:
+ decode2_4(stream, rowPtr, height, 2);
+ break;
+ case 4:
+ case 36:
+ decode2_4(stream, rowPtr, height, 4);
+ break;
+ case 8:
+ case 40:
+ decode8(stream, rowPtr, height);
+ break;
+ case 16:
+ decode16(stream, rowPtr, height);
+ break;
+ case 24:
+ decode24(stream, rowPtr, height);
+ break;
+ case 32:
+ decode32(stream, rowPtr, height);
+ break;
+ default:
+ error("Unsupported QTRLE bits per pixel %d", _bitsPerPixel);
}
return _surface;
@@ -417,4 +405,27 @@ QTRLEDecoder::~QTRLEDecoder() {
delete _surface;
}
+Graphics::PixelFormat QTRLEDecoder::getPixelFormat() const {
+ switch (_bitsPerPixel) {
+ case 1:
+ case 33:
+ case 2:
+ case 34:
+ case 4:
+ case 36:
+ case 8:
+ case 40:
+ return Graphics::PixelFormat::createFormatCLUT8();
+ case 16:
+ return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ case 24:
+ case 32:
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ default:
+ error("Unsupported QTRLE bits per pixel %d", _bitsPerPixel);
+ }
+
+ return Graphics::PixelFormat();
+}
+
} // End of namespace Video
diff --git a/video/codecs/qtrle.h b/video/codecs/qtrle.h
index 6f8e113ca5..d9db58ab23 100644
--- a/video/codecs/qtrle.h
+++ b/video/codecs/qtrle.h
@@ -34,13 +34,12 @@ public:
~QTRLEDecoder();
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
- Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+ Graphics::PixelFormat getPixelFormat() const;
private:
byte _bitsPerPixel;
Graphics::Surface *_surface;
- Graphics::PixelFormat _pixelFormat;
void decode1(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
void decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange, byte bpp);
diff --git a/video/codecs/rpza.cpp b/video/codecs/rpza.cpp
index df5738202e..acc1b7f358 100644
--- a/video/codecs/rpza.cpp
+++ b/video/codecs/rpza.cpp
@@ -28,22 +28,17 @@
#include "common/system.h"
#include "common/stream.h"
#include "common/textconsole.h"
-#include "graphics/colormasks.h"
namespace Video {
RPZADecoder::RPZADecoder(uint16 width, uint16 height) : Codec() {
- _pixelFormat = g_system->getScreenFormat();
-
// We need to increase the surface size to a multiple of 4
uint16 wMod = width % 4;
- if(wMod != 0)
+ if (wMod != 0)
width += 4 - wMod;
- debug(2, "RPZA corrected width: %d", width);
-
_surface = new Graphics::Surface();
- _surface->create(width, height, _pixelFormat);
+ _surface->create(width, height, getPixelFormat());
}
RPZADecoder::~RPZADecoder() {
@@ -59,18 +54,11 @@ RPZADecoder::~RPZADecoder() {
} \
totalBlocks--; \
if (totalBlocks < 0) \
- error("block counter just went negative (this should not happen)") \
+ error("rpza block counter just went negative (this should not happen)") \
-// Convert from RGB555 to the format specified by the screen
#define PUT_PIXEL(color) \
- if ((int32)blockPtr < _surface->w * _surface->h) { \
- byte r = 0, g = 0, b = 0; \
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(color, r, g, b); \
- if (_pixelFormat.bytesPerPixel == 2) \
- *((uint16 *)_surface->pixels + blockPtr) = _pixelFormat.RGBToColor(r, g, b); \
- else \
- *((uint32 *)_surface->pixels + blockPtr) = _pixelFormat.RGBToColor(r, g, b); \
- } \
+ if ((int32)blockPtr < _surface->w * _surface->h) \
+ WRITE_UINT16((uint16 *)_surface->pixels + blockPtr, color); \
blockPtr++
const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *stream) {
diff --git a/video/codecs/rpza.h b/video/codecs/rpza.h
index 809a69f444..f082d25549 100644
--- a/video/codecs/rpza.h
+++ b/video/codecs/rpza.h
@@ -34,11 +34,10 @@ public:
~RPZADecoder();
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
- Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+ Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); }
private:
Graphics::Surface *_surface;
- Graphics::PixelFormat _pixelFormat;
};
} // End of namespace Video