aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS8
-rw-r--r--audio/softsynth/mt32/AReverbModel.cpp277
-rw-r--r--audio/softsynth/mt32/AReverbModel.h87
-rw-r--r--audio/softsynth/mt32/BReverbModel.cpp129
-rw-r--r--audio/softsynth/mt32/BReverbModel.h24
-rw-r--r--audio/softsynth/mt32/DelayReverb.cpp142
-rw-r--r--audio/softsynth/mt32/DelayReverb.h50
-rw-r--r--audio/softsynth/mt32/FreeverbModel.cpp78
-rw-r--r--audio/softsynth/mt32/FreeverbModel.h44
-rw-r--r--audio/softsynth/mt32/LA32FloatWaveGenerator.cpp (renamed from audio/softsynth/mt32/LegacyWaveGenerator.cpp)10
-rw-r--r--audio/softsynth/mt32/LA32FloatWaveGenerator.h (renamed from audio/softsynth/mt32/LegacyWaveGenerator.h)6
-rw-r--r--audio/softsynth/mt32/LA32WaveGenerator.cpp9
-rw-r--r--audio/softsynth/mt32/LA32WaveGenerator.h6
-rw-r--r--audio/softsynth/mt32/Part.cpp43
-rw-r--r--audio/softsynth/mt32/Part.h4
-rw-r--r--audio/softsynth/mt32/Partial.cpp39
-rw-r--r--audio/softsynth/mt32/Partial.h25
-rw-r--r--audio/softsynth/mt32/PartialManager.cpp62
-rw-r--r--audio/softsynth/mt32/PartialManager.h12
-rw-r--r--audio/softsynth/mt32/Poly.cpp49
-rw-r--r--audio/softsynth/mt32/Poly.h6
-rw-r--r--audio/softsynth/mt32/Structures.h6
-rw-r--r--audio/softsynth/mt32/Synth.cpp608
-rw-r--r--audio/softsynth/mt32/Synth.h192
-rw-r--r--audio/softsynth/mt32/TVP.cpp2
-rw-r--r--audio/softsynth/mt32/Tables.h5
-rw-r--r--audio/softsynth/mt32/freeverb.cpp324
-rw-r--r--audio/softsynth/mt32/freeverb.h189
-rw-r--r--audio/softsynth/mt32/module.mk9
-rw-r--r--audio/softsynth/mt32/mt32emu.h35
-rw-r--r--backends/platform/tizen/application.cpp22
-rw-r--r--backends/platform/tizen/audio.cpp36
-rw-r--r--backends/platform/tizen/audio.h4
-rw-r--r--backends/platform/tizen/form.cpp25
-rw-r--r--backends/platform/tizen/form.h9
-rw-r--r--backends/platform/tizen/fs.cpp1
-rw-r--r--backends/platform/tizen/graphics.cpp7
-rw-r--r--backends/platform/tizen/sscanf.cpp2
-rw-r--r--backends/platform/tizen/system.cpp6
-rw-r--r--backends/vkeybd/virtual-keyboard-gui.cpp34
-rw-r--r--backends/vkeybd/virtual-keyboard-gui.h6
-rw-r--r--backends/vkeybd/virtual-keyboard.h4
-rw-r--r--devtools/create_mortdat/create_mortdat.cpp35
-rw-r--r--devtools/create_mortdat/create_mortdat.h2
-rw-r--r--devtools/create_mortdat/gametext.h34
-rw-r--r--devtools/create_mortdat/menudata.h64
-rw-r--r--devtools/create_project/msbuild.cpp4
-rw-r--r--devtools/create_project/visualstudio.cpp4
-rwxr-xr-xdevtools/credits.pl10
-rw-r--r--devtools/scumm-md5.txt1
-rw-r--r--dists/engine-data/mort.datbin75822 -> 76151 bytes
-rw-r--r--engines/agi/detection_tables.h1
-rw-r--r--engines/agos/agos.h24
-rw-r--r--engines/agos/saveload.cpp99
-rw-r--r--engines/agos/script_pn.cpp14
-rw-r--r--engines/drascula/actors.cpp16
-rw-r--r--engines/drascula/animation.cpp18
-rw-r--r--engines/drascula/console.cpp2
-rw-r--r--engines/drascula/converse.cpp16
-rw-r--r--engines/drascula/drascula.cpp93
-rw-r--r--engines/drascula/drascula.h14
-rw-r--r--engines/drascula/graphics.cpp14
-rw-r--r--engines/drascula/interface.cpp8
-rw-r--r--engines/drascula/objects.cpp74
-rw-r--r--engines/drascula/rooms.cpp60
-rw-r--r--engines/drascula/saveload.cpp24
-rw-r--r--engines/drascula/sound.cpp16
-rw-r--r--engines/drascula/talk.cpp54
-rw-r--r--engines/mohawk/myst.cpp1
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp1
-rw-r--r--engines/mortevielle/actions.cpp147
-rw-r--r--engines/mortevielle/detection.cpp8
-rw-r--r--engines/mortevielle/detection_tables.h27
-rw-r--r--engines/mortevielle/dialogs.cpp61
-rw-r--r--engines/mortevielle/dialogs.h4
-rw-r--r--engines/mortevielle/graphics.cpp21
-rw-r--r--engines/mortevielle/menu.cpp473
-rw-r--r--engines/mortevielle/menu.h77
-rw-r--r--engines/mortevielle/mortevielle.cpp25
-rw-r--r--engines/mortevielle/mortevielle.h27
-rw-r--r--engines/mortevielle/mouse.cpp22
-rw-r--r--engines/mortevielle/outtext.cpp26
-rw-r--r--engines/mortevielle/saveload.cpp28
-rw-r--r--engines/mortevielle/saveload.h2
-rw-r--r--engines/mortevielle/sound.cpp4
-rw-r--r--engines/mortevielle/utils.cpp371
-rw-r--r--engines/sci/detection.cpp5
-rw-r--r--engines/sci/detection_tables.h8
-rw-r--r--engines/sci/engine/features.cpp6
-rw-r--r--engines/sci/engine/script_patches.cpp24
-rw-r--r--engines/sci/engine/vm_types.cpp32
-rw-r--r--engines/sci/engine/vm_types.h2
-rw-r--r--engines/sci/engine/workarounds.cpp9
-rw-r--r--engines/sci/graphics/picture.cpp16
-rw-r--r--engines/sci/sci.h1
-rw-r--r--engines/scumm/actor.cpp2
-rw-r--r--engines/scumm/detection_tables.h7
-rw-r--r--engines/scumm/gfx.cpp13
-rw-r--r--engines/scumm/he/script_v100he.cpp2
-rw-r--r--engines/scumm/he/script_v70he.cpp2
-rw-r--r--engines/scumm/he/script_v72he.cpp4
-rw-r--r--engines/scumm/insane/insane_enemy.cpp1
-rw-r--r--engines/scumm/script_v6.cpp2
-rw-r--r--engines/scumm/scumm-md5.h3
-rw-r--r--engines/scumm/scumm.h1
-rw-r--r--engines/scumm/vars.cpp6
-rw-r--r--engines/testbed/graphics.cpp22
-rw-r--r--engines/tinsel/detection_tables.h20
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.cpp1
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.h2
-rw-r--r--engines/tsage/converse.cpp15
-rw-r--r--engines/tsage/core.cpp16
-rw-r--r--engines/tsage/globals.cpp37
-rw-r--r--engines/tsage/globals.h14
-rw-r--r--engines/tsage/graphics.cpp18
-rw-r--r--engines/tsage/ringworld2/ringworld2_dialogs.cpp10
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp62
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h7
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp522
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.h68
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.cpp1008
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes1.h62
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes2.cpp81
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes3.cpp42
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.cpp113
-rw-r--r--engines/tsage/ringworld2/ringworld2_speakers.h16
-rw-r--r--engines/tsage/staticres.cpp6
-rw-r--r--engines/tsage/staticres.h6
-rw-r--r--engines/tsage/user_interface.cpp13
-rw-r--r--engines/tsage/user_interface.h2
-rw-r--r--engines/wintermute/base/font/base_font_truetype.cpp4
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp21
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp90
-rw-r--r--engines/wintermute/base/gfx/osystem/base_surface_osystem.h4
-rw-r--r--engines/wintermute/base/gfx/osystem/render_ticket.cpp17
-rw-r--r--engines/wintermute/detection_tables.h86
-rw-r--r--engines/wintermute/graphics/transparent_surface.cpp173
-rw-r--r--engines/wintermute/graphics/transparent_surface.h13
-rw-r--r--engines/wintermute/utils/string_util.cpp23
-rw-r--r--engines/wintermute/wintermute.cpp2
-rw-r--r--graphics/VectorRenderer.h16
-rw-r--r--graphics/VectorRendererSpec.cpp777
-rw-r--r--graphics/VectorRendererSpec.h26
-rw-r--r--graphics/font.cpp2
-rw-r--r--gui/ThemeEngine.cpp23
-rw-r--r--gui/ThemeEngine.h9
-rw-r--r--gui/about.cpp7
-rw-r--r--gui/credits.h9
-rw-r--r--gui/object.cpp2
-rw-r--r--gui/object.h7
-rw-r--r--gui/themes/default.inc2892
-rw-r--r--gui/themes/scummclassic.zipbin110000 -> 113348 bytes
-rw-r--r--gui/themes/scummmodern.zipbin1485763 -> 1489429 bytes
-rw-r--r--gui/themes/scummmodern/scummmodern_gfx.stx42
-rwxr-xr-xgui/themes/scummtheme.py17
-rw-r--r--gui/widgets/editable.cpp2
-rw-r--r--gui/widgets/edittext.cpp8
-rw-r--r--video/avi_decoder.cpp327
-rw-r--r--video/avi_decoder.h20
-rw-r--r--video/video_decoder.cpp45
-rw-r--r--video/video_decoder.h23
163 files changed, 6002 insertions, 5660 deletions
diff --git a/AUTHORS b/AUTHORS
index 0a2d2c5fe1..fd5407b460 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -142,6 +142,14 @@ ScummVM Team
Eugene Sandulenko
David Turner
+ Mortevielle:
+ Arnaud Boutonne
+ Paul Gilbert
+
+ Neverhood:
+ Benjamin Haisch
+ Filippos Karapetis
+
Parallaction:
peres
diff --git a/audio/softsynth/mt32/AReverbModel.cpp b/audio/softsynth/mt32/AReverbModel.cpp
deleted file mode 100644
index 1d63832157..0000000000
--- a/audio/softsynth/mt32/AReverbModel.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mt32emu.h"
-
-#if MT32EMU_USE_REVERBMODEL == 1
-
-#include "AReverbModel.h"
-
-// Analysing of state of reverb RAM address lines gives exact sizes of the buffers of filters used. This also indicates that
-// the reverb model implemented in the real devices consists of three series allpass filters preceded by a non-feedback comb (or a delay with a LPF)
-// and followed by three parallel comb filters
-
-namespace MT32Emu {
-
-// Because LA-32 chip makes it's output available to process by the Boss chip with a significant delay,
-// the Boss chip puts to the buffer the LA32 dry output when it is ready and performs processing of the _previously_ latched data.
-// Of course, the right way would be to use a dedicated variable for this, but our reverb model is way higher level,
-// so we can simply increase the input buffer size.
-static const Bit32u PROCESS_DELAY = 1;
-
-// Default reverb settings for modes 0-2. These correspond to CM-32L / LAPC-I "new" reverb settings. MT-32 reverb is a bit different.
-// Found by tracing reverb RAM data lines (thanks go to Lord_Nightmare & balrog).
-
-static const Bit32u NUM_ALLPASSES = 3;
-static const Bit32u NUM_COMBS = 4; // Well, actually there are 3 comb filters, but the entrance LPF + delay can be perfectly processed via a comb here.
-
-static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78};
-static const Bit32u MODE_0_COMBS[] = {705 + PROCESS_DELAY, 2349, 2839, 3632};
-static const Bit32u MODE_0_OUTL[] = {2349, 141, 1960};
-static const Bit32u MODE_0_OUTR[] = {1174, 1570, 145};
-static const Bit32u MODE_0_COMB_FACTOR[] = {0x3C, 0x60, 0x60, 0x60};
-static const Bit32u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
-static const Bit32u MODE_0_LEVELS[] = {10*1, 10*3, 10*5, 10*7, 11*9, 11*12, 11*15, 13*15};
-static const Bit32u MODE_0_LPF_AMP = 6;
-
-static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176};
-static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519};
-static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518};
-static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274};
-static const Bit32u MODE_1_COMB_FACTOR[] = {0x30, 0x60, 0x60, 0x60};
-static const Bit32u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
-static const Bit32u MODE_1_LEVELS[] = {10*1, 10*3, 11*5, 11*7, 11*9, 11*12, 11*15, 14*15};
-static const Bit32u MODE_1_LPF_AMP = 6;
-
-static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157};
-static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539};
-static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769};
-static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1};
-static const Bit32u MODE_2_COMB_FACTOR[] = {0, 0x20, 0x20, 0x20};
-static const Bit32u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0,
- 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0,
- 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0};
-static const Bit32u MODE_2_LEVELS[] = {10*1, 10*3, 11*5, 11*7, 11*9, 11*12, 12*15, 14*15};
-static const Bit32u MODE_2_LPF_AMP = 8;
-
-static const AReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_ALLPASSES, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_LEVELS, MODE_0_LPF_AMP};
-static const AReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_ALLPASSES, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_LEVELS, MODE_1_LPF_AMP};
-static const AReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_ALLPASSES, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_LEVELS, MODE_2_LPF_AMP};
-
-static const AReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_0_SETTINGS};
-
-RingBuffer::RingBuffer(const Bit32u newsize) : size(newsize), index(0) {
- buffer = new float[size];
-}
-
-RingBuffer::~RingBuffer() {
- delete[] buffer;
- buffer = NULL;
-}
-
-float RingBuffer::next() {
- if (++index >= size) {
- index = 0;
- }
- return buffer[index];
-}
-
-bool RingBuffer::isEmpty() const {
- if (buffer == NULL) return true;
-
- float *buf = buffer;
- float max = 0.001f;
- for (Bit32u i = 0; i < size; i++) {
- if ((*buf < -max) || (*buf > max)) return false;
- buf++;
- }
- return true;
-}
-
-void RingBuffer::mute() {
- float *buf = buffer;
- for (Bit32u i = 0; i < size; i++) {
- *buf++ = 0;
- }
-}
-
-AllpassFilter::AllpassFilter(const Bit32u useSize) : RingBuffer(useSize) {}
-
-float AllpassFilter::process(const float in) {
- // This model corresponds to the allpass filter implementation of the real CM-32L device
- // found from sample analysis
-
- const float bufferOut = next();
-
- // store input - feedback / 2
- buffer[index] = in - 0.5f * bufferOut;
-
- // return buffer output + feedforward / 2
- return bufferOut + 0.5f * buffer[index];
-}
-
-CombFilter::CombFilter(const Bit32u useSize) : RingBuffer(useSize) {}
-
-void CombFilter::process(const float in) {
- // This model corresponds to the comb filter implementation of the real CM-32L device
- // found from sample analysis
-
- // the previously stored value
- float last = buffer[index];
-
- // prepare input + feedback
- float filterIn = in + next() * feedbackFactor;
-
- // store input + feedback processed by a low-pass filter
- buffer[index] = filterFactor * last - filterIn;
-}
-
-float CombFilter::getOutputAt(const Bit32u outIndex) const {
- return buffer[(size + index - outIndex) % size];
-}
-
-void CombFilter::setFeedbackFactor(const float useFeedbackFactor) {
- feedbackFactor = useFeedbackFactor;
-}
-
-void CombFilter::setFilterFactor(const float useFilterFactor) {
- filterFactor = useFilterFactor;
-}
-
-AReverbModel::AReverbModel(const ReverbMode mode) : allpasses(NULL), combs(NULL), currentSettings(*REVERB_SETTINGS[mode]) {}
-
-AReverbModel::~AReverbModel() {
- close();
-}
-
-void AReverbModel::open() {
- allpasses = new AllpassFilter*[NUM_ALLPASSES];
- for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
- allpasses[i] = new AllpassFilter(currentSettings.allpassSizes[i]);
- }
- combs = new CombFilter*[NUM_COMBS];
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- combs[i] = new CombFilter(currentSettings.combSizes[i]);
- combs[i]->setFilterFactor(currentSettings.filterFactor[i] / 256.0f);
- }
- lpfAmp = currentSettings.lpfAmp / 16.0f;
- mute();
-}
-
-void AReverbModel::close() {
- if (allpasses != NULL) {
- for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
- if (allpasses[i] != NULL) {
- delete allpasses[i];
- allpasses[i] = NULL;
- }
- }
- delete[] allpasses;
- allpasses = NULL;
- }
- if (combs != NULL) {
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- if (combs[i] != NULL) {
- delete combs[i];
- combs[i] = NULL;
- }
- }
- delete[] combs;
- combs = NULL;
- }
-}
-
-void AReverbModel::mute() {
- if (allpasses == NULL || combs == NULL) return;
- for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
- allpasses[i]->mute();
- }
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- combs[i]->mute();
- }
-}
-
-void AReverbModel::setParameters(Bit8u time, Bit8u level) {
-// FIXME: wetLevel definitely needs ramping when changed
-// Although, most games don't set reverb level during MIDI playback
- if (combs == NULL) return;
- level &= 7;
- time &= 7;
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- combs[i]->setFeedbackFactor(currentSettings.decayTimes[(i << 3) + time] / 256.0f);
- }
- wetLevel = (level == 0 && time == 0) ? 0.0f : 0.5f * lpfAmp * currentSettings.wetLevels[level] / 256.0f;
-}
-
-bool AReverbModel::isActive() const {
- for (Bit32u i = 0; i < NUM_ALLPASSES; i++) {
- if (!allpasses[i]->isEmpty()) return true;
- }
- for (Bit32u i = 0; i < NUM_COMBS; i++) {
- if (!combs[i]->isEmpty()) return true;
- }
- return false;
-}
-
-void AReverbModel::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
- float dry, link, outL1;
-
- for (unsigned long i = 0; i < numSamples; i++) {
- dry = wetLevel * (*inLeft + *inRight);
-
- // Get the last stored sample before processing in order not to loose it
- link = combs[0]->getOutputAt(currentSettings.combSizes[0] - 1);
-
- combs[0]->process(-dry);
-
- link = allpasses[0]->process(link);
- link = allpasses[1]->process(link);
- link = allpasses[2]->process(link);
-
- // If the output position is equal to the comb size, get it now in order not to loose it
- outL1 = 1.5f * combs[1]->getOutputAt(currentSettings.outLPositions[0] - 1);
-
- combs[1]->process(link);
- combs[2]->process(link);
- combs[3]->process(link);
-
- link = outL1 + 1.5f * combs[2]->getOutputAt(currentSettings.outLPositions[1]);
- link += combs[3]->getOutputAt(currentSettings.outLPositions[2]);
- *outLeft = link;
-
- link = 1.5f * combs[1]->getOutputAt(currentSettings.outRPositions[0]);
- link += 1.5f * combs[2]->getOutputAt(currentSettings.outRPositions[1]);
- link += combs[3]->getOutputAt(currentSettings.outRPositions[2]);
- *outRight = link;
-
- inLeft++;
- inRight++;
- outLeft++;
- outRight++;
- }
-}
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/AReverbModel.h b/audio/softsynth/mt32/AReverbModel.h
deleted file mode 100644
index c992478907..0000000000
--- a/audio/softsynth/mt32/AReverbModel.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MT32EMU_A_REVERB_MODEL_H
-#define MT32EMU_A_REVERB_MODEL_H
-
-namespace MT32Emu {
-
-struct AReverbSettings {
- const Bit32u * const allpassSizes;
- const Bit32u * const combSizes;
- const Bit32u * const outLPositions;
- const Bit32u * const outRPositions;
- const Bit32u * const filterFactor;
- const Bit32u * const decayTimes;
- const Bit32u * const wetLevels;
- const Bit32u lpfAmp;
-};
-
-class RingBuffer {
-protected:
- float *buffer;
- const Bit32u size;
- Bit32u index;
-
-public:
- RingBuffer(const Bit32u size);
- virtual ~RingBuffer();
- float next();
- bool isEmpty() const;
- void mute();
-};
-
-class AllpassFilter : public RingBuffer {
-public:
- AllpassFilter(const Bit32u size);
- float process(const float in);
-};
-
-class CombFilter : public RingBuffer {
- float feedbackFactor;
- float filterFactor;
-
-public:
- CombFilter(const Bit32u size);
- void process(const float in);
- float getOutputAt(const Bit32u outIndex) const;
- void setFeedbackFactor(const float useFeedbackFactor);
- void setFilterFactor(const float useFilterFactor);
-};
-
-class AReverbModel : public ReverbModel {
- AllpassFilter **allpasses;
- CombFilter **combs;
-
- const AReverbSettings &currentSettings;
- float lpfAmp;
- float wetLevel;
- void mute();
-
-public:
- AReverbModel(const ReverbMode mode);
- ~AReverbModel();
- void open();
- void close();
- void setParameters(Bit8u time, Bit8u level);
- void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
- bool isActive() const;
-};
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/BReverbModel.cpp b/audio/softsynth/mt32/BReverbModel.cpp
index cc0219b741..c16f7f17da 100644
--- a/audio/softsynth/mt32/BReverbModel.cpp
+++ b/audio/softsynth/mt32/BReverbModel.cpp
@@ -15,10 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+//#include <memory.h>
#include "mt32emu.h"
-
-#if MT32EMU_USE_REVERBMODEL == 2
-
#include "BReverbModel.h"
// Analysing of state of reverb RAM address lines gives exact sizes of the buffers of filters used. This also indicates that
@@ -62,9 +60,9 @@ static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518};
static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274};
static const Bit32u MODE_1_COMB_FACTOR[] = {0x80, 0x60, 0x60, 0x60};
static const Bit32u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
- 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
+ 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98,
+ 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98,
+ 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98};
static const Bit32u MODE_1_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xE0};
static const Bit32u MODE_1_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0};
static const Bit32u MODE_1_LPF_AMP = 0x60;
@@ -103,7 +101,11 @@ static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTING
// This algorithm tries to emulate exactly Boss multiplication operation (at least this is what we see on reverb RAM data lines).
// Also LA32 is suspected to use the similar one to perform PCM interpolation and ring modulation.
-static Bit32s weirdMul(Bit32s a, Bit8u addMask, Bit8u carryMask) {
+static Sample weirdMul(Sample a, Bit8u addMask, Bit8u carryMask) {
+ (void)carryMask;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ return a * addMask / 256.0f;
+#elif MT32EMU_BOSS_REVERB_PRECISE_MODE
Bit8u mask = 0x80;
Bit32s res = 0;
for (int i = 0; i < 8; i++) {
@@ -113,10 +115,13 @@ static Bit32s weirdMul(Bit32s a, Bit8u addMask, Bit8u carryMask) {
mask >>= 1;
}
return res;
+#else
+ return Sample(((Bit32s)a * addMask) >> 8);
+#endif
}
RingBuffer::RingBuffer(Bit32u newsize) : size(newsize), index(0) {
- buffer = new Bit16s[size];
+ buffer = new Sample[size];
}
RingBuffer::~RingBuffer() {
@@ -124,7 +129,7 @@ RingBuffer::~RingBuffer() {
buffer = NULL;
}
-Bit32s RingBuffer::next() {
+Sample RingBuffer::next() {
if (++index >= size) {
index = 0;
}
@@ -134,52 +139,69 @@ Bit32s RingBuffer::next() {
bool RingBuffer::isEmpty() const {
if (buffer == NULL) return true;
- Bit16s *buf = buffer;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ Sample max = 0.001f;
+#else
+ Sample max = 8;
+#endif
+ Sample *buf = buffer;
for (Bit32u i = 0; i < size; i++) {
- if (*buf < -8 || *buf > 8) return false;
+ if (*buf < -max || *buf > max) return false;
buf++;
}
return true;
}
void RingBuffer::mute() {
- Bit16s *buf = buffer;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ Sample *buf = buffer;
for (Bit32u i = 0; i < size; i++) {
*buf++ = 0;
}
+#else
+ memset(buffer, 0, size * sizeof(Sample));
+#endif
}
AllpassFilter::AllpassFilter(const Bit32u useSize) : RingBuffer(useSize) {}
-Bit32s AllpassFilter::process(const Bit32s in) {
+Sample AllpassFilter::process(const Sample in) {
// This model corresponds to the allpass filter implementation of the real CM-32L device
// found from sample analysis
- Bit16s bufferOut = next();
+ const Sample bufferOut = next();
+#if MT32EMU_USE_FLOAT_SAMPLES
+ // store input - feedback / 2
+ buffer[index] = in - 0.5f * bufferOut;
+
+ // return buffer output + feedforward / 2
+ return bufferOut + 0.5f * buffer[index];
+#else
// store input - feedback / 2
buffer[index] = in - (bufferOut >> 1);
// return buffer output + feedforward / 2
return bufferOut + (buffer[index] >> 1);
+#endif
}
CombFilter::CombFilter(const Bit32u useSize, const Bit32u useFilterFactor) : RingBuffer(useSize), filterFactor(useFilterFactor) {}
-void CombFilter::process(const Bit32s in) {
+void CombFilter::process(const Sample in) {
// This model corresponds to the comb filter implementation of the real CM-32L device
// the previously stored value
- Bit32s last = buffer[index];
+ const Sample last = buffer[index];
// prepare input + feedback
- Bit32s filterIn = in + weirdMul(next(), feedbackFactor, 0xF0 /* Maybe 0x80 ? */);
+ const Sample filterIn = in + weirdMul(next(), feedbackFactor, 0xF0 /* Maybe 0x80 ? */);
// store input + feedback processed by a low-pass filter
buffer[index] = weirdMul(last, filterFactor, 0x40) - filterIn;
}
-Bit32s CombFilter::getOutputAt(const Bit32u outIndex) const {
+Sample CombFilter::getOutputAt(const Bit32u outIndex) const {
return buffer[(size + index - outIndex) % size];
}
@@ -190,15 +212,15 @@ void CombFilter::setFeedbackFactor(const Bit32u useFeedbackFactor) {
DelayWithLowPassFilter::DelayWithLowPassFilter(const Bit32u useSize, const Bit32u useFilterFactor, const Bit32u useAmp)
: CombFilter(useSize, useFilterFactor), amp(useAmp) {}
-void DelayWithLowPassFilter::process(const Bit32s in) {
+void DelayWithLowPassFilter::process(const Sample in) {
// the previously stored value
- Bit32s last = buffer[index];
+ const Sample last = buffer[index];
// move to the next index
next();
// low-pass filter process
- Bit32s lpfOut = weirdMul(last, filterFactor, 0xFF) + in;
+ Sample lpfOut = weirdMul(last, filterFactor, 0xFF) + in;
// store lpfOut multiplied by LPF amp factor
buffer[index] = weirdMul(lpfOut, amp, 0xFF);
@@ -206,26 +228,26 @@ void DelayWithLowPassFilter::process(const Bit32s in) {
TapDelayCombFilter::TapDelayCombFilter(const Bit32u useSize, const Bit32u useFilterFactor) : CombFilter(useSize, useFilterFactor) {}
-void TapDelayCombFilter::process(const Bit32s in) {
+void TapDelayCombFilter::process(const Sample in) {
// the previously stored value
- Bit32s last = buffer[index];
+ const Sample last = buffer[index];
// move to the next index
next();
// prepare input + feedback
// Actually, the size of the filter varies with the TIME parameter, the feedback sample is taken from the position just below the right output
- Bit32s filterIn = in + weirdMul(getOutputAt(outR + MODE_3_FEEDBACK_DELAY), feedbackFactor, 0xF0);
+ const Sample filterIn = in + weirdMul(getOutputAt(outR + MODE_3_FEEDBACK_DELAY), feedbackFactor, 0xF0);
// store input + feedback processed by a low-pass filter
buffer[index] = weirdMul(last, filterFactor, 0xF0) - filterIn;
}
-Bit32s TapDelayCombFilter::getLeftOutput() const {
+Sample TapDelayCombFilter::getLeftOutput() const {
return getOutputAt(outL + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY);
}
-Bit32s TapDelayCombFilter::getRightOutput() const {
+Sample TapDelayCombFilter::getRightOutput() const {
return getOutputAt(outR + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY);
}
@@ -327,14 +349,14 @@ bool BReverbModel::isActive() const {
return false;
}
-void BReverbModel::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
- Bit32s dry, link, outL1, outR1;
+void BReverbModel::process(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, unsigned long numSamples) {
+ Sample dry;
- for (unsigned long i = 0; i < numSamples; i++) {
+ while (numSamples > 0) {
if (tapDelayMode) {
- dry = Bit32s(*inLeft * 8192.0f) + Bit32s(*inRight * 8192.0f);
+ dry = *inLeft + *inRight;
} else {
- dry = Bit32s(*inLeft * 8192.0f) / 2 + Bit32s(*inRight * 8192.0f) / 2;
+ dry = *inLeft / 2 + *inRight / 2;
}
// Looks like dryAmp doesn't change in MT-32 but it does in CM-32L / LAPC-I
@@ -343,44 +365,53 @@ void BReverbModel::process(const float *inLeft, const float *inRight, float *out
if (tapDelayMode) {
TapDelayCombFilter *comb = static_cast<TapDelayCombFilter *> (*combs);
comb->process(dry);
- *outLeft = weirdMul(comb->getLeftOutput(), wetLevel, 0xFF) / 8192.0f;
- *outRight = weirdMul(comb->getRightOutput(), wetLevel, 0xFF) / 8192.0f;
+ *outLeft = weirdMul(comb->getLeftOutput(), wetLevel, 0xFF);
+ *outRight = weirdMul(comb->getRightOutput(), wetLevel, 0xFF);
} else {
- // Get the last stored sample before processing in order not to loose it
- link = combs[0]->getOutputAt(currentSettings.combSizes[0] - 1);
+ // If the output position is equal to the comb size, get it now in order not to loose it
+ Sample link = combs[0]->getOutputAt(currentSettings.combSizes[0] - 1);
// Entrance LPF. Note, comb.process() differs a bit here.
combs[0]->process(dry);
+#if !MT32EMU_USE_FLOAT_SAMPLES
// This introduces reverb noise which actually makes output from the real Boss chip nondeterministic
link = link - 1;
+#endif
link = allpasses[0]->process(link);
link = allpasses[1]->process(link);
link = allpasses[2]->process(link);
// If the output position is equal to the comb size, get it now in order not to loose it
- outL1 = combs[1]->getOutputAt(currentSettings.outLPositions[0] - 1);
- outL1 += outL1 >> 1;
+ Sample outL1 = combs[1]->getOutputAt(currentSettings.outLPositions[0] - 1);
combs[1]->process(link);
combs[2]->process(link);
combs[3]->process(link);
- link = combs[2]->getOutputAt(currentSettings.outLPositions[1]);
- link += link >> 1;
- link += outL1;
- link += combs[3]->getOutputAt(currentSettings.outLPositions[2]);
- *outLeft = weirdMul(link, wetLevel, 0xFF) / 8192.0f;
+ Sample outL2 = combs[2]->getOutputAt(currentSettings.outLPositions[1]);
+ Sample outL3 = combs[3]->getOutputAt(currentSettings.outLPositions[2]);
+ Sample outR1 = combs[1]->getOutputAt(currentSettings.outRPositions[0]);
+ Sample outR2 = combs[2]->getOutputAt(currentSettings.outRPositions[1]);
+ Sample outR3 = combs[3]->getOutputAt(currentSettings.outRPositions[2]);
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+ *outLeft = 1.5f * (outL1 + outL2) + outL3;
+ *outRight = 1.5f * (outR1 + outR2) + outR3;
+#else
+ outL1 += outL1 >> 1;
+ outL2 += outL2 >> 1;
+ *outLeft = outL1 + outL2 + outL3;
- outR1 = combs[1]->getOutputAt(currentSettings.outRPositions[0]);
outR1 += outR1 >> 1;
- link = combs[2]->getOutputAt(currentSettings.outRPositions[1]);
- link += link >> 1;
- link += outR1;
- link += combs[3]->getOutputAt(currentSettings.outRPositions[2]);
- *outRight = weirdMul(link, wetLevel, 0xFF) / 8192.0f;
+ outR2 += outR2 >> 1;
+ *outRight = outR1 + outR2 + outR3;
+#endif
+ *outLeft = weirdMul(*outLeft, wetLevel, 0xFF);
+ *outRight = weirdMul(*outRight, wetLevel, 0xFF);
}
+ numSamples--;
inLeft++;
inRight++;
outLeft++;
@@ -389,5 +420,3 @@ void BReverbModel::process(const float *inLeft, const float *inRight, float *out
}
}
-
-#endif
diff --git a/audio/softsynth/mt32/BReverbModel.h b/audio/softsynth/mt32/BReverbModel.h
index d6fcb73c13..7cf431db0d 100644
--- a/audio/softsynth/mt32/BReverbModel.h
+++ b/audio/softsynth/mt32/BReverbModel.h
@@ -36,14 +36,14 @@ struct BReverbSettings {
class RingBuffer {
protected:
- Bit16s *buffer;
+ Sample *buffer;
const Bit32u size;
Bit32u index;
public:
RingBuffer(const Bit32u size);
virtual ~RingBuffer();
- Bit32s next();
+ Sample next();
bool isEmpty() const;
void mute();
};
@@ -51,7 +51,7 @@ public:
class AllpassFilter : public RingBuffer {
public:
AllpassFilter(const Bit32u size);
- Bit32s process(const Bit32s in);
+ Sample process(const Sample in);
};
class CombFilter : public RingBuffer {
@@ -61,8 +61,8 @@ protected:
public:
CombFilter(const Bit32u size, const Bit32u useFilterFactor);
- virtual void process(const Bit32s in); // Actually, no need to make it virtual, but for sure
- Bit32s getOutputAt(const Bit32u outIndex) const;
+ virtual void process(const Sample in);
+ Sample getOutputAt(const Bit32u outIndex) const;
void setFeedbackFactor(const Bit32u useFeedbackFactor);
};
@@ -71,7 +71,7 @@ class DelayWithLowPassFilter : public CombFilter {
public:
DelayWithLowPassFilter(const Bit32u useSize, const Bit32u useFilterFactor, const Bit32u useAmp);
- void process(const Bit32s in);
+ void process(const Sample in);
void setFeedbackFactor(const Bit32u) {}
};
@@ -81,13 +81,13 @@ class TapDelayCombFilter : public CombFilter {
public:
TapDelayCombFilter(const Bit32u useSize, const Bit32u useFilterFactor);
- void process(const Bit32s in);
- Bit32s getLeftOutput() const;
- Bit32s getRightOutput() const;
+ void process(const Sample in);
+ Sample getLeftOutput() const;
+ Sample getRightOutput() const;
void setOutputPositions(const Bit32u useOutL, const Bit32u useOutR);
};
-class BReverbModel : public ReverbModel {
+class BReverbModel {
AllpassFilter **allpasses;
CombFilter **combs;
@@ -100,10 +100,12 @@ class BReverbModel : public ReverbModel {
public:
BReverbModel(const ReverbMode mode);
~BReverbModel();
+ // After construction or a close(), open() must be called at least once before any other call (with the exception of close()).
void open();
+ // May be called multiple times without an open() in between.
void close();
void setParameters(Bit8u time, Bit8u level);
- void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
+ void process(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, unsigned long numSamples);
bool isActive() const;
};
diff --git a/audio/softsynth/mt32/DelayReverb.cpp b/audio/softsynth/mt32/DelayReverb.cpp
deleted file mode 100644
index d80c98acbc..0000000000
--- a/audio/softsynth/mt32/DelayReverb.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-//#include <cmath>
-//#include <cstring>
-#include "mt32emu.h"
-#include "DelayReverb.h"
-
-namespace MT32Emu {
-
-// CONFIRMED: The values below are found via analysis of digital samples and tracing reverb RAM address / data lines. Checked with all time and level combinations.
-// Obviously:
-// rightDelay = (leftDelay - 2) * 2 + 2
-// echoDelay = rightDelay - 1
-// Leaving these separate in case it's useful for work on other reverb modes...
-static const Bit32u REVERB_TIMINGS[8][3]= {
- // {leftDelay, rightDelay, feedbackDelay}
- {402, 802, 801},
- {626, 1250, 1249},
- {962, 1922, 1921},
- {1490, 2978, 2977},
- {2258, 4514, 4513},
- {3474, 6946, 6945},
- {5282, 10562, 10561},
- {8002, 16002, 16001}
-};
-
-// Reverb amp is found as dryAmp * wetAmp
-static const Bit32u REVERB_AMP[8] = {0x20*0x18, 0x50*0x18, 0x50*0x28, 0x50*0x40, 0x50*0x60, 0x50*0x80, 0x50*0xA8, 0x50*0xF8};
-static const Bit32u REVERB_FEEDBACK67 = 0x60;
-static const Bit32u REVERB_FEEDBACK = 0x68;
-static const float LPF_VALUE = 0x68 / 256.0f;
-
-static const Bit32u BUFFER_SIZE = 16384;
-
-DelayReverb::DelayReverb() {
- buf = NULL;
- setParameters(0, 0);
-}
-
-DelayReverb::~DelayReverb() {
- delete[] buf;
-}
-
-void DelayReverb::open() {
- if (buf == NULL) {
- delete[] buf;
-
- buf = new float[BUFFER_SIZE];
-
- recalcParameters();
-
- // mute buffer
- bufIx = 0;
- if (buf != NULL) {
- for (unsigned int i = 0; i < BUFFER_SIZE; i++) {
- buf[i] = 0.0f;
- }
- }
- }
-}
-
-void DelayReverb::close() {
- delete[] buf;
- buf = NULL;
-}
-
-// This method will always trigger a flush of the buffer
-void DelayReverb::setParameters(Bit8u newTime, Bit8u newLevel) {
- time = newTime;
- level = newLevel;
- recalcParameters();
-}
-
-void DelayReverb::recalcParameters() {
- // Number of samples between impulse and eventual appearance on the left channel
- delayLeft = REVERB_TIMINGS[time][0];
- // Number of samples between impulse and eventual appearance on the right channel
- delayRight = REVERB_TIMINGS[time][1];
- // Number of samples between a response and that response feeding back/echoing
- delayFeedback = REVERB_TIMINGS[time][2];
-
- if (level < 3 || time < 6) {
- feedback = REVERB_FEEDBACK / 256.0f;
- } else {
- feedback = REVERB_FEEDBACK67 / 256.0f;
- }
-
- // Overall output amp
- amp = (level == 0 && time == 0) ? 0.0f : REVERB_AMP[level] / 65536.0f;
-}
-
-void DelayReverb::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
- if (buf == NULL) return;
-
- for (unsigned int sampleIx = 0; sampleIx < numSamples; sampleIx++) {
- // The ring buffer write index moves backwards; reads are all done with positive offsets.
- Bit32u bufIxPrev = (bufIx + 1) % BUFFER_SIZE;
- Bit32u bufIxLeft = (bufIx + delayLeft) % BUFFER_SIZE;
- Bit32u bufIxRight = (bufIx + delayRight) % BUFFER_SIZE;
- Bit32u bufIxFeedback = (bufIx + delayFeedback) % BUFFER_SIZE;
-
- // Attenuated input samples and feedback response are directly added to the current ring buffer location
- float lpfIn = amp * (inLeft[sampleIx] + inRight[sampleIx]) + feedback * buf[bufIxFeedback];
-
- // Single-pole IIR filter found on real devices
- buf[bufIx] = buf[bufIxPrev] * LPF_VALUE - lpfIn;
-
- outLeft[sampleIx] = buf[bufIxLeft];
- outRight[sampleIx] = buf[bufIxRight];
-
- bufIx = (BUFFER_SIZE + bufIx - 1) % BUFFER_SIZE;
- }
-}
-
-bool DelayReverb::isActive() const {
- if (buf == NULL) return false;
-
- float *b = buf;
- float max = 0.001f;
- for (Bit32u i = 0; i < BUFFER_SIZE; i++) {
- if ((*b < -max) || (*b > max)) return true;
- b++;
- }
- return false;
-}
-
-}
diff --git a/audio/softsynth/mt32/DelayReverb.h b/audio/softsynth/mt32/DelayReverb.h
deleted file mode 100644
index c8003832b5..0000000000
--- a/audio/softsynth/mt32/DelayReverb.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MT32EMU_DELAYREVERB_H
-#define MT32EMU_DELAYREVERB_H
-
-namespace MT32Emu {
-
-class DelayReverb : public ReverbModel {
-private:
- Bit8u time;
- Bit8u level;
-
- Bit32u bufIx;
- float *buf;
-
- Bit32u delayLeft;
- Bit32u delayRight;
- Bit32u delayFeedback;
-
- float amp;
- float feedback;
-
- void recalcParameters();
-
-public:
- DelayReverb();
- ~DelayReverb();
- void open();
- void close();
- void setParameters(Bit8u time, Bit8u level);
- void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
- bool isActive() const;
-};
-}
-#endif
diff --git a/audio/softsynth/mt32/FreeverbModel.cpp b/audio/softsynth/mt32/FreeverbModel.cpp
deleted file mode 100644
index bd9c70b6f4..0000000000
--- a/audio/softsynth/mt32/FreeverbModel.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mt32emu.h"
-#include "FreeverbModel.h"
-
-#include "freeverb.h"
-
-namespace MT32Emu {
-
-FreeverbModel::FreeverbModel(float useScaleTuning, float useFiltVal, float useWet, Bit8u useRoom, float useDamp) {
- freeverb = NULL;
- scaleTuning = useScaleTuning;
- filtVal = useFiltVal;
- wet = useWet;
- room = useRoom;
- damp = useDamp;
-}
-
-FreeverbModel::~FreeverbModel() {
- delete freeverb;
-}
-
-void FreeverbModel::open() {
- if (freeverb == NULL) {
- freeverb = new revmodel(scaleTuning);
- }
- freeverb->mute();
-
- // entrance Lowpass filter factor
- freeverb->setfiltval(filtVal);
-
- // decay speed of high frequencies in the wet signal
- freeverb->setdamp(damp);
-}
-
-void FreeverbModel::close() {
- delete freeverb;
- freeverb = NULL;
-}
-
-void FreeverbModel::process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) {
- freeverb->process(inLeft, inRight, outLeft, outRight, numSamples);
-}
-
-void FreeverbModel::setParameters(Bit8u time, Bit8u level) {
- // wet signal level
- // FIXME: need to implement some sort of reverb level ramping
- freeverb->setwet((float)level / 7.0f * wet);
-
- // wet signal decay speed
- static float roomTable[] = {
- 0.25f, 0.37f, 0.54f, 0.71f, 0.78f, 0.86f, 0.93f, 1.00f,
- -1.00f, -0.50f, 0.00f, 0.30f, 0.51f, 0.64f, 0.77f, 0.90f,
- 0.50f, 0.57f, 0.70f, 0.77f, 0.85f, 0.93f, 0.96f, 1.01f};
- freeverb->setroomsize(roomTable[8 * room + time]);
-}
-
-bool FreeverbModel::isActive() const {
- // FIXME: Not bothering to do this properly since we'll be replacing Freeverb soon...
- return false;
-}
-
-}
diff --git a/audio/softsynth/mt32/FreeverbModel.h b/audio/softsynth/mt32/FreeverbModel.h
deleted file mode 100644
index 5ea11f1f40..0000000000
--- a/audio/softsynth/mt32/FreeverbModel.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
- * Copyright (C) 2011, 2012, 2013 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MT32EMU_FREEVERB_MODEL_H
-#define MT32EMU_FREEVERB_MODEL_H
-
-class revmodel;
-
-namespace MT32Emu {
-
-class FreeverbModel : public ReverbModel {
- revmodel *freeverb;
- float scaleTuning;
- float filtVal;
- float wet;
- Bit8u room;
- float damp;
-public:
- FreeverbModel(float useScaleTuning, float useFiltVal, float useWet, Bit8u useRoom, float useDamp);
- ~FreeverbModel();
- void open();
- void close();
- void setParameters(Bit8u time, Bit8u level);
- void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples);
- bool isActive() const;
-};
-
-}
-
-#endif
diff --git a/audio/softsynth/mt32/LegacyWaveGenerator.cpp b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
index 35ca975018..486942b75c 100644
--- a/audio/softsynth/mt32/LegacyWaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
@@ -18,9 +18,7 @@
//#include <cmath>
#include "mt32emu.h"
#include "mmath.h"
-#include "LegacyWaveGenerator.h"
-
-#if MT32EMU_ACCURATE_WG == 1
+#include "LA32FloatWaveGenerator.h"
namespace MT32Emu {
@@ -317,7 +315,7 @@ void LA32PartialPair::generateNextSample(const PairType useMaster, const Bit32u
}
}
-Bit16s LA32PartialPair::nextOutSample() {
+float LA32PartialPair::nextOutSample() {
float outputSample;
if (ringModulated) {
float ringModulatedSample = masterOutputSample * slaveOutputSample;
@@ -325,7 +323,7 @@ Bit16s LA32PartialPair::nextOutSample() {
} else {
outputSample = masterOutputSample + slaveOutputSample;
}
- return Bit16s(outputSample * 8192.0f);
+ return outputSample;
}
void LA32PartialPair::deactivate(const PairType useMaster) {
@@ -343,5 +341,3 @@ bool LA32PartialPair::isActive(const PairType useMaster) const {
}
}
-
-#endif // #if MT32EMU_ACCURATE_WG == 1
diff --git a/audio/softsynth/mt32/LegacyWaveGenerator.h b/audio/softsynth/mt32/LA32FloatWaveGenerator.h
index 81c1b9c713..9046160083 100644
--- a/audio/softsynth/mt32/LegacyWaveGenerator.h
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.h
@@ -15,8 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#if MT32EMU_ACCURATE_WG == 1
-
#ifndef MT32EMU_LA32_WAVE_GENERATOR_H
#define MT32EMU_LA32_WAVE_GENERATOR_H
@@ -130,7 +128,7 @@ public:
void generateNextSample(const PairType master, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff);
// Perform mixing / ring modulation and return the result
- Bit16s nextOutSample();
+ float nextOutSample();
// Deactivate the WG engine
void deactivate(const PairType master);
@@ -142,5 +140,3 @@ public:
} // namespace MT32Emu
#endif // #ifndef MT32EMU_LA32_WAVE_GENERATOR_H
-
-#endif // #if MT32EMU_ACCURATE_WG == 1
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.cpp b/audio/softsynth/mt32/LA32WaveGenerator.cpp
index 80650699fb..9ffc2ca32e 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32WaveGenerator.cpp
@@ -20,7 +20,9 @@
#include "mmath.h"
#include "LA32WaveGenerator.h"
-#if MT32EMU_ACCURATE_WG == 0
+#if MT32EMU_USE_FLOAT_SAMPLES
+#include "LA32FloatWaveGenerator.cpp"
+#else
namespace MT32Emu {
@@ -129,7 +131,8 @@ void LA32WaveGenerator::advancePosition() {
computePositions(highLinearLength, lowLinearLength, resonanceWaveLengthFactor);
// resonancePhase computation hack
- *(int*)&resonancePhase = ((resonanceSinePosition >> 18) + (phase > POSITIVE_FALLING_SINE_SEGMENT ? 2 : 0)) & 3;
+ int *resonancePhaseAlias = (int *)&resonancePhase;
+ *resonancePhaseAlias = ((resonanceSinePosition >> 18) + (phase > POSITIVE_FALLING_SINE_SEGMENT ? 2 : 0)) & 3;
}
void LA32WaveGenerator::generateNextSquareWaveLogSample() {
@@ -415,4 +418,4 @@ bool LA32PartialPair::isActive(const PairType useMaster) const {
}
-#endif // #if MT32EMU_ACCURATE_WG == 0
+#endif // #if MT32EMU_USE_FLOAT_SAMPLES
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.h b/audio/softsynth/mt32/LA32WaveGenerator.h
index 37a4aead85..4bc04c78d3 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.h
+++ b/audio/softsynth/mt32/LA32WaveGenerator.h
@@ -15,7 +15,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#if MT32EMU_ACCURATE_WG == 0
+#if MT32EMU_USE_FLOAT_SAMPLES
+#include "LA32FloatWaveGenerator.h"
+#else
#ifndef MT32EMU_LA32_WAVE_GENERATOR_H
#define MT32EMU_LA32_WAVE_GENERATOR_H
@@ -243,4 +245,4 @@ public:
#endif // #ifndef MT32EMU_LA32_WAVE_GENERATOR_H
-#endif // #if MT32EMU_ACCURATE_WG == 0
+#endif // #if MT32EMU_USE_FLOAT_SAMPLES
diff --git a/audio/softsynth/mt32/Part.cpp b/audio/softsynth/mt32/Part.cpp
index 88404316eb..8a0daf3b38 100644
--- a/audio/softsynth/mt32/Part.cpp
+++ b/audio/softsynth/mt32/Part.cpp
@@ -67,18 +67,12 @@ Part::Part(Synth *useSynth, unsigned int usePartNum) {
pitchBend = 0;
activePartialCount = 0;
memset(patchCache, 0, sizeof(patchCache));
- for (int i = 0; i < MT32EMU_MAX_POLY; i++) {
- freePolys.prepend(new Poly(this));
- }
}
Part::~Part() {
while (!activePolys.isEmpty()) {
delete activePolys.takeFirst();
}
- while (!freePolys.isEmpty()) {
- delete freePolys.takeFirst();
- }
}
void Part::setDataEntryMSB(unsigned char midiDataEntryMSB) {
@@ -431,23 +425,10 @@ void Part::noteOn(unsigned int midiKey, unsigned int velocity) {
playPoly(patchCache, NULL, midiKey, key, velocity);
}
-void Part::abortPoly(Poly *poly) {
- if (poly->startAbort()) {
- while (poly->isActive()) {
- if (!synth->prerender()) {
- synth->printDebug("%s (%s): Ran out of prerender space to abort poly gracefully", name, currentInstr);
- poly->terminate();
- break;
- }
- }
- }
-}
-
bool Part::abortFirstPoly(unsigned int key) {
for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) {
if (poly->getKey() == key) {
- abortPoly(poly);
- return true;
+ return poly->startAbort();
}
}
return false;
@@ -456,8 +437,7 @@ bool Part::abortFirstPoly(unsigned int key) {
bool Part::abortFirstPoly(PolyState polyState) {
for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) {
if (poly->getState() == polyState) {
- abortPoly(poly);
- return true;
+ return poly->startAbort();
}
}
return false;
@@ -474,8 +454,7 @@ bool Part::abortFirstPoly() {
if (activePolys.isEmpty()) {
return false;
}
- abortPoly(activePolys.getFirst());
- return true;
+ return activePolys.getFirst()->startAbort();
}
void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity) {
@@ -489,6 +468,7 @@ void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhyt
if ((patchTemp->patch.assignMode & 2) == 0) {
// Single-assign mode
abortFirstPoly(key);
+ if (synth->isAbortingPoly()) return;
}
if (!synth->partialManager->freePartials(needPartials, partNum)) {
@@ -498,12 +478,13 @@ void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhyt
#endif
return;
}
+ if (synth->isAbortingPoly()) return;
- if (freePolys.isEmpty()) {
+ Poly *poly = synth->partialManager->assignPolyToPart(this);
+ if (poly == NULL) {
synth->printDebug("%s (%s): No free poly to play key %d (velocity %d)", name, currentInstr, midiKey, velocity);
return;
}
- Poly *poly = freePolys.takeFirst();
if (patchTemp->patch.assignMode & 1) {
// Priority to data first received
activePolys.prepend(poly);
@@ -596,6 +577,10 @@ unsigned int Part::getActivePartialCount() const {
return activePartialCount;
}
+const Poly *Part::getFirstActivePoly() const {
+ return activePolys.getFirst();
+}
+
unsigned int Part::getActiveNonReleasingPartialCount() const {
unsigned int activeNonReleasingPartialCount = 0;
for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) {
@@ -606,11 +591,15 @@ unsigned int Part::getActiveNonReleasingPartialCount() const {
return activeNonReleasingPartialCount;
}
+Synth *Part::getSynth() const {
+ return synth;
+}
+
void Part::partialDeactivated(Poly *poly) {
activePartialCount--;
if (!poly->isActive()) {
activePolys.remove(poly);
- freePolys.prepend(poly);
+ synth->partialManager->polyFreed(poly);
synth->polyStateChanged(partNum);
}
}
diff --git a/audio/softsynth/mt32/Part.h b/audio/softsynth/mt32/Part.h
index b6585880fe..2aeeaf5bd7 100644
--- a/audio/softsynth/mt32/Part.h
+++ b/audio/softsynth/mt32/Part.h
@@ -51,13 +51,11 @@ private:
unsigned int activePartialCount;
PatchCache patchCache[4];
- PolyList freePolys;
PolyList activePolys;
void setPatch(const PatchParam *patch);
unsigned int midiKeyToKey(unsigned int midiKey);
- void abortPoly(Poly *poly);
bool abortFirstPoly(unsigned int key);
protected:
@@ -110,8 +108,10 @@ public:
virtual void setTimbre(TimbreParam *timbre);
virtual unsigned int getAbsTimbreNum() const;
const char *getCurrentInstr() const;
+ const Poly *getFirstActivePoly() const;
unsigned int getActivePartialCount() const;
unsigned int getActiveNonReleasingPartialCount() const;
+ Synth *getSynth() const;
const MemParams::PatchTemp *getPatchTemp() const;
diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp
index b80a028515..c7848f02d8 100644
--- a/audio/softsynth/mt32/Partial.cpp
+++ b/audio/softsynth/mt32/Partial.cpp
@@ -131,6 +131,7 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us
}
// FIXME: Sample analysis suggests that the use of panVal is linear, but there are some some quirks that still need to be resolved.
+ // FIXME: I suppose this should be panVal / 8 and undoubtly integer, clarify ASAP
stereoVolume.leftVol = panVal / 7.0f;
stereoVolume.rightVol = 1.0f - stereoVolume.leftVol;
@@ -198,9 +199,6 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us
if (!hasRingModulatingSlave()) {
la32Pair.deactivate(LA32PartialPair::SLAVE);
}
- // Temporary integration hack
- stereoVolume.leftVol /= 8192.0f;
- stereoVolume.rightVol /= 8192.0f;
}
Bit32u Partial::getAmpValue() {
@@ -232,7 +230,7 @@ Bit32u Partial::getCutoffValue() {
return (tvf->getBaseCutoff() << 18) + cutoffModifierRampVal;
}
-unsigned long Partial::generateSamples(Bit16s *partialBuf, unsigned long length) {
+unsigned long Partial::generateSamples(Sample *partialBuf, unsigned long length) {
if (!isActive() || alreadyOutputed) {
return 0;
}
@@ -258,7 +256,7 @@ unsigned long Partial::generateSamples(Bit16s *partialBuf, unsigned long length)
}
}
}
- *partialBuf++ = la32Pair.nextOutSample();
+ *(partialBuf++) = la32Pair.nextOutSample();
}
unsigned long renderedSamples = sampleNum;
sampleNum = 0;
@@ -288,7 +286,18 @@ Synth *Partial::getSynth() const {
return synth;
}
-bool Partial::produceOutput(float *leftBuf, float *rightBuf, unsigned long length) {
+TVA *Partial::getTVA() const {
+ return tva;
+}
+
+void Partial::backupCache(const PatchCache &cache) {
+ if (patchCache == &cache) {
+ cachebackup = cache;
+ patchCache = &cachebackup;
+ }
+}
+
+bool Partial::produceOutput(Sample *leftBuf, Sample *rightBuf, unsigned long length) {
if (!isActive() || alreadyOutputed || isRingModulatingSlave()) {
return false;
}
@@ -296,14 +305,18 @@ bool Partial::produceOutput(float *leftBuf, float *rightBuf, unsigned long lengt
synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", debugPartialNum);
return false;
}
- unsigned long numGenerated = generateSamples(myBuffer, length);
+ Sample buffer[MAX_SAMPLES_PER_RUN];
+ unsigned long numGenerated = generateSamples(buffer, length);
for (unsigned int i = 0; i < numGenerated; i++) {
- *leftBuf++ = myBuffer[i] * stereoVolume.leftVol;
- *rightBuf++ = myBuffer[i] * stereoVolume.rightVol;
- }
- for (; numGenerated < length; numGenerated++) {
- *leftBuf++ = 0.0f;
- *rightBuf++ = 0.0f;
+#if MT32EMU_USE_FLOAT_SAMPLES
+ *(leftBuf++) += buffer[i] * stereoVolume.leftVol;
+ *(rightBuf++) += buffer[i] * stereoVolume.rightVol;
+#else
+ *leftBuf = Synth::clipBit16s((Bit32s)*leftBuf + Bit32s(buffer[i] * stereoVolume.leftVol));
+ *rightBuf = Synth::clipBit16s((Bit32s)*rightBuf + Bit32s(buffer[i] * stereoVolume.rightVol));
+ leftBuf++;
+ rightBuf++;
+#endif
}
return true;
}
diff --git a/audio/softsynth/mt32/Partial.h b/audio/softsynth/mt32/Partial.h
index 21b1bfe376..358cb9d2d9 100644
--- a/audio/softsynth/mt32/Partial.h
+++ b/audio/softsynth/mt32/Partial.h
@@ -44,8 +44,6 @@ private:
int structurePosition; // 0 or 1 of a structure pair
StereoVolume stereoVolume;
- Bit16s myBuffer[MAX_SAMPLES_PER_RUN];
-
// Only used for PCM partials
int pcmNum;
// FIXME: Give this a better name (e.g. pcmWaveInfo)
@@ -56,6 +54,11 @@ private:
int pulseWidthVal;
Poly *poly;
+ Partial *pair;
+
+ TVA *tva;
+ TVP *tvp;
+ TVF *tvf;
LA32Ramp ampRamp;
LA32Ramp cutoffModifierRamp;
@@ -63,18 +66,13 @@ private:
// TODO: This should be owned by PartialPair
LA32PartialPair la32Pair;
+ const PatchCache *patchCache;
+ PatchCache cachebackup;
+
Bit32u getAmpValue();
Bit32u getCutoffValue();
public:
- const PatchCache *patchCache;
- TVA *tva;
- TVP *tvp;
- TVF *tvf;
-
- PatchCache cachebackup;
-
- Partial *pair;
bool alreadyOutputed;
Partial(Synth *synth, int debugPartialNum);
@@ -97,14 +95,17 @@ public:
bool isPCM() const;
const ControlROMPCMStruct *getControlROMPCMStruct() const;
Synth *getSynth() const;
+ TVA *getTVA() const;
+
+ void backupCache(const PatchCache &cache);
// Returns true only if data written to buffer
// This function (unlike the one below it) returns processed stereo samples
// made from combining this single partial with its pair, if it has one.
- bool produceOutput(float *leftBuf, float *rightBuf, unsigned long length);
+ bool produceOutput(Sample *leftBuf, Sample *rightBuf, unsigned long length);
// This function writes mono sample output to the provided buffer, and returns the number of samples written
- unsigned long generateSamples(Bit16s *partialBuf, unsigned long length);
+ unsigned long generateSamples(Sample *partialBuf, unsigned long length);
};
}
diff --git a/audio/softsynth/mt32/PartialManager.cpp b/audio/softsynth/mt32/PartialManager.cpp
index 436e7a353e..905b5b8cf3 100644
--- a/audio/softsynth/mt32/PartialManager.cpp
+++ b/audio/softsynth/mt32/PartialManager.cpp
@@ -25,19 +25,26 @@ namespace MT32Emu {
PartialManager::PartialManager(Synth *useSynth, Part **useParts) {
synth = useSynth;
parts = useParts;
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ partialTable = new Partial *[synth->getPartialCount()];
+ freePolys = new Poly *[synth->getPartialCount()];
+ firstFreePolyIndex = 0;
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
partialTable[i] = new Partial(synth, i);
+ freePolys[i] = new Poly();
}
}
PartialManager::~PartialManager(void) {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
delete partialTable[i];
+ if (freePolys[i] != NULL) delete freePolys[i];
}
+ delete[] partialTable;
+ delete[] freePolys;
}
void PartialManager::clearAlreadyOutputed() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
partialTable[i]->alreadyOutputed = false;
}
}
@@ -46,12 +53,12 @@ bool PartialManager::shouldReverb(int i) {
return partialTable[i]->shouldReverb();
}
-bool PartialManager::produceOutput(int i, float *leftBuf, float *rightBuf, Bit32u bufferLength) {
+bool PartialManager::produceOutput(int i, Sample *leftBuf, Sample *rightBuf, Bit32u bufferLength) {
return partialTable[i]->produceOutput(leftBuf, rightBuf, bufferLength);
}
void PartialManager::deactivateAll() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
partialTable[i]->deactivate();
}
}
@@ -69,7 +76,7 @@ Partial *PartialManager::allocPartial(int partNum) {
Partial *outPartial = NULL;
// Get the first inactive partial
- for (int partialNum = 0; partialNum < MT32EMU_MAX_PARTIALS; partialNum++) {
+ for (unsigned int partialNum = 0; partialNum < synth->getPartialCount(); partialNum++) {
if (!partialTable[partialNum]->isActive()) {
outPartial = partialTable[partialNum];
break;
@@ -83,7 +90,7 @@ Partial *PartialManager::allocPartial(int partNum) {
unsigned int PartialManager::getFreePartialCount(void) {
int count = 0;
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
if (!partialTable[i]->isActive()) {
count++;
}
@@ -94,7 +101,7 @@ unsigned int PartialManager::getFreePartialCount(void) {
// This function is solely used to gather data for debug output at the moment.
void PartialManager::getPerPartPartialUsage(unsigned int perPartPartialUsage[9]) {
memset(perPartPartialUsage, 0, 9 * sizeof(unsigned int));
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ for (unsigned int i = 0; i < synth->getPartialCount(); i++) {
if (partialTable[i]->isActive()) {
perPartPartialUsage[partialTable[i]->getOwnerPart()]++;
}
@@ -189,7 +196,7 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
break;
}
#endif
- if (getFreePartialCount() >= needed) {
+ if (synth->isAbortingPoly() || getFreePartialCount() >= needed) {
return true;
}
}
@@ -206,7 +213,7 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
if (!abortFirstPolyPreferHeldWhereReserveExceeded(partNum)) {
break;
}
- if (getFreePartialCount() >= needed) {
+ if (synth->isAbortingPoly() || getFreePartialCount() >= needed) {
return true;
}
}
@@ -222,7 +229,7 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
if (!abortFirstPolyPreferHeldWhereReserveExceeded(-1)) {
break;
}
- if (getFreePartialCount() >= needed) {
+ if (synth->isAbortingPoly() || getFreePartialCount() >= needed) {
return true;
}
}
@@ -233,7 +240,7 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
if (!parts[partNum]->abortFirstPolyPreferHeld()) {
break;
}
- if (getFreePartialCount() >= needed) {
+ if (synth->isAbortingPoly() || getFreePartialCount() >= needed) {
return true;
}
}
@@ -243,10 +250,39 @@ bool PartialManager::freePartials(unsigned int needed, int partNum) {
}
const Partial *PartialManager::getPartial(unsigned int partialNum) const {
- if (partialNum > MT32EMU_MAX_PARTIALS - 1) {
+ if (partialNum > synth->getPartialCount() - 1) {
return NULL;
}
return partialTable[partialNum];
}
+Poly *PartialManager::assignPolyToPart(Part *part) {
+ if (firstFreePolyIndex < synth->getPartialCount()) {
+ Poly *poly = freePolys[firstFreePolyIndex];
+ freePolys[firstFreePolyIndex] = NULL;
+ firstFreePolyIndex++;
+ poly->setPart(part);
+ return poly;
+ }
+ return NULL;
+}
+
+void PartialManager::polyFreed(Poly *poly) {
+ if (0 == firstFreePolyIndex) {
+ synth->printDebug("Cannot return freed poly, currently active polys:\n");
+ for (Bit32u partNum = 0; partNum < 9; partNum++) {
+ const Poly *activePoly = synth->getPart(partNum)->getFirstActivePoly();
+ Bit32u polyCount = 0;
+ while (activePoly != NULL) {
+ activePoly->getNext();
+ polyCount++;
+ }
+ synth->printDebug("Part: %i, active poly count: %i\n", partNum, polyCount);
+ }
+ }
+ poly->setPart(NULL);
+ firstFreePolyIndex--;
+ freePolys[firstFreePolyIndex] = poly;
+}
+
}
diff --git a/audio/softsynth/mt32/PartialManager.h b/audio/softsynth/mt32/PartialManager.h
index a1c9266ea1..229b6e8121 100644
--- a/audio/softsynth/mt32/PartialManager.h
+++ b/audio/softsynth/mt32/PartialManager.h
@@ -24,17 +24,17 @@ class Synth;
class PartialManager {
private:
- Synth *synth; // Only used for sending debug output
+ Synth *synth;
Part **parts;
-
- Partial *partialTable[MT32EMU_MAX_PARTIALS];
+ Poly **freePolys;
+ Partial **partialTable;
Bit8u numReservedPartialsForPart[9];
+ Bit32u firstFreePolyIndex;
bool abortFirstReleasingPolyWhereReserveExceeded(int minPart);
bool abortFirstPolyPreferHeldWhereReserveExceeded(int minPart);
public:
-
PartialManager(Synth *synth, Part **parts);
~PartialManager();
Partial *allocPartial(int partNum);
@@ -43,10 +43,12 @@ public:
bool freePartials(unsigned int needed, int partNum);
unsigned int setReserve(Bit8u *rset);
void deactivateAll();
- bool produceOutput(int i, float *leftBuf, float *rightBuf, Bit32u bufferLength);
+ bool produceOutput(int i, Sample *leftBuf, Sample *rightBuf, Bit32u bufferLength);
bool shouldReverb(int i);
void clearAlreadyOutputed();
const Partial *getPartial(unsigned int partialNum) const;
+ Poly *assignPolyToPart(Part *part);
+ void polyFreed(Poly *poly);
};
}
diff --git a/audio/softsynth/mt32/Poly.cpp b/audio/softsynth/mt32/Poly.cpp
index 46574f8967..1554881270 100644
--- a/audio/softsynth/mt32/Poly.cpp
+++ b/audio/softsynth/mt32/Poly.cpp
@@ -19,8 +19,8 @@
namespace MT32Emu {
-Poly::Poly(Part *usePart) {
- part = usePart;
+Poly::Poly() {
+ part = NULL;
key = 255;
velocity = 255;
sustain = false;
@@ -32,10 +32,21 @@ Poly::Poly(Part *usePart) {
next = NULL;
}
+void Poly::setPart(Part *usePart) {
+ part = usePart;
+}
+
void Poly::reset(unsigned int newKey, unsigned int newVelocity, bool newSustain, Partial **newPartials) {
if (isActive()) {
- // FIXME: Throw out some big ugly debug output with a lot of exclamation marks - we should never get here
- terminate();
+ // This should never happen
+ part->getSynth()->printDebug("Resetting active poly. Active partial count: %i\n", activePartialCount);
+ for (int i = 0; i < 4; i++) {
+ if (partials[i] != NULL && partials[i]->isActive()) {
+ partials[i]->deactivate();
+ activePartialCount--;
+ }
+ }
+ state = POLY_Inactive;
}
key = newKey;
@@ -92,41 +103,24 @@ bool Poly::startDecay() {
}
bool Poly::startAbort() {
- if (state == POLY_Inactive) {
+ if (state == POLY_Inactive || part->getSynth()->isAbortingPoly()) {
return false;
}
for (int t = 0; t < 4; t++) {
Partial *partial = partials[t];
if (partial != NULL) {
partial->startAbort();
+ part->getSynth()->abortingPoly = this;
}
}
return true;
}
-void Poly::terminate() {
- if (state == POLY_Inactive) {
- return;
- }
- for (int t = 0; t < 4; t++) {
- Partial *partial = partials[t];
- if (partial != NULL) {
- partial->deactivate();
- }
- }
- if (state != POLY_Inactive) {
- // FIXME: Throw out lots of debug output - this should never happen
- // (Deactivating the partials above should've made them each call partialDeactivated(), ultimately changing the state to POLY_Inactive)
- state = POLY_Inactive;
- }
-}
-
void Poly::backupCacheToPartials(PatchCache cache[4]) {
for (int partialNum = 0; partialNum < 4; partialNum++) {
Partial *partial = partials[partialNum];
- if (partial != NULL && partial->patchCache == &cache[partialNum]) {
- partial->cachebackup = cache[partialNum];
- partial->patchCache = &partial->cachebackup;
+ if (partial != NULL) {
+ partial->backupCache(cache[partialNum]);
}
}
}
@@ -171,11 +165,14 @@ void Poly::partialDeactivated(Partial *partial) {
}
if (activePartialCount == 0) {
state = POLY_Inactive;
+ if (part->getSynth()->abortingPoly == this) {
+ part->getSynth()->abortingPoly = NULL;
+ }
}
part->partialDeactivated(this);
}
-Poly *Poly::getNext() {
+Poly *Poly::getNext() const {
return next;
}
diff --git a/audio/softsynth/mt32/Poly.h b/audio/softsynth/mt32/Poly.h
index 068cf73d35..33abc35fdf 100644
--- a/audio/softsynth/mt32/Poly.h
+++ b/audio/softsynth/mt32/Poly.h
@@ -44,13 +44,13 @@ private:
Poly *next;
public:
- Poly(Part *part);
+ Poly();
+ void setPart(Part *usePart);
void reset(unsigned int key, unsigned int velocity, bool sustain, Partial **partials);
bool noteOff(bool pedalHeld);
bool stopPedalHold();
bool startDecay();
bool startAbort();
- void terminate();
void backupCacheToPartials(PatchCache cache[4]);
@@ -63,7 +63,7 @@ public:
void partialDeactivated(Partial *partial);
- Poly *getNext();
+ Poly *getNext() const;
void setNext(Poly *poly);
};
diff --git a/audio/softsynth/mt32/Structures.h b/audio/softsynth/mt32/Structures.h
index 43d2d1f226..421e427fc0 100644
--- a/audio/softsynth/mt32/Structures.h
+++ b/audio/softsynth/mt32/Structures.h
@@ -38,6 +38,12 @@ typedef signed short int Bit16s;
typedef unsigned char Bit8u;
typedef signed char Bit8s;
+#if MT32EMU_USE_FLOAT_SAMPLES
+typedef float Sample;
+#else
+typedef Bit16s Sample;
+#endif
+
// The following structures represent the MT-32's memory
// Since sysex allows this memory to be written to in blocks of bytes,
// we keep this packed so that we can copy data into the various
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
index 1e1be06bc9..b76dc58b5f 100644
--- a/audio/softsynth/mt32/Synth.cpp
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -26,15 +26,7 @@
#include "mt32emu.h"
#include "mmath.h"
#include "PartialManager.h"
-
-#if MT32EMU_USE_REVERBMODEL == 1
-#include "AReverbModel.h"
-#elif MT32EMU_USE_REVERBMODEL == 2
#include "BReverbModel.h"
-#else
-#include "FreeverbModel.h"
-#endif
-#include "DelayReverb.h"
namespace MT32Emu {
@@ -50,84 +42,22 @@ static const ControlROMMap ControlROMMaps[7] = {
// (Note that all but CM-32L ROM actually have 86 entries for rhythmTemp)
};
-static inline Bit16s *streamOffset(Bit16s *stream, Bit32u pos) {
- return stream == NULL ? NULL : stream + pos;
-}
+static inline void muteStream(Sample *stream, Bit32u len) {
+ if (stream == NULL) return;
-static inline void clearIfNonNull(Bit16s *stream, Bit32u len) {
- if (stream != NULL) {
- memset(stream, 0, len * sizeof(Bit16s));
- }
-}
-
-static inline void mix(float *target, const float *stream, Bit32u len) {
- while (len--) {
- *target += *stream;
- stream++;
- target++;
- }
-}
-
-static inline void clearFloats(float *leftBuf, float *rightBuf, Bit32u len) {
+#if MT32EMU_USE_FLOAT_SAMPLES
// FIXME: Use memset() where compatibility is guaranteed (if this turns out to be a win)
while (len--) {
- *leftBuf++ = 0.0f;
- *rightBuf++ = 0.0f;
- }
-}
-
-static inline Bit16s clipBit16s(Bit32s a) {
- // Clamp values above 32767 to 32767, and values below -32768 to -32768
- if ((a + 32768) & ~65535) {
- return (a >> 31) ^ 32767;
- }
- return a;
-}
-
-static void floatToBit16s_nice(Bit16s *target, const float *source, Bit32u len, float outputGain) {
- float gain = outputGain * 16384.0f;
- while (len--) {
- // Since we're not shooting for accuracy here, don't worry about the rounding mode.
- *target = clipBit16s((Bit32s)(*source * gain));
- source++;
- target++;
- }
-}
-
-static void floatToBit16s_pure(Bit16s *target, const float *source, Bit32u len, float /*outputGain*/) {
- while (len--) {
- *target = clipBit16s((Bit32s)floor(*source * 8192.0f));
- source++;
- target++;
- }
-}
-
-static void floatToBit16s_reverb(Bit16s *target, const float *source, Bit32u len, float outputGain) {
- float gain = outputGain * 8192.0f;
- while (len--) {
- *target = clipBit16s((Bit32s)floor(*source * gain));
- source++;
- target++;
- }
-}
-
-static void floatToBit16s_generation1(Bit16s *target, const float *source, Bit32u len, float outputGain) {
- float gain = outputGain * 8192.0f;
- while (len--) {
- *target = clipBit16s((Bit32s)floor(*source * gain));
- *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE);
- source++;
- target++;
+ *stream++ = 0.0f;
}
+#else
+ memset(stream, 0, len * sizeof(Sample));
+#endif
}
-static void floatToBit16s_generation2(Bit16s *target, const float *source, Bit32u len, float outputGain) {
- float gain = outputGain * 8192.0f;
- while (len--) {
- *target = clipBit16s((Bit32s)floor(*source * gain));
- *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE) | ((*target >> 14) & 0x0001);
- source++;
- target++;
+static inline void advanceStreamPosition(Sample *&stream, Bit32u posDelta) {
+ if (stream != NULL) {
+ stream += posDelta;
}
}
@@ -155,28 +85,19 @@ Synth::Synth(ReportHandler *useReportHandler) {
isDefaultReportHandler = false;
}
-#if MT32EMU_USE_REVERBMODEL == 1
- reverbModels[REVERB_MODE_ROOM] = new AReverbModel(REVERB_MODE_ROOM);
- reverbModels[REVERB_MODE_HALL] = new AReverbModel(REVERB_MODE_HALL);
- reverbModels[REVERB_MODE_PLATE] = new AReverbModel(REVERB_MODE_PLATE);
- reverbModels[REVERB_MODE_TAP_DELAY] = new DelayReverb();
-#elif MT32EMU_USE_REVERBMODEL == 2
reverbModels[REVERB_MODE_ROOM] = new BReverbModel(REVERB_MODE_ROOM);
reverbModels[REVERB_MODE_HALL] = new BReverbModel(REVERB_MODE_HALL);
reverbModels[REVERB_MODE_PLATE] = new BReverbModel(REVERB_MODE_PLATE);
reverbModels[REVERB_MODE_TAP_DELAY] = new BReverbModel(REVERB_MODE_TAP_DELAY);
-#else
- reverbModels[REVERB_MODE_ROOM] = new FreeverbModel(0.76f, 0.687770909f, 0.63f, 0, 0.5f);
- reverbModels[REVERB_MODE_HALL] = new FreeverbModel(2.0f, 0.712025098f, 0.86f, 1, 0.5f);
- reverbModels[REVERB_MODE_PLATE] = new FreeverbModel(0.4f, 0.939522749f, 0.38f, 2, 0.05f);
- reverbModels[REVERB_MODE_TAP_DELAY] = new DelayReverb();
-#endif
reverbModel = NULL;
setDACInputMode(DACInputMode_NICE);
+ setMIDIDelayMode(MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY);
setOutputGain(1.0f);
- setReverbOutputGain(0.68f);
+ setReverbOutputGain(1.0f);
partialManager = NULL;
+ midiQueue = NULL;
+ lastReceivedMIDIEventTimestamp = 0;
memset(parts, 0, sizeof(parts));
renderedSampleCount = 0;
}
@@ -197,8 +118,8 @@ void ReportHandler::showLCDMessage(const char *data) {
}
void ReportHandler::printDebug(const char *fmt, va_list list) {
- vprintf(fmt, list);
- printf("\n");
+ vprintf(fmt, list);
+ printf("\n");
}
void Synth::polyStateChanged(int partNum) {
@@ -236,35 +157,37 @@ bool Synth::isReverbOverridden() const {
}
void Synth::setDACInputMode(DACInputMode mode) {
- switch(mode) {
- case DACInputMode_GENERATION1:
- la32FloatToBit16sFunc = floatToBit16s_generation1;
- reverbFloatToBit16sFunc = floatToBit16s_reverb;
- break;
- case DACInputMode_GENERATION2:
- la32FloatToBit16sFunc = floatToBit16s_generation2;
- reverbFloatToBit16sFunc = floatToBit16s_reverb;
- break;
- case DACInputMode_PURE:
- la32FloatToBit16sFunc = floatToBit16s_pure;
- reverbFloatToBit16sFunc = floatToBit16s_pure;
- break;
- case DACInputMode_NICE:
- default:
- la32FloatToBit16sFunc = floatToBit16s_nice;
- reverbFloatToBit16sFunc = floatToBit16s_reverb;
- break;
- }
+ dacInputMode = mode;
+}
+
+DACInputMode Synth::getDACInputMode() const {
+ return dacInputMode;
+}
+
+void Synth::setMIDIDelayMode(MIDIDelayMode mode) {
+ midiDelayMode = mode;
+}
+
+MIDIDelayMode Synth::getMIDIDelayMode() const {
+ return midiDelayMode;
}
void Synth::setOutputGain(float newOutputGain) {
outputGain = newOutputGain;
}
+float Synth::getOutputGain() const {
+ return outputGain;
+}
+
void Synth::setReverbOutputGain(float newReverbOutputGain) {
reverbOutputGain = newReverbOutputGain;
}
+float Synth::getReverbOutputGain() const {
+ return reverbOutputGain;
+}
+
bool Synth::loadControlROM(const ROMImage &controlROMImage) {
if (&controlROMImage == NULL) return false;
Common::File *file = controlROMImage.getFile();
@@ -343,9 +266,9 @@ bool Synth::loadPCMROM(const ROMImage &pcmROMImage) {
bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) {
ControlROMPCMStruct *tps = (ControlROMPCMStruct *)&controlROMData[mapAddress];
for (int i = 0; i < count; i++) {
- size_t rAddr = tps[i].pos * 0x800;
- size_t rLenExp = (tps[i].len & 0x70) >> 4;
- size_t rLen = 0x800 << rLenExp;
+ Bit32u rAddr = tps[i].pos * 0x800;
+ Bit32u rLenExp = (tps[i].len & 0x70) >> 4;
+ Bit32u rLen = 0x800 << rLenExp;
if (rAddr + rLen > pcmROMSize) {
printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen);
return false;
@@ -407,17 +330,18 @@ bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, int count, int startTi
return true;
}
-bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage) {
+bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount) {
if (isOpen) {
return false;
}
- prerenderReadIx = prerenderWriteIx = 0;
+ partialCount = usePartialCount;
+ abortingPoly = NULL;
#if MT32EMU_MONITOR_INIT
printDebug("Initialising Constant Tables");
#endif
#if !MT32EMU_REDUCE_REVERB_MEMORY
- for (int i = 0; i < 4; i++) {
- reverbModels[i]->open(useProp.sampleRate);
+ for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) {
+ reverbModels[i]->open();
}
#endif
@@ -554,6 +478,8 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage) {
// For resetting mt32 mid-execution
mt32default = mt32ram;
+ midiQueue = new MidiEventQueue();
+
isOpen = true;
isEnabled = false;
@@ -568,6 +494,9 @@ void Synth::close() {
return;
}
+ delete midiQueue;
+ midiQueue = NULL;
+
delete partialManager;
partialManager = NULL;
@@ -588,12 +517,78 @@ void Synth::close() {
isOpen = false;
}
-void Synth::playMsg(Bit32u msg) {
+void Synth::flushMIDIQueue() {
+ if (midiQueue != NULL) {
+ for (;;) {
+ const MidiEvent *midiEvent = midiQueue->peekMidiEvent();
+ if (midiEvent == NULL) break;
+ if (midiEvent->sysexData == NULL) {
+ playMsgNow(midiEvent->shortMessageData);
+ } else {
+ playSysexNow(midiEvent->sysexData, midiEvent->sysexLength);
+ }
+ midiQueue->dropMidiEvent();
+ }
+ lastReceivedMIDIEventTimestamp = renderedSampleCount;
+ }
+}
+
+void Synth::setMIDIEventQueueSize(Bit32u useSize) {
+ if (midiQueue != NULL) {
+ flushMIDIQueue();
+ delete midiQueue;
+ midiQueue = new MidiEventQueue(useSize);
+ }
+}
+
+Bit32u Synth::getShortMessageLength(Bit32u msg) {
+ if ((msg & 0xF0) == 0xF0) return 1;
+ // NOTE: This calculation isn't quite correct
+ // as it doesn't consider the running status byte
+ return ((msg & 0xE0) == 0xC0) ? 2 : 3;
+}
+
+Bit32u Synth::addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp) {
+ Bit32u transferTime = Bit32u((double)len * MIDI_DATA_TRANSFER_RATE);
+ // Dealing with wrapping
+ if (Bit32s(timestamp - lastReceivedMIDIEventTimestamp) < 0) {
+ timestamp = lastReceivedMIDIEventTimestamp;
+ }
+ timestamp += transferTime;
+ lastReceivedMIDIEventTimestamp = timestamp;
+ return timestamp;
+}
+
+bool Synth::playMsg(Bit32u msg) {
+ return playMsg(msg, renderedSampleCount);
+}
+
+bool Synth::playMsg(Bit32u msg, Bit32u timestamp) {
+ if (midiQueue == NULL) return false;
+ if (midiDelayMode != MIDIDelayMode_IMMEDIATE) {
+ timestamp = addMIDIInterfaceDelay(getShortMessageLength(msg), timestamp);
+ }
+ return midiQueue->pushShortMessage(msg, timestamp);
+}
+
+bool Synth::playSysex(const Bit8u *sysex, Bit32u len) {
+ return playSysex(sysex, len, renderedSampleCount);
+}
+
+bool Synth::playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp) {
+ if (midiQueue == NULL) return false;
+ if (midiDelayMode == MIDIDelayMode_DELAY_ALL) {
+ timestamp = addMIDIInterfaceDelay(len, timestamp);
+ }
+ return midiQueue->pushSysex(sysex, len, timestamp);
+}
+
+void Synth::playMsgNow(Bit32u msg) {
// FIXME: Implement active sensing
unsigned char code = (unsigned char)((msg & 0x0000F0) >> 4);
unsigned char chan = (unsigned char)(msg & 0x00000F);
- unsigned char note = (unsigned char)((msg & 0x00FF00) >> 8);
- unsigned char velocity = (unsigned char)((msg & 0xFF0000) >> 16);
+ unsigned char note = (unsigned char)((msg & 0x007F00) >> 8);
+ unsigned char velocity = (unsigned char)((msg & 0x7F0000) >> 16);
isEnabled = true;
//printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note);
@@ -606,11 +601,6 @@ void Synth::playMsg(Bit32u msg) {
return;
}
playMsgOnPart(part, code, note, velocity);
-
- // This ensures minimum 1-sample delay between sequential MIDI events
- // Without this, a sequence of NoteOn and immediately succeeding NoteOff messages is always silent
- // Technically, it's also impossible to send events through the MIDI interface faster than about each millisecond
- prerender();
}
void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity) {
@@ -692,7 +682,7 @@ void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char
#if MT32EMU_MONITOR_MIDI > 0
printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity);
#endif
- break;
+ return;
}
break;
@@ -709,13 +699,12 @@ void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char
#if MT32EMU_MONITOR_MIDI > 0
printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity);
#endif
- break;
+ return;
}
-
- //midiOutShortMsg(m_out, msg);
+ reportHandler->onMIDIMessagePlayed();
}
-void Synth::playSysex(const Bit8u *sysex, Bit32u len) {
+void Synth::playSysexNow(const Bit8u *sysex, Bit32u len) {
if (len < 2) {
printDebug("playSysex: Message is too short for sysex (%d bytes)", len);
}
@@ -810,6 +799,7 @@ void Synth::readSysex(unsigned char /*device*/, const Bit8u * /*sysex*/, Bit32u
}
void Synth::writeSysex(unsigned char device, const Bit8u *sysex, Bit32u len) {
+ reportHandler->onMIDIMessagePlayed();
Bit32u addr = (sysex[0] << 16) | (sysex[1] << 8) | (sysex[2]);
addr = MT32EMU_MEMADDR(addr);
sysex += 3;
@@ -1232,7 +1222,7 @@ void Synth::refreshSystemReverbParameters() {
reportHandler->onNewReverbTime(mt32ram.system.reverbTime);
reportHandler->onNewReverbLevel(mt32ram.system.reverbLevel);
- ReverbModel *newReverbModel = reverbModels[mt32ram.system.reverbMode];
+ BReverbModel *newReverbModel = reverbModels[mt32ram.system.reverbMode];
#if MT32EMU_REDUCE_REVERB_MEMORY
if (reverbModel != newReverbModel) {
if (reverbModel != NULL) {
@@ -1308,179 +1298,226 @@ void Synth::reset() {
isEnabled = false;
}
-void Synth::render(Bit16s *stream, Bit32u len) {
- if (!isEnabled) {
- memset(stream, 0, len * sizeof(Bit16s) * 2);
- return;
+MidiEvent::~MidiEvent() {
+ if (sysexData != NULL) {
+ delete[] sysexData;
}
- while (len > 0) {
- Bit32u thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
- renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisLen);
- for (Bit32u i = 0; i < thisLen; i++) {
- stream[0] = clipBit16s((Bit32s)tmpNonReverbLeft[i] + (Bit32s)tmpReverbDryLeft[i] + (Bit32s)tmpReverbWetLeft[i]);
- stream[1] = clipBit16s((Bit32s)tmpNonReverbRight[i] + (Bit32s)tmpReverbDryRight[i] + (Bit32s)tmpReverbWetRight[i]);
- stream += 2;
- }
- len -= thisLen;
+}
+
+void MidiEvent::setShortMessage(Bit32u useShortMessageData, Bit32u useTimestamp) {
+ if (sysexData != NULL) {
+ delete[] sysexData;
}
+ shortMessageData = useShortMessageData;
+ timestamp = useTimestamp;
+ sysexData = NULL;
+ sysexLength = 0;
}
-bool Synth::prerender() {
- int newPrerenderWriteIx = (prerenderWriteIx + 1) % MAX_PRERENDER_SAMPLES;
- if (newPrerenderWriteIx == prerenderReadIx) {
- // The prerender buffer is full
- return false;
+void MidiEvent::setSysex(const Bit8u *useSysexData, Bit32u useSysexLength, Bit32u useTimestamp) {
+ if (sysexData != NULL) {
+ delete[] sysexData;
}
- doRenderStreams(
- prerenderNonReverbLeft + prerenderWriteIx,
- prerenderNonReverbRight + prerenderWriteIx,
- prerenderReverbDryLeft + prerenderWriteIx,
- prerenderReverbDryRight + prerenderWriteIx,
- prerenderReverbWetLeft + prerenderWriteIx,
- prerenderReverbWetRight + prerenderWriteIx,
- 1);
- prerenderWriteIx = newPrerenderWriteIx;
+ shortMessageData = 0;
+ timestamp = useTimestamp;
+ sysexLength = useSysexLength;
+ Bit8u *dstSysexData = new Bit8u[sysexLength];
+ sysexData = dstSysexData;
+ memcpy(dstSysexData, useSysexData, sysexLength);
+}
+
+MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBufferSize(useRingBufferSize) {
+ ringBuffer = new MidiEvent[ringBufferSize];
+ memset(ringBuffer, 0, ringBufferSize * sizeof(MidiEvent));
+ reset();
+}
+
+MidiEventQueue::~MidiEventQueue() {
+ delete[] ringBuffer;
+}
+
+void MidiEventQueue::reset() {
+ startPosition = 0;
+ endPosition = 0;
+}
+
+bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp) {
+ unsigned int newEndPosition = (endPosition + 1) % ringBufferSize;
+ // Is ring buffer full?
+ if (startPosition == newEndPosition) return false;
+ ringBuffer[endPosition].setShortMessage(shortMessageData, timestamp);
+ endPosition = newEndPosition;
return true;
}
-static inline void maybeCopy(Bit16s *out, Bit32u outPos, Bit16s *in, Bit32u inPos, Bit32u len) {
- if (out == NULL) {
- return;
- }
- memcpy(out + outPos, in + inPos, len * sizeof(Bit16s));
+bool MidiEventQueue::pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp) {
+ unsigned int newEndPosition = (endPosition + 1) % ringBufferSize;
+ // Is ring buffer full?
+ if (startPosition == newEndPosition) return false;
+ ringBuffer[endPosition].setSysex(sysexData, sysexLength, timestamp);
+ endPosition = newEndPosition;
+ return true;
}
-void Synth::copyPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u pos, Bit32u len) {
- maybeCopy(nonReverbLeft, pos, prerenderNonReverbLeft, prerenderReadIx, len);
- maybeCopy(nonReverbRight, pos, prerenderNonReverbRight, prerenderReadIx, len);
- maybeCopy(reverbDryLeft, pos, prerenderReverbDryLeft, prerenderReadIx, len);
- maybeCopy(reverbDryRight, pos, prerenderReverbDryRight, prerenderReadIx, len);
- maybeCopy(reverbWetLeft, pos, prerenderReverbWetLeft, prerenderReadIx, len);
- maybeCopy(reverbWetRight, pos, prerenderReverbWetRight, prerenderReadIx, len);
+const MidiEvent *MidiEventQueue::peekMidiEvent() {
+ return (startPosition == endPosition) ? NULL : &ringBuffer[startPosition];
}
-void Synth::checkPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u &pos, Bit32u &len) {
- if (prerenderReadIx > prerenderWriteIx) {
- // There's data in the prerender buffer, and the write index has wrapped.
- Bit32u prerenderCopyLen = MAX_PRERENDER_SAMPLES - prerenderReadIx;
- if (prerenderCopyLen > len) {
- prerenderCopyLen = len;
- }
- copyPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, prerenderCopyLen);
- len -= prerenderCopyLen;
- pos += prerenderCopyLen;
- prerenderReadIx = (prerenderReadIx + prerenderCopyLen) % MAX_PRERENDER_SAMPLES;
- }
- if (prerenderReadIx < prerenderWriteIx) {
- // There's data in the prerender buffer, and the write index is ahead of the read index.
- Bit32u prerenderCopyLen = prerenderWriteIx - prerenderReadIx;
- if (prerenderCopyLen > len) {
- prerenderCopyLen = len;
- }
- copyPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, prerenderCopyLen);
- len -= prerenderCopyLen;
- pos += prerenderCopyLen;
- prerenderReadIx += prerenderCopyLen;
- }
- if (prerenderReadIx == prerenderWriteIx) {
- // If the ring buffer's empty, reset it to start at 0 to minimise wrapping,
- // which requires two writes instead of one.
- prerenderReadIx = prerenderWriteIx = 0;
- }
-}
-
-void Synth::renderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len) {
- if (!isEnabled) {
- clearIfNonNull(nonReverbLeft, len);
- clearIfNonNull(nonReverbRight, len);
- clearIfNonNull(reverbDryLeft, len);
- clearIfNonNull(reverbDryRight, len);
- clearIfNonNull(reverbWetLeft, len);
- clearIfNonNull(reverbWetRight, len);
- return;
+void MidiEventQueue::dropMidiEvent() {
+ // Is ring buffer empty?
+ if (startPosition != endPosition) {
+ startPosition = (startPosition + 1) % ringBufferSize;
}
- Bit32u pos = 0;
+}
- // First, check for data in the prerender buffer and spit that out before generating anything new.
- // Note that the prerender buffer is rarely used - see comments elsewhere for details.
- checkPrerender(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, pos, len);
+void Synth::render(Sample *stream, Bit32u len) {
+ Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN];
+ Sample tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
while (len > 0) {
Bit32u thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
- doRenderStreams(
- streamOffset(nonReverbLeft, pos),
- streamOffset(nonReverbRight, pos),
- streamOffset(reverbDryLeft, pos),
- streamOffset(reverbDryRight, pos),
- streamOffset(reverbWetLeft, pos),
- streamOffset(reverbWetRight, pos),
- thisLen);
+ renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisLen);
+ for (Bit32u i = 0; i < thisLen; i++) {
+#if MT32EMU_USE_FLOAT_SAMPLES
+ *(stream++) = tmpNonReverbLeft[i] + tmpReverbDryLeft[i] + tmpReverbWetLeft[i];
+ *(stream++) = tmpNonReverbRight[i] + tmpReverbDryRight[i] + tmpReverbWetRight[i];
+#else
+ *(stream++) = clipBit16s((Bit32s)tmpNonReverbLeft[i] + (Bit32s)tmpReverbDryLeft[i] + (Bit32s)tmpReverbWetLeft[i]);
+ *(stream++) = clipBit16s((Bit32s)tmpNonReverbRight[i] + (Bit32s)tmpReverbDryRight[i] + (Bit32s)tmpReverbWetRight[i]);
+#endif
+ }
len -= thisLen;
- pos += thisLen;
}
}
-// FIXME: Using more temporary buffers than we need to
-void Synth::doRenderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len) {
- clearFloats(&tmpBufMixLeft[0], &tmpBufMixRight[0], len);
- if (!reverbEnabled) {
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
- mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
- mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
- }
- }
- if (nonReverbLeft != NULL) {
- la32FloatToBit16sFunc(nonReverbLeft, &tmpBufMixLeft[0], len, outputGain);
- }
- if (nonReverbRight != NULL) {
- la32FloatToBit16sFunc(nonReverbRight, &tmpBufMixRight[0], len, outputGain);
- }
- clearIfNonNull(reverbDryLeft, len);
- clearIfNonNull(reverbDryRight, len);
- clearIfNonNull(reverbWetLeft, len);
- clearIfNonNull(reverbWetRight, len);
- } else {
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (!partialManager->shouldReverb(i)) {
- if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
- mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
- mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
+void Synth::renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len) {
+ while (len > 0) {
+ // We need to ensure zero-duration notes will play so add minimum 1-sample delay.
+ Bit32u thisLen = 1;
+ if (!isAbortingPoly()) {
+ const MidiEvent *nextEvent = midiQueue->peekMidiEvent();
+ Bit32s samplesToNextEvent = (nextEvent != NULL) ? Bit32s(nextEvent->timestamp - renderedSampleCount) : MAX_SAMPLES_PER_RUN;
+ if (samplesToNextEvent > 0) {
+ thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
+ if (thisLen > (Bit32u)samplesToNextEvent) {
+ thisLen = samplesToNextEvent;
+ }
+ } else {
+ if (nextEvent->sysexData == NULL) {
+ playMsgNow(nextEvent->shortMessageData);
+ // If a poly is aborting we don't drop the event from the queue.
+ // Instead, we'll return to it again when the abortion is done.
+ if (!isAbortingPoly()) {
+ midiQueue->dropMidiEvent();
+ }
+ } else {
+ playSysexNow(nextEvent->sysexData, nextEvent->sysexLength);
+ midiQueue->dropMidiEvent();
}
}
}
- if (nonReverbLeft != NULL) {
- la32FloatToBit16sFunc(nonReverbLeft, &tmpBufMixLeft[0], len, outputGain);
+ doRenderStreams(nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, thisLen);
+ advanceStreamPosition(nonReverbLeft, thisLen);
+ advanceStreamPosition(nonReverbRight, thisLen);
+ advanceStreamPosition(reverbDryLeft, thisLen);
+ advanceStreamPosition(reverbDryRight, thisLen);
+ advanceStreamPosition(reverbWetLeft, thisLen);
+ advanceStreamPosition(reverbWetRight, thisLen);
+ len -= thisLen;
+ }
+}
+
+void Synth::convertSamplesToOutput(Sample *target, const Sample *source, Bit32u len, bool reverb) {
+ if (target == NULL) return;
+
+ if (dacInputMode == DACInputMode_PURE) {
+ memcpy(target, source, len * sizeof(Sample));
+ return;
+ }
+
+#if MT32EMU_USE_FLOAT_SAMPLES
+ float gain = reverb ? reverbOutputGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR : 2.0f * outputGain;
+ while (len--) {
+ *(target++) = *(source++) * gain;
+ }
+#else
+ float gain = reverb ? reverbOutputGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR : outputGain;
+ if (!reverb) {
+ switch (dacInputMode) {
+ case DACInputMode_NICE:
+ // Since we're not shooting for accuracy here, don't worry about the rounding mode.
+ gain *= 2.0f;
+ break;
+ case DACInputMode_GENERATION1:
+ while (len--) {
+ *target = clipBit16s(Bit32s(*source * gain));
+ *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE);
+ source++;
+ target++;
+ }
+ return;
+ case DACInputMode_GENERATION2:
+ while (len--) {
+ *target = clipBit16s(Bit32s(*source * gain));
+ *target = (*target & 0x8000) | ((*target << 1) & 0x7FFE) | ((*target >> 14) & 0x0001);
+ source++;
+ target++;
+ }
+ return;
+ default:
+ break;
}
- if (nonReverbRight != NULL) {
- la32FloatToBit16sFunc(nonReverbRight, &tmpBufMixRight[0], len, outputGain);
+ }
+ while (len--) {
+ *(target++) = clipBit16s(Bit32s(*(source++) * gain));
+ }
+#endif
+}
+
+void Synth::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len) {
+ if (isEnabled) {
+ Sample tmpBufMixLeft[MAX_SAMPLES_PER_RUN], tmpBufMixRight[MAX_SAMPLES_PER_RUN];
+ muteStream(tmpBufMixLeft, len);
+ muteStream(tmpBufMixRight, len);
+ for (unsigned int i = 0; i < getPartialCount(); i++) {
+ if (!reverbEnabled || !partialManager->shouldReverb(i)) {
+ partialManager->produceOutput(i, tmpBufMixLeft, tmpBufMixRight, len);
+ }
}
+ convertSamplesToOutput(nonReverbLeft, tmpBufMixLeft, len, false);
+ convertSamplesToOutput(nonReverbRight, tmpBufMixRight, len, false);
+ } else {
+ muteStream(nonReverbLeft, len);
+ muteStream(nonReverbRight, len);
+ }
- clearFloats(&tmpBufMixLeft[0], &tmpBufMixRight[0], len);
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
+ if (isEnabled && reverbEnabled) {
+ Sample tmpBufMixLeft[MAX_SAMPLES_PER_RUN], tmpBufMixRight[MAX_SAMPLES_PER_RUN];
+ muteStream(tmpBufMixLeft, len);
+ muteStream(tmpBufMixRight, len);
+ for (unsigned int i = 0; i < getPartialCount(); i++) {
if (partialManager->shouldReverb(i)) {
- if (partialManager->produceOutput(i, &tmpBufPartialLeft[0], &tmpBufPartialRight[0], len)) {
- mix(&tmpBufMixLeft[0], &tmpBufPartialLeft[0], len);
- mix(&tmpBufMixRight[0], &tmpBufPartialRight[0], len);
- }
+ partialManager->produceOutput(i, tmpBufMixLeft, tmpBufMixRight, len);
}
}
- if (reverbDryLeft != NULL) {
- la32FloatToBit16sFunc(reverbDryLeft, &tmpBufMixLeft[0], len, outputGain);
- }
- if (reverbDryRight != NULL) {
- la32FloatToBit16sFunc(reverbDryRight, &tmpBufMixRight[0], len, outputGain);
- }
+ convertSamplesToOutput(reverbDryLeft, tmpBufMixLeft, len, false);
+ convertSamplesToOutput(reverbDryRight, tmpBufMixRight, len, false);
- // FIXME: Note that on the real devices, reverb input and output are signed linear 16-bit (well, kinda, there's some fudging) PCM, not float.
- reverbModel->process(&tmpBufMixLeft[0], &tmpBufMixRight[0], &tmpBufReverbOutLeft[0], &tmpBufReverbOutRight[0], len);
- if (reverbWetLeft != NULL) {
- reverbFloatToBit16sFunc(reverbWetLeft, &tmpBufReverbOutLeft[0], len, reverbOutputGain);
- }
- if (reverbWetRight != NULL) {
- reverbFloatToBit16sFunc(reverbWetRight, &tmpBufReverbOutRight[0], len, reverbOutputGain);
- }
+ Sample tmpBufReverbOutLeft[MAX_SAMPLES_PER_RUN], tmpBufReverbOutRight[MAX_SAMPLES_PER_RUN];
+ reverbModel->process(tmpBufMixLeft, tmpBufMixRight, tmpBufReverbOutLeft, tmpBufReverbOutRight, len);
+ convertSamplesToOutput(reverbWetLeft, tmpBufReverbOutLeft, len, true);
+ convertSamplesToOutput(reverbWetRight, tmpBufReverbOutRight, len, true);
+ } else {
+ muteStream(reverbDryLeft, len);
+ muteStream(reverbDryRight, len);
+ muteStream(reverbWetLeft, len);
+ muteStream(reverbWetRight, len);
}
+
partialManager->clearAlreadyOutputed();
renderedSampleCount += len;
}
@@ -1489,19 +1526,14 @@ void Synth::printPartialUsage(unsigned long sampleOffset) {
unsigned int partialUsage[9];
partialManager->getPerPartPartialUsage(partialUsage);
if (sampleOffset > 0) {
- printDebug("[+%lu] Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", sampleOffset, partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->getFreePartialCount());
+ printDebug("[+%lu] Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", sampleOffset, partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], getPartialCount() - partialManager->getFreePartialCount());
} else {
- printDebug("Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->getFreePartialCount());
+ printDebug("Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], getPartialCount() - partialManager->getFreePartialCount());
}
}
bool Synth::hasActivePartials() const {
- if (prerenderReadIx != prerenderWriteIx) {
- // Data in the prerender buffer means that the current isActive() states are "in the future".
- // It also means that partials are definitely active at this render point.
- return true;
- }
- for (int partialNum = 0; partialNum < MT32EMU_MAX_PARTIALS; partialNum++) {
+ for (unsigned int partialNum = 0; partialNum < getPartialCount(); partialNum++) {
if (partialManager->getPartial(partialNum)->isActive()) {
return true;
}
@@ -1509,6 +1541,10 @@ bool Synth::hasActivePartials() const {
return false;
}
+bool Synth::isAbortingPoly() const {
+ return abortingPoly != NULL;
+}
+
bool Synth::isActive() const {
if (hasActivePartials()) {
return true;
@@ -1523,6 +1559,10 @@ const Partial *Synth::getPartial(unsigned int partialNum) const {
return partialManager->getPartial(partialNum);
}
+unsigned int Synth::getPartialCount() const {
+ return partialCount;
+}
+
const Part *Synth::getPart(unsigned int partNum) const {
if (partNum > 8) {
return NULL;
diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h
index b85e7ae507..783d6e2747 100644
--- a/audio/softsynth/mt32/Synth.h
+++ b/audio/softsynth/mt32/Synth.h
@@ -27,6 +27,7 @@ class Partial;
class PartialManager;
class Part;
class ROMImage;
+class BReverbModel;
/**
* Methods for emulating the connection between the LA32 and the DAC, which involves
@@ -44,6 +45,7 @@ enum DACInputMode {
// * Much less likely to overdrive than any other mode.
// * Half the volume of any of the other modes, meaning its volume relative to the reverb
// output when mixed together directly will sound wrong.
+ // * Output gain is ignored for both LA32 and reverb output.
// * Perfect for developers while debugging :)
DACInputMode_PURE,
@@ -58,7 +60,17 @@ enum DACInputMode {
DACInputMode_GENERATION2
};
-typedef void (*FloatToBit16sFunc)(Bit16s *target, const float *source, Bit32u len, float outputGain);
+enum MIDIDelayMode {
+ // Process incoming MIDI events immediately.
+ MIDIDelayMode_IMMEDIATE,
+
+ // Delay incoming short MIDI messages as if they where transferred via a MIDI cable to a real hardware unit and immediate sysex processing.
+ // This ensures more accurate timing of simultaneous NoteOn messages.
+ MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY,
+
+ // Delay all incoming MIDI events as if they where transferred via a MIDI cable to a real hardware unit.
+ MIDIDelayMode_DELAY_ALL
+};
const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41;
@@ -217,18 +229,6 @@ public:
ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {}
};
-class ReverbModel {
-public:
- virtual ~ReverbModel() {}
- // After construction or a close(), open() will be called at least once before any other call (with the exception of close()).
- virtual void open() = 0;
- // May be called multiple times without an open() in between.
- virtual void close() = 0;
- virtual void setParameters(Bit8u time, Bit8u level) = 0;
- virtual void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples) = 0;
- virtual bool isActive() const = 0;
-};
-
class ReportHandler {
friend class Synth;
@@ -244,22 +244,63 @@ protected:
virtual void onErrorControlROM() {}
virtual void onErrorPCMROM() {}
virtual void showLCDMessage(const char *message);
+ virtual void onMIDIMessagePlayed() {}
virtual void onDeviceReset() {}
virtual void onDeviceReconfig() {}
virtual void onNewReverbMode(Bit8u /* mode */) {}
virtual void onNewReverbTime(Bit8u /* time */) {}
virtual void onNewReverbLevel(Bit8u /* level */) {}
- virtual void onPartStateChanged(int /* partNum */, bool /* hasActiveNonReleasingPolys */) {}
virtual void onPolyStateChanged(int /* partNum */) {}
- virtual void onPartialStateChanged(int /* partialNum */, int /* oldPartialPhase */, int /* newPartialPhase */) {}
virtual void onProgramChanged(int /* partNum */, int /* bankNum */, const char * /* patchName */) {}
};
+/**
+ * Used to safely store timestamped MIDI events in a local queue.
+ */
+struct MidiEvent {
+ Bit32u shortMessageData;
+ const Bit8u *sysexData;
+ Bit32u sysexLength;
+ Bit32u timestamp;
+
+ ~MidiEvent();
+ void setShortMessage(Bit32u shortMessageData, Bit32u timestamp);
+ void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
+};
+
+/**
+ * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it.
+ * It is intended to:
+ * - get rid of prerenderer while retaining graceful partial abortion
+ * - add fair emulation of the MIDI interface delays
+ * - extend the synth interface with the default implementation of a typical rendering loop.
+ * THREAD SAFETY:
+ * It is safe to use either in a single thread environment or when there are only two threads - one performs only reading
+ * and one performs only writing. More complicated usage requires external synchronisation.
+ */
+class MidiEventQueue {
+private:
+ MidiEvent *ringBuffer;
+ Bit32u ringBufferSize;
+ volatile Bit32u startPosition;
+ volatile Bit32u endPosition;
+
+public:
+ MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE);
+ ~MidiEventQueue();
+ void reset();
+ bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp);
+ bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp);
+ const MidiEvent *peekMidiEvent();
+ void dropMidiEvent();
+};
+
class Synth {
friend class Part;
friend class RhythmPart;
friend class Poly;
friend class Partial;
+friend class PartialManager;
friend class Tables;
friend class MemoryRegion;
friend class TVA;
@@ -286,20 +327,22 @@ private:
Bit16s *pcmROMData;
size_t pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM
- Bit8s chantable[32];
-
- Bit32u renderedSampleCount;
+ unsigned int partialCount;
+ Bit8s chantable[32]; // FIXME: Need explanation why 32 is set, obviously it should be 16
+ MidiEventQueue *midiQueue;
+ volatile Bit32u lastReceivedMIDIEventTimestamp;
+ volatile Bit32u renderedSampleCount;
MemParams mt32ram, mt32default;
- ReverbModel *reverbModels[4];
- ReverbModel *reverbModel;
+ BReverbModel *reverbModels[4];
+ BReverbModel *reverbModel;
bool reverbEnabled;
bool reverbOverridden;
- FloatToBit16sFunc la32FloatToBit16sFunc;
- FloatToBit16sFunc reverbFloatToBit16sFunc;
+ MIDIDelayMode midiDelayMode;
+ DACInputMode dacInputMode;
float outputGain;
float reverbOutputGain;
@@ -311,41 +354,18 @@ private:
PartialManager *partialManager;
Part *parts[9];
- // FIXME: We can reorganise things so that we don't need all these separate tmpBuf, tmp and prerender buffers.
- // This should be rationalised when things have stabilised a bit (if prerender buffers don't die in the mean time).
-
- float tmpBufPartialLeft[MAX_SAMPLES_PER_RUN];
- float tmpBufPartialRight[MAX_SAMPLES_PER_RUN];
- float tmpBufMixLeft[MAX_SAMPLES_PER_RUN];
- float tmpBufMixRight[MAX_SAMPLES_PER_RUN];
- float tmpBufReverbOutLeft[MAX_SAMPLES_PER_RUN];
- float tmpBufReverbOutRight[MAX_SAMPLES_PER_RUN];
-
- Bit16s tmpNonReverbLeft[MAX_SAMPLES_PER_RUN];
- Bit16s tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
- Bit16s tmpReverbDryLeft[MAX_SAMPLES_PER_RUN];
- Bit16s tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
- Bit16s tmpReverbWetLeft[MAX_SAMPLES_PER_RUN];
- Bit16s tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
-
- // These ring buffers are only used to simulate delays present on the real device.
- // In particular, when a partial needs to be aborted to free it up for use by a new Poly,
+ // When a partial needs to be aborted to free it up for use by a new Poly,
// the controller will busy-loop waiting for the sound to finish.
- Bit16s prerenderNonReverbLeft[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderNonReverbRight[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderReverbDryLeft[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderReverbDryRight[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderReverbWetLeft[MAX_PRERENDER_SAMPLES];
- Bit16s prerenderReverbWetRight[MAX_PRERENDER_SAMPLES];
- int prerenderReadIx;
- int prerenderWriteIx;
-
- bool prerender();
- void copyPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u pos, Bit32u len);
- void checkPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u &pos, Bit32u &len);
- void doRenderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len);
-
- void playAddressedSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
+ // We emulate this by delaying new MIDI events processing until abortion finishes.
+ Poly *abortingPoly;
+
+ Bit32u getShortMessageLength(Bit32u msg);
+ Bit32u addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp);
+
+ void convertSamplesToOutput(Sample *target, const Sample *source, Bit32u len, bool reverb);
+ bool isAbortingPoly() const;
+ void doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
+
void readSysex(unsigned char channel, const Bit8u *sysex, Bit32u len) const;
void initMemoryRegions();
void deleteMemoryRegions();
@@ -375,6 +395,14 @@ private:
void printDebug(const char *fmt, ...);
public:
+ static inline Bit16s clipBit16s(Bit32s sample) {
+ // Clamp values above 32767 to 32767, and values below -32768 to -32768
+ if ((sample + 32768) & ~65535) {
+ return (sample >> 31) ^ 32767;
+ }
+ return (Bit16s)sample;
+ }
+
static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum);
// Optionally sets callbacks for reporting various errors, information and debug messages
@@ -384,18 +412,44 @@ public:
// Used to initialise the MT-32. Must be called before any other function.
// Returns true if initialization was sucessful, otherwise returns false.
// controlROMImage and pcmROMImage represent Control and PCM ROM images for use by synth.
- bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage);
+ // usePartialCount sets the maximum number of partials playing simultaneously for this session.
+ bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount = DEFAULT_MAX_PARTIALS);
// Closes the MT-32 and deallocates any memory used by the synthesizer
void close(void);
- // Sends a 4-byte MIDI message to the MT-32 for immediate playback
- void playMsg(Bit32u msg);
+ // All the enqueued events are processed by the synth immediately.
+ void flushMIDIQueue();
+
+ // Sets size of the internal MIDI event queue.
+ // The queue is flushed before reallocation.
+ void setMIDIEventQueueSize(Bit32u);
+
+ // Enqueues a MIDI event for subsequent playback.
+ // The minimum delay involves the delay introduced while the event is transferred via MIDI interface
+ // and emulation of the MCU busy-loop while it frees partials for use by a new Poly.
+ // Calls from multiple threads must be synchronised, although,
+ // no synchronisation is required with the rendering thread.
+
+ // The MIDI event will be processed not before the specified timestamp.
+ // The timestamp is measured as the global rendered sample count since the synth was created.
+ bool playMsg(Bit32u msg, Bit32u timestamp);
+ bool playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp);
+ // The MIDI event will be processed ASAP.
+ bool playMsg(Bit32u msg);
+ bool playSysex(const Bit8u *sysex, Bit32u len);
+
+ // WARNING:
+ // The methods below don't ensure minimum 1-sample delay between sequential MIDI events,
+ // and a sequence of NoteOn and immediately succeeding NoteOff messages is always silent.
+
+ // Sends a 4-byte MIDI message to the MT-32 for immediate playback.
+ void playMsgNow(Bit32u msg);
void playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity);
// Sends a string of Sysex commands to the MT-32 for immediate interpretation
// The length is in bytes
- void playSysex(const Bit8u *sysex, Bit32u len);
+ void playSysexNow(const Bit8u *sysex, Bit32u len);
void playSysexWithoutFraming(const Bit8u *sysex, Bit32u len);
void playSysexWithoutHeader(unsigned char device, unsigned char command, const Bit8u *sysex, Bit32u len);
void writeSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
@@ -405,20 +459,31 @@ public:
void setReverbOverridden(bool reverbOverridden);
bool isReverbOverridden() const;
void setDACInputMode(DACInputMode mode);
+ DACInputMode getDACInputMode() const;
+ void setMIDIDelayMode(MIDIDelayMode mode);
+ MIDIDelayMode getMIDIDelayMode() const;
// Sets output gain factor. Applied to all output samples and unrelated with the synth's Master volume.
+ // Ignored in DACInputMode_PURE
void setOutputGain(float);
+ float getOutputGain() const;
// Sets output gain factor for the reverb wet output. setOutputGain() doesn't change reverb output gain.
+ // Note: We're currently emulate CM-32L/CM-64 reverb quite accurately and the reverb output level closely
+ // corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic,
+ // there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68
+ // of that for LA32 analogue output. This factor is applied to the reverb output gain.
+ // Ignored in DACInputMode_PURE
void setReverbOutputGain(float);
+ float getReverbOutputGain() const;
// Renders samples to the specified output stream.
// The length is in frames, not bytes (in 16-bit stereo,
// one frame is 4 bytes).
- void render(Bit16s *stream, Bit32u len);
+ void render(Sample *stream, Bit32u len);
// Renders samples to the specified output streams (any or all of which may be NULL).
- void renderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len);
+ void renderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
// Returns true when there is at least one active partial, otherwise false.
bool hasActivePartials() const;
@@ -428,6 +493,9 @@ public:
const Partial *getPartial(unsigned int partialNum) const;
+ // Returns the maximum number of partials playing simultaneously.
+ unsigned int getPartialCount() const;
+
void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
// partNum should be 0..7 for Part 1..8, or 8 for Rhythm
diff --git a/audio/softsynth/mt32/TVP.cpp b/audio/softsynth/mt32/TVP.cpp
index c3e64c18d0..8f68245753 100644
--- a/audio/softsynth/mt32/TVP.cpp
+++ b/audio/softsynth/mt32/TVP.cpp
@@ -181,7 +181,7 @@ void TVP::updatePitch() {
pitch = (Bit16u)newPitch;
// FIXME: We're doing this here because that's what the CM-32L does - we should probably move this somewhere more appropriate in future.
- partial->tva->recalcSustain();
+ partial->getTVA()->recalcSustain();
}
void TVP::targetPitchOffsetReached() {
diff --git a/audio/softsynth/mt32/Tables.h b/audio/softsynth/mt32/Tables.h
index 8b4580df0e..bfb80e121e 100644
--- a/audio/softsynth/mt32/Tables.h
+++ b/audio/softsynth/mt32/Tables.h
@@ -25,6 +25,11 @@ namespace MT32Emu {
// The output from the synth is supposed to be resampled to convert the sample rate.
const unsigned int SAMPLE_RATE = 32000;
+// MIDI interface data transfer rate in samples. Used to simulate the transfer delay.
+const double MIDI_DATA_TRANSFER_RATE = (double)SAMPLE_RATE / 31250.0 * 8.0;
+
+const float CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR = 0.68f;
+
const int MIDDLEC = 60;
class Synth;
diff --git a/audio/softsynth/mt32/freeverb.cpp b/audio/softsynth/mt32/freeverb.cpp
deleted file mode 100644
index 181b878596..0000000000
--- a/audio/softsynth/mt32/freeverb.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-// Allpass filter implementation
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-#include "freeverb.h"
-
-allpass::allpass()
-{
- bufidx = 0;
-}
-
-void allpass::setbuffer(float *buf, int size)
-{
- buffer = buf;
- bufsize = size;
-}
-
-void allpass::mute()
-{
- for (int i=0; i<bufsize; i++)
- buffer[i]=0;
-}
-
-void allpass::setfeedback(float val)
-{
- feedback = val;
-}
-
-float allpass::getfeedback()
-{
- return feedback;
-}
-
-void allpass::deletebuffer()
-{
- delete[] buffer;
- buffer = 0;
-}
-// Comb filter implementation
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-comb::comb()
-{
- filterstore = 0;
- bufidx = 0;
-}
-
-void comb::setbuffer(float *buf, int size)
-{
- buffer = buf;
- bufsize = size;
-}
-
-void comb::mute()
-{
- for (int i=0; i<bufsize; i++)
- buffer[i]=0;
-}
-
-void comb::setdamp(float val)
-{
- damp1 = val;
- damp2 = 1-val;
-}
-
-float comb::getdamp()
-{
- return damp1;
-}
-
-void comb::setfeedback(float val)
-{
- feedback = val;
-}
-
-float comb::getfeedback()
-{
- return feedback;
-}
-
-void comb::deletebuffer()
-{
- delete[] buffer;
- buffer = 0;
-}
-// Reverb model implementation
-//
-// Written by Jezar at Dreampoint, June 2000
-// Modifications by Jerome Fisher, 2009, 2011
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-revmodel::revmodel(float scaletuning)
-{
- int i;
- int bufsize;
-
- // Allocate buffers for the components
- for (i = 0; i < numcombs; i++) {
- bufsize = int(scaletuning * combtuning[i]);
- combL[i].setbuffer(new float[bufsize], bufsize);
- bufsize += int(scaletuning * stereospread);
- combR[i].setbuffer(new float[bufsize], bufsize);
- }
- for (i = 0; i < numallpasses; i++) {
- bufsize = int(scaletuning * allpasstuning[i]);
- allpassL[i].setbuffer(new float[bufsize], bufsize);
- allpassL[i].setfeedback(0.5f);
- bufsize += int(scaletuning * stereospread);
- allpassR[i].setbuffer(new float[bufsize], bufsize);
- allpassR[i].setfeedback(0.5f);
- }
-
- // Set default values
- dry = initialdry;
- wet = initialwet*scalewet;
- damp = initialdamp*scaledamp;
- roomsize = (initialroom*scaleroom) + offsetroom;
- width = initialwidth;
- mode = initialmode;
- update();
-
- // Buffer will be full of rubbish - so we MUST mute them
- mute();
-}
-
-revmodel::~revmodel()
-{
- int i;
-
- for (i = 0; i < numcombs; i++) {
- combL[i].deletebuffer();
- combR[i].deletebuffer();
- }
- for (i = 0; i < numallpasses; i++) {
- allpassL[i].deletebuffer();
- allpassR[i].deletebuffer();
- }
-}
-
-void revmodel::mute()
-{
- int i;
-
- if (getmode() >= freezemode)
- return;
-
- for (i=0;i<numcombs;i++)
- {
- combL[i].mute();
- combR[i].mute();
- }
- for (i=0;i<numallpasses;i++)
- {
- allpassL[i].mute();
- allpassR[i].mute();
- }
-
- // Init LPF history
- filtprev1 = 0;
- filtprev2 = 0;
-}
-
-void revmodel::process(const float *inputL, const float *inputR, float *outputL, float *outputR, long numsamples)
-{
- float outL,outR,input;
-
- while (numsamples-- > 0)
- {
- int i;
-
- outL = outR = 0;
- input = (*inputL + *inputR) * gain;
-
- // Implementation of 2-stage IIR single-pole low-pass filter
- // found at the entrance of reverb processing on real devices
- filtprev1 += (input - filtprev1) * filtval;
- filtprev2 += (filtprev1 - filtprev2) * filtval;
- input = filtprev2;
-
- int s = -1;
- // Accumulate comb filters in parallel
- for (i=0; i<numcombs; i++)
- {
- outL += s * combL[i].process(input);
- outR += s * combR[i].process(input);
- s = -s;
- }
-
- // Feed through allpasses in series
- for (i=0; i<numallpasses; i++)
- {
- outL = allpassL[i].process(outL);
- outR = allpassR[i].process(outR);
- }
-
- // Calculate output REPLACING anything already there
- *outputL = outL*wet1 + outR*wet2;
- *outputR = outR*wet1 + outL*wet2;
-
- inputL++;
- inputR++;
- outputL++;
- outputR++;
- }
-}
-
-void revmodel::update()
-{
-// Recalculate internal values after parameter change
-
- int i;
-
- wet1 = wet*(width/2 + 0.5f);
- wet2 = wet*((1-width)/2);
-
- if (mode >= freezemode)
- {
- roomsize1 = 1;
- damp1 = 0;
- gain = muted;
- }
- else
- {
- roomsize1 = roomsize;
- damp1 = damp;
- gain = fixedgain;
- }
-
- for (i=0; i<numcombs; i++)
- {
- combL[i].setfeedback(roomsize1);
- combR[i].setfeedback(roomsize1);
- }
-
- for (i=0; i<numcombs; i++)
- {
- combL[i].setdamp(damp1);
- combR[i].setdamp(damp1);
- }
-}
-
-// The following get/set functions are not inlined, because
-// speed is never an issue when calling them, and also
-// because as you develop the reverb model, you may
-// wish to take dynamic action when they are called.
-
-void revmodel::setroomsize(float value)
-{
- roomsize = (value*scaleroom) + offsetroom;
- update();
-}
-
-float revmodel::getroomsize()
-{
- return (roomsize-offsetroom)/scaleroom;
-}
-
-void revmodel::setdamp(float value)
-{
- damp = value*scaledamp;
- update();
-}
-
-float revmodel::getdamp()
-{
- return damp/scaledamp;
-}
-
-void revmodel::setwet(float value)
-{
- wet = value*scalewet;
- update();
-}
-
-float revmodel::getwet()
-{
- return wet/scalewet;
-}
-
-void revmodel::setdry(float value)
-{
- dry = value*scaledry;
-}
-
-float revmodel::getdry()
-{
- return dry/scaledry;
-}
-
-void revmodel::setwidth(float value)
-{
- width = value;
- update();
-}
-
-float revmodel::getwidth()
-{
- return width;
-}
-
-void revmodel::setmode(float value)
-{
- mode = value;
- update();
-}
-
-float revmodel::getmode()
-{
- if (mode >= freezemode)
- return 1;
- else
- return 0;
-}
-
-void revmodel::setfiltval(float value)
-{
- filtval = value;
-}
diff --git a/audio/softsynth/mt32/freeverb.h b/audio/softsynth/mt32/freeverb.h
deleted file mode 100644
index ae4d48169e..0000000000
--- a/audio/softsynth/mt32/freeverb.h
+++ /dev/null
@@ -1,189 +0,0 @@
-#ifndef _freeverb_
-#define _freeverb_
-
-// Reverb model tuning values
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-const int numcombs = 8;
-const int numallpasses = 4;
-const float muted = 0;
-const float fixedgain = 0.015f;
-const float scalewet = 3;
-const float scaledry = 2;
-const float scaledamp = 0.4f;
-const float scaleroom = 0.28f;
-const float offsetroom = 0.7f;
-const float initialroom = 0.5f;
-const float initialdamp = 0.5f;
-const float initialwet = 1/scalewet;
-const float initialdry = 0;
-const float initialwidth = 1;
-const float initialmode = 0;
-const float freezemode = 0.5f;
-const int stereospread = 23;
-
-const int combtuning[] = {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617};
-const int allpasstuning[] = {556, 441, 341, 225};
-
-// Macro for killing denormalled numbers
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// Based on IS_DENORMAL macro by Jon Watte
-// This code is public domain
-
-static inline float undenormalise(float x) {
- union {
- float f;
- unsigned int i;
- } u;
- u.f = x;
- if ((u.i & 0x7f800000) == 0) {
- return 0.0f;
- }
- return x;
-}
-
-// Allpass filter declaration
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-class allpass
-{
-public:
- allpass();
- void setbuffer(float *buf, int size);
- void deletebuffer();
- inline float process(float inp);
- void mute();
- void setfeedback(float val);
- float getfeedback();
-// private:
- float feedback;
- float *buffer;
- int bufsize;
- int bufidx;
-};
-
-
-// Big to inline - but crucial for speed
-
-inline float allpass::process(float input)
-{
- float output;
- float bufout;
-
- bufout = undenormalise(buffer[bufidx]);
-
- output = -input + bufout;
- buffer[bufidx] = input + (bufout*feedback);
-
- if (++bufidx>=bufsize) bufidx = 0;
-
- return output;
-}
-
-// Comb filter class declaration
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-class comb
-{
-public:
- comb();
- void setbuffer(float *buf, int size);
- void deletebuffer();
- inline float process(float inp);
- void mute();
- void setdamp(float val);
- float getdamp();
- void setfeedback(float val);
- float getfeedback();
-private:
- float feedback;
- float filterstore;
- float damp1;
- float damp2;
- float *buffer;
- int bufsize;
- int bufidx;
-};
-
-
-// Big to inline - but crucial for speed
-
-inline float comb::process(float input)
-{
- float output;
-
- output = undenormalise(buffer[bufidx]);
-
- filterstore = undenormalise((output*damp2) + (filterstore*damp1));
-
- buffer[bufidx] = input + (filterstore*feedback);
-
- if (++bufidx>=bufsize) bufidx = 0;
-
- return output;
-}
-
-// Reverb model declaration
-//
-// Written by Jezar at Dreampoint, June 2000
-// Modifications by Jerome Fisher, 2009
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-class revmodel
-{
-public:
- revmodel(float scaletuning);
- ~revmodel();
- void mute();
- void process(const float *inputL, const float *inputR, float *outputL, float *outputR, long numsamples);
- void setroomsize(float value);
- float getroomsize();
- void setdamp(float value);
- float getdamp();
- void setwet(float value);
- float getwet();
- void setdry(float value);
- float getdry();
- void setwidth(float value);
- float getwidth();
- void setmode(float value);
- float getmode();
- void setfiltval(float value);
-private:
- void update();
-private:
- float gain;
- float roomsize,roomsize1;
- float damp,damp1;
- float wet,wet1,wet2;
- float dry;
- float width;
- float mode;
-
- // LPF stuff
- float filtval;
- float filtprev1;
- float filtprev2;
-
- // Comb filters
- comb combL[numcombs];
- comb combR[numcombs];
-
- // Allpass filters
- allpass allpassL[numallpasses];
- allpass allpassR[numallpasses];
-};
-
-#endif//_freeverb_
diff --git a/audio/softsynth/mt32/module.mk b/audio/softsynth/mt32/module.mk
index e7afdfd2b4..1c8aa125ab 100644
--- a/audio/softsynth/mt32/module.mk
+++ b/audio/softsynth/mt32/module.mk
@@ -1,24 +1,19 @@
MODULE := audio/softsynth/mt32
MODULE_OBJS := \
- AReverbModel.o \
BReverbModel.o \
- DelayReverb.o \
- FreeverbModel.o \
LA32Ramp.o \
LA32WaveGenerator.o \
- LegacyWaveGenerator.o \
Part.o \
Partial.o \
PartialManager.o \
Poly.o \
ROMInfo.o \
Synth.o \
+ Tables.o \
TVA.o \
TVF.o \
- TVP.o \
- Tables.o \
- freeverb.o
+ TVP.o
# Include common rules
include $(srcdir)/rules.mk
diff --git a/audio/softsynth/mt32/mt32emu.h b/audio/softsynth/mt32/mt32emu.h
index 971a0886d5..ab963886ac 100644
--- a/audio/softsynth/mt32/mt32emu.h
+++ b/audio/softsynth/mt32/mt32emu.h
@@ -60,27 +60,24 @@
#define MT32EMU_MONITOR_TVF 0
// Configuration
-// The maximum number of partials playing simultaneously
-#define MT32EMU_MAX_PARTIALS 32
-// The maximum number of notes playing simultaneously per part.
-// No point making it more than MT32EMU_MAX_PARTIALS, since each note needs at least one partial.
-#define MT32EMU_MAX_POLY 32
// If non-zero, deletes reverb buffers that are not in use to save memory.
// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path.
#define MT32EMU_REDUCE_REVERB_MEMORY 1
-// 0: Use legacy Freeverb
-// 1: Use Accurate Reverb model aka AReverb
-// 2: Use Bit-perfect Boss Reverb model aka BReverb (for developers, not much practical use)
-#define MT32EMU_USE_REVERBMODEL 1
+// 0: Maximum speed at the cost of a bit lower emulation accuracy.
+// 1: Maximum achievable emulation accuracy.
+#define MT32EMU_BOSS_REVERB_PRECISE_MODE 0
-// 0: Use refined wave generator based on logarithmic fixed-point computations and LUTs
-// 1: Use legacy accurate wave generator based on float computations
-#define MT32EMU_ACCURATE_WG 0
+// 0: Use 16-bit signed samples and refined wave generator based on logarithmic fixed-point computations and LUTs. Maximum emulation accuracy and speed.
+// 1: Use float samples in the wave generator and renderer. Maximum output quality and minimum noise.
+#define MT32EMU_USE_FLOAT_SAMPLES 0
namespace MT32Emu
{
+// The default value for the maximum number of partials playing simultaneously.
+const unsigned int DEFAULT_MAX_PARTIALS = 32;
+
// The higher this number, the more memory will be used, but the more samples can be processed in one run -
// various parts of sample generation can be processed more efficiently in a single run.
// A run's maximum length is that given to Synth::render(), so giving a value here higher than render() is ever
@@ -90,11 +87,14 @@ namespace MT32Emu
// This value must be >= 1.
const unsigned int MAX_SAMPLES_PER_RUN = 4096;
-// This determines the amount of memory available for simulating delays.
-// If set too low, partials aborted to allow other partials to play will not end gracefully, but will terminate
-// abruptly and potentially cause a pop/crackle in the audio output.
-// This value must be >= 1.
-const unsigned int MAX_PRERENDER_SAMPLES = 1024;
+// The default size of the internal MIDI event queue.
+// It holds the incoming MIDI events before the rendering engine actually processes them.
+// The main goal is to fairly emulate the real hardware behaviour which obviously
+// uses an internal MIDI event queue to gather incoming data as well as the delays
+// introduced by transferring data via the MIDI interface.
+// This also facilitates building of an external rendering loop
+// as the queue stores timestamped MIDI events.
+const unsigned int DEFAULT_MIDI_EVENT_QUEUE_SIZE = 1024;
}
#include "Structures.h"
@@ -103,7 +103,6 @@ const unsigned int MAX_PRERENDER_SAMPLES = 1024;
#include "Poly.h"
#include "LA32Ramp.h"
#include "LA32WaveGenerator.h"
-#include "LegacyWaveGenerator.h"
#include "TVA.h"
#include "TVP.h"
#include "TVF.h"
diff --git a/backends/platform/tizen/application.cpp b/backends/platform/tizen/application.cpp
index 8236ebef67..a73efacf58 100644
--- a/backends/platform/tizen/application.cpp
+++ b/backends/platform/tizen/application.cpp
@@ -31,7 +31,7 @@ Application *TizenScummVM::createInstance() {
return new TizenScummVM();
}
-TizenScummVM::TizenScummVM() : _appForm(0) {
+TizenScummVM::TizenScummVM() : _appForm(NULL) {
logEntered();
}
@@ -41,7 +41,7 @@ TizenScummVM::~TizenScummVM() {
TizenSystem *system = (TizenSystem *)g_system;
system->destroyBackend();
delete system;
- g_system = 0;
+ g_system = NULL;
}
}
@@ -68,17 +68,19 @@ bool TizenScummVM::OnAppTerminating(AppRegistry &appRegistry, bool forcedTermina
}
void TizenScummVM::OnUserEventReceivedN(RequestId requestId, IList *args) {
+ logEntered();
MessageBox messageBox;
int modalResult;
+ String *message;
- logEntered();
-
- if (requestId == USER_MESSAGE_EXIT) {
+ switch (requestId) {
+ case USER_MESSAGE_EXIT:
// normal program termination
Terminate();
- } else if (requestId == USER_MESSAGE_EXIT_ERR) {
+ break;
+
+ case USER_MESSAGE_EXIT_ERR:
// assertion failure termination
- String *message = NULL;
if (args) {
message = (String *)args->GetAt(0);
}
@@ -88,12 +90,15 @@ void TizenScummVM::OnUserEventReceivedN(RequestId requestId, IList *args) {
messageBox.Construct(L"Oops...", *message, MSGBOX_STYLE_OK);
messageBox.ShowAndWait(modalResult);
Terminate();
- } else if (requestId == USER_MESSAGE_EXIT_ERR_CONFIG) {
+ break;
+
+ case USER_MESSAGE_EXIT_ERR_CONFIG:
// the config file was corrupted
messageBox.Construct(L"Config file corrupted",
L"Settings have been reverted, please restart.", MSGBOX_STYLE_OK);
messageBox.ShowAndWait(modalResult);
Terminate();
+ break;
}
}
@@ -132,7 +137,6 @@ void TizenScummVM::pauseGame(bool pause) {
if (pause && g_engine && !g_engine->isPaused()) {
_appForm->pushKey(Common::KEYCODE_SPACE);
}
-
if (g_system) {
((TizenSystem *)g_system)->setMute(pause);
}
diff --git a/backends/platform/tizen/audio.cpp b/backends/platform/tizen/audio.cpp
index 313a10eaa8..f9ac80a583 100644
--- a/backends/platform/tizen/audio.cpp
+++ b/backends/platform/tizen/audio.cpp
@@ -26,8 +26,9 @@
#include "backends/platform/tizen/audio.h"
#include "backends/platform/tizen/system.h"
-#define TIMER_INTERVAL 10
-#define VOLUME 99
+#define TIMER_INTERVAL 10
+#define VOLUME 96
+#define MIN_TIMER_INTERVAL 5
AudioThread::AudioThread() :
_mixer(0),
@@ -38,6 +39,7 @@ AudioThread::AudioThread() :
_ready(0),
_interval(TIMER_INTERVAL),
_playing(-1),
+ _size(0),
_muted(true) {
}
@@ -70,7 +72,7 @@ void AudioThread::setMute(bool on) {
if (on) {
_timer->Cancel();
} else {
- _timer->StartAsRepeatable(_interval);
+ _timer->Start(_interval);
}
}
}
@@ -105,13 +107,14 @@ bool AudioThread::OnStart(void) {
}
}
+ _size = _audioBuffer[0].GetCapacity();
_timer = new Timer();
if (!_timer || IsFailed(_timer->Construct(*this))) {
AppLog("Failed to create audio timer");
return false;
}
- if (IsFailed(_timer->StartAsRepeatable(_interval))) {
+ if (IsFailed(_timer->Start(_interval))) {
AppLog("failed to start audio timer");
return false;
}
@@ -137,6 +140,7 @@ void AudioThread::OnStop(void) {
if (_audioOut) {
_audioOut->Reset();
+ _audioOut->Unprepare();
delete _audioOut;
}
}
@@ -161,21 +165,33 @@ void AudioThread::OnAudioOutBufferEndReached(Tizen::Media::AudioOut &src) {
_tail = (_tail + 1) % NUM_AUDIO_BUFFERS;
_ready--;
} else {
- // audio buffer empty: decrease timer inverval
+ // audio buffer empty: decrease timer interval
_playing = -1;
+ _interval -= 1;
+ if (_interval < MIN_TIMER_INTERVAL) {
+ _interval = MIN_TIMER_INTERVAL;
+ }
}
+
}
void AudioThread::OnTimerExpired(Timer &timer) {
if (_ready < NUM_AUDIO_BUFFERS) {
- uint len = _audioBuffer[_head].GetCapacity();
- int samples = _mixer->mixCallback((byte *)_audioBuffer[_head].GetPointer(), len);
- if (samples) {
- _head = (_head + 1) % NUM_AUDIO_BUFFERS;
- _ready++;
+ if (_playing != _head) {
+ if (_mixer->mixCallback((byte *)_audioBuffer[_head].GetPointer(), _size)) {
+ _head = (_head + 1) % NUM_AUDIO_BUFFERS;
+ _ready++;
+ }
}
+ } else {
+ // audio buffer full: restore timer interval
+ _interval = TIMER_INTERVAL;
}
+
if (_ready && _playing == -1) {
OnAudioOutBufferEndReached(*_audioOut);
}
+
+ _timer->Start(_interval);
}
+
diff --git a/backends/platform/tizen/audio.h b/backends/platform/tizen/audio.h
index 8d7835042d..a304231578 100644
--- a/backends/platform/tizen/audio.h
+++ b/backends/platform/tizen/audio.h
@@ -54,6 +54,7 @@ public:
bool isSilentMode();
void setMute(bool on);
+private:
bool OnStart(void);
void OnStop(void);
void OnAudioOutErrorOccurred(Tizen::Media::AudioOut &src, result r);
@@ -62,12 +63,11 @@ public:
void OnAudioOutBufferEndReached(Tizen::Media::AudioOut &src);
void OnTimerExpired(Timer &timer);
-private:
Audio::MixerImpl *_mixer;
Tizen::Base::Runtime::Timer *_timer;
Tizen::Media::AudioOut *_audioOut;
Tizen::Base::ByteBuffer _audioBuffer[NUM_AUDIO_BUFFERS];
- int _head, _tail, _ready, _interval, _playing;
+ int _head, _tail, _ready, _interval, _playing, _size;
bool _muted;
};
diff --git a/backends/platform/tizen/form.cpp b/backends/platform/tizen/form.cpp
index 5050699ca9..10d51cc610 100644
--- a/backends/platform/tizen/form.cpp
+++ b/backends/platform/tizen/form.cpp
@@ -52,7 +52,7 @@ TizenAppForm::TizenAppForm() :
_eventQueueLock(NULL),
_state(kInitState),
_buttonState(kLeftButton),
- _shortcut(kShowKeypad) {
+ _shortcut(kEscapeKey) {
}
result TizenAppForm::Construct() {
@@ -157,6 +157,8 @@ result TizenAppForm::OnInitializing(void) {
AddOrientationEventListener(*this);
AddTouchEventListener(*this);
SetMultipointTouchEnabled(true);
+ SetFormBackEventListener(this);
+ SetFormMenuEventListener(this);
// set focus to enable receiving key events
SetEnabled(true);
@@ -316,16 +318,16 @@ void TizenAppForm::invokeShortcut() {
case kControlMouse:
setButtonShortcut();
break;
-
+
case kEscapeKey:
pushKey(Common::KEYCODE_ESCAPE);
break;
-
+
case kGameMenu:
_buttonState = kLeftButton;
pushKey(Common::KEYCODE_F5);
break;
-
+
case kShowKeypad:
showKeypad();
break;
@@ -354,8 +356,6 @@ void TizenAppForm::OnTouchDoublePressed(const Control &source,
if (_buttonState != kMoveOnly) {
pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN,
currentPosition);
- pushEvent(_buttonState == kLeftButton ? Common::EVENT_LBUTTONDOWN : Common::EVENT_RBUTTONDOWN,
- currentPosition);
}
}
@@ -417,3 +417,16 @@ void TizenAppForm::OnTouchReleased(const Control &source,
}
}
+void TizenAppForm::OnFormBackRequested(Form &source) {
+ logEntered();
+ if (_state == kActiveState) {
+ invokeShortcut();
+ }
+}
+
+void TizenAppForm::OnFormMenuRequested(Form &source) {
+ logEntered();
+ if (_state == kActiveState) {
+ setShortcut();
+ }
+}
diff --git a/backends/platform/tizen/form.h b/backends/platform/tizen/form.h
index 64c447d409..e419c14d24 100644
--- a/backends/platform/tizen/form.h
+++ b/backends/platform/tizen/form.h
@@ -29,6 +29,8 @@
#include <FBase.h>
#include <FUiITouchEventListener.h>
#include <FUiITextEventListener.h>
+#include <FUiCtrlIFormBackEventListener.h>
+#include <FUiCtrlIFormMenuEventListener.h>
#include "config.h"
#include "common/scummsys.h"
@@ -40,6 +42,7 @@
using namespace Tizen::Ui;
using namespace Tizen::Graphics;
using namespace Tizen::Base::Runtime;
+using namespace Tizen::Ui::Controls;
//
// TizenAppForm
@@ -48,7 +51,9 @@ class TizenAppForm :
public Controls::Form,
public IRunnable,
public IOrientationEventListener,
- public ITouchEventListener {
+ public ITouchEventListener,
+ public IFormBackEventListener,
+ public IFormMenuEventListener {
public:
TizenAppForm();
@@ -89,6 +94,8 @@ private:
void OnTouchReleased(const Control &source,
const Point &currentPosition,
const TouchEventInfo &touchInfo);
+ void OnFormBackRequested(Form &source);
+ void OnFormMenuRequested(Form &source);
void pushEvent(Common::EventType type, const Point &currentPosition);
void terminate();
diff --git a/backends/platform/tizen/fs.cpp b/backends/platform/tizen/fs.cpp
index f8b32f4239..8145cd5638 100644
--- a/backends/platform/tizen/fs.cpp
+++ b/backends/platform/tizen/fs.cpp
@@ -339,7 +339,6 @@ bool TizenFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo
if (_isVirtualDir && mode != Common::FSNode::kListFilesOnly && _path == "/") {
// present well known TIZEN file system areas
myList.push_back(new TizenFilesystemNode(kData));
- myList.push_back(new TizenFilesystemNode(kResource));
myList.push_back(new TizenFilesystemNode(kSdCard));
myList.push_back(new TizenFilesystemNode(kMedia));
myList.push_back(new TizenFilesystemNode(kShared));
diff --git a/backends/platform/tizen/graphics.cpp b/backends/platform/tizen/graphics.cpp
index bf255cd264..2cafb9f781 100644
--- a/backends/platform/tizen/graphics.cpp
+++ b/backends/platform/tizen/graphics.cpp
@@ -100,6 +100,8 @@ void TizenGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
}
void TizenGraphicsManager::setReady() {
+ logEntered();
+ _appForm->GetVisualElement()->SetShowState(true);
_initState = false;
}
@@ -176,7 +178,9 @@ bool TizenGraphicsManager::loadEgl() {
systemError("eglMakeCurrent() failed");
return false;
}
-
+ if (!_initState) {
+ _appForm->GetVisualElement()->SetShowState(true);
+ }
logLeaving();
return true;
}
@@ -213,6 +217,7 @@ void TizenGraphicsManager::internUpdateScreen() {
void TizenGraphicsManager::unloadGFXMode() {
logEntered();
+ _appForm->GetVisualElement()->SetShowState(false);
if (_eglDisplay != EGL_NO_DISPLAY) {
eglMakeCurrent(_eglDisplay, NULL, NULL, NULL);
diff --git a/backends/platform/tizen/sscanf.cpp b/backends/platform/tizen/sscanf.cpp
index aa846698f6..75f009cc61 100644
--- a/backends/platform/tizen/sscanf.cpp
+++ b/backends/platform/tizen/sscanf.cpp
@@ -93,7 +93,7 @@ bool scanStringUntil(const char **in, va_list *ap, char c_end) {
char *arg = va_arg(*ap, char*);
while (**in && **in != c_end) {
*arg = **in;
- *arg++;
+ arg++;
(*in)++;
}
*arg = 0;
diff --git a/backends/platform/tizen/system.cpp b/backends/platform/tizen/system.cpp
index 54d92146e5..3448dc1421 100644
--- a/backends/platform/tizen/system.cpp
+++ b/backends/platform/tizen/system.cpp
@@ -513,13 +513,15 @@ TizenAppForm *systemStart(Tizen::App::Application *app) {
}
if (E_SUCCESS != appForm->Construct() ||
- E_SUCCESS != appFrame->AddControl(*appForm)) {
+ E_SUCCESS != appFrame->AddControl(appForm)) {
delete appForm;
AppLog("Failed to construct appForm");
return NULL;
}
appFrame->SetCurrentForm(appForm);
+ appForm->GetVisualElement()->SetShowState(false);
+
logLeaving();
return appForm;
}
@@ -531,7 +533,7 @@ void systemError(const char *message) {
AppLog("Fatal system error: %s", message);
if (strspn(message, "Config file buggy:") > 0) {
- Tizen::Io::File::Remove(DEFAULT_CONFIG_FILE);
+ Tizen::Io::File::Remove(App::GetInstance()->GetAppDataPath() + DEFAULT_CONFIG_FILE);
Application::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT_ERR_CONFIG, NULL);
} else {
ArrayList *args = new ArrayList();
diff --git a/backends/vkeybd/virtual-keyboard-gui.cpp b/backends/vkeybd/virtual-keyboard-gui.cpp
index 8bf9a54251..ec4cbf1de2 100644
--- a/backends/vkeybd/virtual-keyboard-gui.cpp
+++ b/backends/vkeybd/virtual-keyboard-gui.cpp
@@ -32,11 +32,9 @@
namespace Common {
-static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16 x, int16 y, OverlayColor transparent) {
- if (surf_dst->format.bytesPerPixel != sizeof(OverlayColor) || surf_src->format.bytesPerPixel != sizeof(OverlayColor))
- return;
-
- const OverlayColor *src = (const OverlayColor *)surf_src->getPixels();
+template<typename ColorType>
+static void blitImplementation(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16 x, int16 y, ColorType transparent) {
+ const ColorType *src = (const ColorType *)surf_src->getPixels();
int blitW = surf_src->w;
int blitH = surf_src->h;
@@ -58,13 +56,13 @@ static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16
if (blitW <= 0 || blitH <= 0)
return;
- OverlayColor *dst = (OverlayColor *)surf_dst->getBasePtr(x, y);
+ ColorType *dst = (ColorType *)surf_dst->getBasePtr(x, y);
int dstAdd = surf_dst->w - blitW;
int srcAdd = surf_src->w - blitW;
for (int i = 0; i < blitH; ++i) {
for (int j = 0; j < blitW; ++j, ++dst, ++src) {
- OverlayColor col = *src;
+ ColorType col = *src;
if (col != transparent)
*dst = col;
}
@@ -73,6 +71,16 @@ static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16
}
}
+static void blit(Graphics::Surface *surf_dst, Graphics::Surface *surf_src, int16 x, int16 y, uint32 transparent) {
+ if (surf_dst->format.bytesPerPixel != surf_src->format.bytesPerPixel)
+ return;
+
+ if (surf_dst->format.bytesPerPixel == 2)
+ blitImplementation<uint16>(surf_dst, surf_src, x, y, transparent);
+ else if (surf_dst->format.bytesPerPixel == 4)
+ blitImplementation<uint32>(surf_dst, surf_src, x, y, transparent);
+}
+
VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd)
: _kbd(kbd), _displaying(false), _drag(false),
_drawCaret(false), _displayEnabled(false), _firstRun(true),
@@ -111,7 +119,7 @@ void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) {
}
}
-void VirtualKeyboardGUI::setupDisplayArea(Rect &r, OverlayColor forecolor) {
+void VirtualKeyboardGUI::setupDisplayArea(Rect &r, uint32 forecolor) {
_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
if (!fontIsSuitable(_dispFont, r)) {
@@ -356,13 +364,13 @@ void VirtualKeyboardGUI::redraw() {
Graphics::Surface surf;
surf.create(w, h, _system->getOverlayFormat());
- OverlayColor *dst = (OverlayColor *)surf.getPixels();
- const OverlayColor *src = (OverlayColor *) _overlayBackup.getBasePtr(_dirtyRect.left, _dirtyRect.top);
+ byte *dst = (byte *)surf.getPixels();
+ const byte *src = (const byte *)_overlayBackup.getBasePtr(_dirtyRect.left, _dirtyRect.top);
while (h--) {
- memcpy(dst, src, surf.w * sizeof(OverlayColor));
- dst += surf.w;
- src += _overlayBackup.w;
+ memcpy(dst, src, surf.pitch);
+ dst += surf.pitch;
+ src += _overlayBackup.pitch;
}
blit(&surf, _kbdSurface, _kbdBound.left - _dirtyRect.left,
diff --git a/backends/vkeybd/virtual-keyboard-gui.h b/backends/vkeybd/virtual-keyboard-gui.h
index d0f9c884ed..a2000adea0 100644
--- a/backends/vkeybd/virtual-keyboard-gui.h
+++ b/backends/vkeybd/virtual-keyboard-gui.h
@@ -99,7 +99,7 @@ private:
VirtualKeyboard *_kbd;
Rect _kbdBound;
Graphics::Surface *_kbdSurface;
- OverlayColor _kbdTransparentColor;
+ uint32 _kbdTransparentColor;
Point _dragPoint;
bool _drag;
@@ -113,7 +113,7 @@ private:
const Graphics::Font *_dispFont;
int16 _dispX, _dispY;
uint _dispI;
- OverlayColor _dispForeColor, _dispBackColor;
+ uint32 _dispForeColor, _dispBackColor;
int _lastScreenChanged;
int16 _screenW, _screenH;
@@ -121,7 +121,7 @@ private:
bool _displaying;
bool _firstRun;
- void setupDisplayArea(Rect &r, OverlayColor forecolor);
+ void setupDisplayArea(Rect &r, uint32 forecolor);
void move(int16 x, int16 y);
void moveToDefaultPosition();
void screenChanged();
diff --git a/backends/vkeybd/virtual-keyboard.h b/backends/vkeybd/virtual-keyboard.h
index 4ab5ad446d..3b2b2196bd 100644
--- a/backends/vkeybd/virtual-keyboard.h
+++ b/backends/vkeybd/virtual-keyboard.h
@@ -112,11 +112,11 @@ protected:
String resolution;
String bitmapName;
Graphics::Surface *image;
- OverlayColor transparentColor;
+ uint32 transparentColor;
ImageMap imageMap;
VKEventMap events;
Rect displayArea;
- OverlayColor displayFontColor;
+ uint32 displayFontColor;
Mode() : image(0) {}
~Mode() {
diff --git a/devtools/create_mortdat/create_mortdat.cpp b/devtools/create_mortdat/create_mortdat.cpp
index f12a69bd37..5a491eea2f 100644
--- a/devtools/create_mortdat/create_mortdat.cpp
+++ b/devtools/create_mortdat/create_mortdat.cpp
@@ -204,16 +204,19 @@ void writeGameStrings() {
/**
* Write out the data for the English menu
*/
-void writeMenuBlock() {
- // Write out a section header to the output file and the font data
+void writeMenuData(const char *menuData, int languageId) {
+ // Write out a section header to the output file and the menu data
const char menuHeader[4] = { 'M', 'E', 'N', 'U' };
outputFile.write(menuHeader, 4); // Section Id
- outputFile.writeWord(strlen(menuDataEn) / 8); // Section size
+ int size = strlen(menuData) / 8 + 1; // Language code + Menu data size
+ outputFile.writeWord(size);
+
+ outputFile.writeByte(languageId);
// Write each 8-characters block as a byte (one bit per character)
// ' ' -> 0, anything else -> 1
byte value;
int valueCpt = 0;
- const char* str = menuDataEn;
+ const char* str = menuData;
while (*str != 0) {
if (*(str++) != ' ')
value |= (1 << (7 - valueCpt));
@@ -226,10 +229,34 @@ void writeMenuBlock() {
}
}
+void writeMenuBlock() {
+ writeMenuData(menuDataEn, 1);
+ writeMenuData(menuDataDe, 2);
+}
+
+void writeVerbNums(const int *verbs, int languageId) {
+ // Write out a section header to the output file
+ const char menuHeader[4] = { 'V', 'E', 'R', 'B' };
+ outputFile.write(menuHeader, 4); // Section Id
+ int size = 52 + 1; // Language code + 26 words
+ outputFile.writeWord(size);
+
+ outputFile.writeByte(languageId);
+ for (int i = 0; i < 26; i++)
+ outputFile.writeWord(verbs[i]);
+}
+
+void writeMenuVerbs() {
+ writeVerbNums(verbsEn, 1);
+ writeVerbNums(verbsFr, 0);
+ writeVerbNums(verbsDe, 2);
+}
+
void process() {
writeFontBlock();
writeGameStrings();
writeEngineStrings();
+ writeMenuVerbs();
writeMenuBlock();
}
diff --git a/devtools/create_mortdat/create_mortdat.h b/devtools/create_mortdat/create_mortdat.h
index 8c210d32d9..e5007ae653 100644
--- a/devtools/create_mortdat/create_mortdat.h
+++ b/devtools/create_mortdat/create_mortdat.h
@@ -24,7 +24,7 @@
*/
#define VERSION_MAJOR 1
-#define VERSION_MINOR 0
+#define VERSION_MINOR 2
enum AccessMode {
kFileReadMode = 1,
diff --git a/devtools/create_mortdat/gametext.h b/devtools/create_mortdat/gametext.h
index b1809c614c..4f7b1f9776 100644
--- a/devtools/create_mortdat/gametext.h
+++ b/devtools/create_mortdat/gametext.h
@@ -505,31 +505,31 @@ const char *gameDataEn[] = {
"$",
"YOUR MOVE$",
" attach$",
- " wait$",
- " force$",
- " sleep$",
- " listen$",
- " enter$",
" close$",
- " search$",
- " knock$",
- " scratch$",
- " read$",
" eat$",
- " place$",
- " open$",
- " take$",
+ " enter$",
+ " force$",
+ " knock$",
+ " leave$",
+ " lift$",
+ " listen$",
" look$",
+ " open$",
+ " place$",
+ " read$",
+ " scratch$",
+ " search$",
+ " sleep$",
" smell$",
" sound$",
- " leave$",
- " lift$",
+ " take$",
" turn$",
+ " wait$",
" hide yourself$",
- " search$",
- " read$",
- " put$",
" look$",
+ " put$",
+ " read$",
+ " search$",
" Leo$",
" Pat$",
" Guy$",
diff --git a/devtools/create_mortdat/menudata.h b/devtools/create_mortdat/menudata.h
index aa4557b336..ec8724135c 100644
--- a/devtools/create_mortdat/menudata.h
+++ b/devtools/create_mortdat/menudata.h
@@ -76,4 +76,68 @@ const char *menuDataEn =
"@@@ @@@ @@@ @@@ "
" ";
+const char *menuDataDe =
+ " @@@ @@ "
+ " @ @ "
+ " @ @ @@ @ @@@@"
+ " @ @ @ @@@ @ @"
+ " @ @ @ @ @ @ @ "
+ " @ @ @ @ @ @ @ "
+ "@@@ @@@ @@ @@ @@ @@@@ "
+ " "
+ " @@@@@@ @ @@ "
+ " @ @ @ "
+ " @ @ @@ @@@@ @ "
+ " @@@@ @ @ @ @@@ "
+ " @ @ @ @ @ @ "
+ " @ @ @ @ @ @ @ "
+ "@@ @@ @@@ @@@ @@ @@"
+ " "
+ " @ @@ @ "
+ " @@@ @ @ "
+ " @ @ @ @@ @@@@ "
+ " @ @ @ @ @ "
+ " @@@@@ @@@ @ "
+ " @ @ @ @ @ "
+ "@@@ @@@ @@@ @@ @@ "
+ " "
+ " @@@ @@ "
+ " @ @ "
+ " @ @@@@ @ "
+ " @ @ @ @@@ "
+ " @ @ @ @ "
+ " @ @ @ @ @ "
+ " @@@ @@@ @@ @@ "
+ " "
+ " @@@@@@ "
+ " @ @ @@ "
+ " @ @ @@@ @ @@@ "
+ " @@@@ @ @ @@@@ @ @"
+ " @ @ @@@@@ @ @ @@@@ "
+ " @ @ @ @ @ @ "
+ "@@ @@ @@@ @@@ @@@ "
+ " "
+ " @@@@@ @ "
+ " @ @ @ "
+ " @ @ @@@@ @@@@ "
+ " @ @ @ @ @ "
+ " @ @ @ @ @ "
+ " @ @ @ @ @ "
+ "@@@@@ @@@@ @@ "
+ " ";
+
+const int verbsFr[26] = { 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x307, 0x308,
+ 0x309, 0x30a, 0x30b, 0x30c, 0x30d, 0x30e, 0x30f, 0x310,
+ 0x311, 0x312, 0x313, 0x314, 0x315, 0x401, 0x402, 0x403,
+ 0x404, 0x405 };
+
+const int verbsEn[26] = { 0x301, 0x315, 0x305, 0x310, 0x309, 0x304, 0x302, 0x30f,
+ 0x306, 0x30d, 0x30e, 0x303, 0x30c, 0x30b, 0x313, 0x30a,
+ 0x311, 0x312, 0x307, 0x308, 0x314, 0x401, 0x405, 0x404,
+ 0x403, 0x402 };
+
+const int verbsDe[26] = { 0x304, 0x314, 0x307, 0x310, 0x315, 0x308, 0x311, 0x306,
+ 0x30c, 0x301, 0x30d, 0x309, 0x312, 0x30f, 0x30e, 0x302,
+ 0x30a, 0x313, 0x303, 0x30b, 0x305, 0x405, 0x402, 0x404,
+ 0x403, 0x401 };
#endif
diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp
index 23bf1bc28a..60aa35b739 100644
--- a/devtools/create_project/msbuild.cpp
+++ b/devtools/create_project/msbuild.cpp
@@ -405,7 +405,7 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b
if (isRelease) {
properties << "\t\t\t<IntrinsicFunctions>true</IntrinsicFunctions>\n"
"\t\t\t<WholeProgramOptimization>true</WholeProgramOptimization>\n"
- "\t\t\t<PreprocessorDefinitions>WIN32;DISABLE_GUI_BUILTIN_THEME;RELEASE_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
+ "\t\t\t<PreprocessorDefinitions>WIN32;RELEASE_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
"\t\t\t<StringPooling>true</StringPooling>\n"
"\t\t\t<BufferSecurityCheck>false</BufferSecurityCheck>\n"
"\t\t\t<DebugInformationFormat></DebugInformationFormat>\n"
@@ -417,7 +417,7 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b
"\t\t\t<SetChecksum>true</SetChecksum>\n";
} else {
properties << "\t\t\t<Optimization>Disabled</Optimization>\n"
- "\t\t\t<PreprocessorDefinitions>WIN32;DISABLE_GUI_BUILTIN_THEME;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
+ "\t\t\t<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n"
"\t\t\t<MinimalRebuild>true</MinimalRebuild>\n"
"\t\t\t<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n"
"\t\t\t<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n"
diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp
index 17e378fd0f..23225d3435 100644
--- a/devtools/create_project/visualstudio.cpp
+++ b/devtools/create_project/visualstudio.cpp
@@ -286,7 +286,7 @@ void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelea
if (isRelease) {
properties << "\t\tEnableIntrinsicFunctions=\"true\"\n"
"\t\tWholeProgramOptimization=\"true\"\n"
- "\t\tPreprocessorDefinitions=\"WIN32;DISABLE_GUI_BUILTIN_THEME;RELEASE_BUILD\"\n"
+ "\t\tPreprocessorDefinitions=\"WIN32;RELEASE_BUILD\"\n"
"\t\tStringPooling=\"true\"\n"
"\t\tBufferSecurityCheck=\"false\"\n"
"\t\tDebugInformationFormat=\"0\"\n"
@@ -300,7 +300,7 @@ void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelea
"\t\tSetChecksum=\"true\"\n";
} else {
properties << "\t\tOptimization=\"0\"\n"
- "\t\tPreprocessorDefinitions=\"WIN32;DISABLE_GUI_BUILTIN_THEME\"\n"
+ "\t\tPreprocessorDefinitions=\"WIN32\"\n"
"\t\tMinimalRebuild=\"true\"\n"
"\t\tBasicRuntimeChecks=\"3\"\n"
"\t\tRuntimeLibrary=\"1\"\n"
diff --git a/devtools/credits.pl b/devtools/credits.pl
index 7d39730c63..45018a5633 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -638,6 +638,16 @@ begin_credits("Credits");
add_person("David Turner", "digitall", "");
end_section();
+ begin_section("Mortevielle");
+ add_person("Arnaud Boutonn&eacute;", "Strangerke", "");
+ add_person("Paul Gilbert", "dreammaster", "");
+ end_section();
+
+ begin_section("Neverhood");
+ add_person("Benjamin Haisch", "john_doe", "");
+ add_person("Filippos Karapetis", "[md5]", "");
+ end_section();
+
begin_section("Parallaction");
add_person("", "peres", "");
end_section();
diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt
index 76c12f57f4..0dbcbf4792 100644
--- a/devtools/scumm-md5.txt
+++ b/devtools/scumm-md5.txt
@@ -775,6 +775,7 @@ puttzoo Putt-Putt Saves the Zoo
3a3e592b074f595489f7f11e150c398d -1 us Windows HE 99 Updated - Adrian
c5cc7cba02a2fbd539c4439e775b0536 43470 de Windows HE 99 Updated - Lightkey
5c9cecbd2952ccec14c9ecebf5822a34 -1 en iOS HE 100 - - clone2727
+ 7b4ee071eecadc2d8cd0c3509110825c -1 en Windows HE 100 Remastered - Kirben
3486ede0f904789267d4bcc5537a46d4 14337 en Mac - Demo - khalek
d220d154aafbfa12bd6f3ab1b2dae420 -1 de Mac - Demo - Joachim Eberhard
diff --git a/dists/engine-data/mort.dat b/dists/engine-data/mort.dat
index 8775b46c38..0d6a44206d 100644
--- a/dists/engine-data/mort.dat
+++ b/dists/engine-data/mort.dat
Binary files differ
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index 0c2c3ed3be..f1bb079ffc 100644
--- a/engines/agi/detection_tables.h
+++ b/engines/agi/detection_tables.h
@@ -642,6 +642,7 @@ static const AGIGameDescription gameDescriptions[] = {
FANMADE("AGI Piano (v1.0)", "8778b3d89eb93c1d50a70ef06ef10310"),
FANMADE("AGI Quest (v1.46-TJ0)", "1cf1a5307c1a0a405f5039354f679814"),
GAME("tetris", "", "7a874e2db2162e7a4ce31c9130248d8a", 0x2917, GID_FANMADE),
+ FANMADE("AGI Tetris (1998)", "1afcbc25bfafded2d5fb82de9da0bd9a"),
FANMADE_V("AGI Trek (Demo)", "c02882b8a8245b629c91caf7eb78eafe", 0x2440),
FANMADE_F("AGI256 Demo", "79261ac143b2e2773b2753674733b0d5", GF_AGI256),
FANMADE_F("AGI256-2 Demo", "3cad9b3aff1467cebf0c5c5b110985c5", GF_AGI256_2),
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index 65f8dd1420..87a1228c6a 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -1272,7 +1272,7 @@ protected:
Item *getNextItemPtrStrange();
- virtual bool loadGame(const char *filename, bool restartMode = false);
+ virtual bool loadGame(const Common::String &filename, bool restartMode = false);
virtual bool saveGame(uint slot, const char *caption);
void openTextWindow();
@@ -1311,7 +1311,7 @@ protected:
int countSaveGames();
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_PN : public AGOSEngine {
@@ -1517,8 +1517,8 @@ protected:
virtual void windowPutChar(WindowBlock *window, byte c, byte b = 0);
bool badload(int8 errorNum);
- int loadFile(char *name);
- int saveFile(char *name);
+ int loadFile(const Common::String &name);
+ int saveFile(const Common::String &name);
void getFilename();
void sysftodb();
void dbtosysf();
@@ -1640,7 +1640,7 @@ protected:
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Elvira2 : public AGOSEngine_Elvira1 {
@@ -1709,7 +1709,7 @@ protected:
virtual void readItemChildren(Common::SeekableReadStream *in, Item *item, uint tmp);
- virtual bool loadGame(const char *filename, bool restartMode = false);
+ virtual bool loadGame(const Common::String &filename, bool restartMode = false);
virtual bool saveGame(uint slot, const char *caption);
virtual void addArrows(WindowBlock *window, uint8 num);
@@ -1735,7 +1735,7 @@ protected:
virtual void userGame(bool load);
virtual int userGameGetKey(bool *b, char *buf, uint maxChar);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Waxworks : public AGOSEngine_Elvira2 {
@@ -1802,7 +1802,7 @@ protected:
virtual bool confirmOverWrite(WindowBlock *window);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Simon1 : public AGOSEngine_Waxworks {
@@ -1873,7 +1873,7 @@ protected:
virtual void vcStopAnimation(uint16 zone, uint16 sprite);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
class AGOSEngine_Simon2 : public AGOSEngine_Simon1 {
@@ -1919,7 +1919,7 @@ protected:
virtual void playSpeech(uint16 speechId, uint16 vgaSpriteId);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
#ifdef ENABLE_AGOS2
@@ -2059,7 +2059,7 @@ protected:
void saveUserGame(int slot);
void windowBackSpace(WindowBlock *window);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
virtual void quickLoadOrSave();
};
@@ -2139,7 +2139,7 @@ protected:
void printInfoText(const char *itemText);
- virtual char *genSaveName(int slot);
+ virtual Common::String genSaveName(int slot) const;
};
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 48671390f0..8eb7f066b3 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -33,32 +33,35 @@
namespace AGOS {
+
+// FIXME: This code counts savegames, but callers in many cases assume
+// that the return value + 1 indicates an empty slot.
int AGOSEngine::countSaveGames() {
Common::InSaveFile *f = NULL;
Common::StringArray filenames;
uint i = 1;
- char slot[4];
int slotNum;
bool marks[256];
- char *prefix = genSaveName(998);
- prefix[strlen(prefix)-3] = '*';
- prefix[strlen(prefix)-2] = '\0';
+ // Get the name of (possibly non-existent) savegame slot 998, and replace
+ // the extension by * to get a pattern.
+ Common::String tmp = genSaveName(998);
+ assert(tmp.size() >= 4 && tmp[tmp.size()-4] == '.');
+ Common::String prefix = Common::String(tmp.c_str(), tmp.size()-3) + "*";
+
memset(marks, false, 256 * sizeof(bool)); //assume no savegames for this title
filenames = _saveFileMan->listSavefiles(prefix);
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file){
//Obtain the last 3 digits of the filename, since they correspond to the save slot
- slot[0] = file->c_str()[file->size()-3];
- slot[1] = file->c_str()[file->size()-2];
- slot[2] = file->c_str()[file->size()-1];
- slot[3] = '\0';
-
- slotNum = atoi(slot);
+ assert(file->size() >= 4);
+ slotNum = atoi(file->c_str() + file->size() - 3);
if (slotNum >= 0 && slotNum < 256)
marks[slotNum] = true; //mark this slot as valid
}
+ // FIXME: Why does this already try to actually open the savegames?
+ // Historical accident?
while (i < 256) {
if (marks[i] &&
(f = _saveFileMan->openForLoading(genSaveName(i)))) {
@@ -72,68 +75,46 @@ int AGOSEngine::countSaveGames() {
}
#ifdef ENABLE_AGOS2
-char *AGOSEngine_PuzzlePack::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_PuzzlePack::genSaveName(int slot) const {
if (getGameId() == GID_DIMP)
- sprintf(buf, "dimp.sav");
+ return "dimp.sav";
else
- sprintf(buf, "swampy.sav");
-
- return buf;
+ return "swampy.sav";
}
-char *AGOSEngine_Feeble::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "feeble.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Feeble::genSaveName(int slot) const {
+ return Common::String::format("feeble.%.3d", slot);
}
#endif
-char *AGOSEngine_Simon2::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "simon2.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Simon2::genSaveName(int slot) const {
+ return Common::String::format("simon2.%.3d", slot);
}
-char *AGOSEngine_Simon1::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "simon1.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Simon1::genSaveName(int slot) const {
+ return Common::String::format("simon1.%.3d", slot);
}
-char *AGOSEngine_Waxworks::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_Waxworks::genSaveName(int slot) const {
if (getPlatform() == Common::kPlatformDOS)
- sprintf(buf, "waxworks-pc.%.3d", slot);
+ return Common::String::format("waxworks-pc.%.3d", slot);
else
- sprintf(buf, "waxworks.%.3d", slot);
-
- return buf;
+ return Common::String::format("waxworks.%.3d", slot);
}
-char *AGOSEngine_Elvira2::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_Elvira2::genSaveName(int slot) const {
if (getPlatform() == Common::kPlatformDOS)
- sprintf(buf, "elvira2-pc.%.3d", slot);
+ return Common::String::format("elvira2-pc.%.3d", slot);
else
- sprintf(buf, "elvira2.%.3d", slot);
-
- return buf;
+ return Common::String::format("elvira2.%.3d", slot);
}
-char *AGOSEngine_Elvira1::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "elvira1.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Elvira1::genSaveName(int slot) const {
+ return Common::String::format("elvira1.%.3d", slot);
}
-char *AGOSEngine::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "pn.%.3d", slot);
- return buf;
+Common::String AGOSEngine::genSaveName(int slot) const {
+ return Common::String::format("pn.%.3d", slot);
}
#ifdef ENABLE_AGOS2
@@ -177,12 +158,12 @@ void AGOSEngine::quickLoadOrSave() {
waitForSync(1122);
}
- char *filename = genSaveName(_saveLoadSlot);
+ Common::String filename = genSaveName(_saveLoadSlot);
if (_saveLoadType == 2) {
Subroutine *sub;
success = loadGame(genSaveName(_saveLoadSlot));
if (!success) {
- buf = Common::String::format(_("Failed to load game state from file:\n\n%s"), filename);
+ buf = Common::String::format(_("Failed to load game state from file:\n\n%s"), filename.c_str());
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
drawIconArray(2, me(), 0, 0);
setBitFlag(97, true);
@@ -217,7 +198,7 @@ void AGOSEngine::quickLoadOrSave() {
} else {
success = saveGame(_saveLoadSlot, _saveLoadName);
if (!success)
- buf = Common::String::format(_("Failed to save game state to file:\n\n%s"), filename);
+ buf = Common::String::format(_("Failed to save game state to file:\n\n%s"), filename.c_str());
}
if (!success) {
@@ -225,7 +206,7 @@ void AGOSEngine::quickLoadOrSave() {
dialog.runModal();
} else if (_saveLoadType == 1) {
- buf = Common::String::format(_("Successfully saved game state in file:\n\n%s"), filename);
+ buf = Common::String::format(_("Successfully saved game state in file:\n\n%s"), filename.c_str());
GUI::TimedMessageDialog dialog(buf, 1500);
dialog.runModal();
@@ -1041,7 +1022,7 @@ void writeItemID(Common::WriteStream *f, uint16 val) {
f->writeUint32BE(val - 1);
}
-bool AGOSEngine::loadGame(const char *filename, bool restartMode) {
+bool AGOSEngine::loadGame(const Common::String &filename, bool restartMode) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i;
@@ -1215,7 +1196,7 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
return result;
}
-bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
+bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMode) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i, j;
@@ -1633,7 +1614,7 @@ void AGOSEngine_PN::getFilename() {
}
}
-int AGOSEngine_PN::loadFile(char *name) {
+int AGOSEngine_PN::loadFile(const Common::String &name) {
Common::InSaveFile *f;
haltAnimation();
@@ -1666,7 +1647,7 @@ int AGOSEngine_PN::loadFile(char *name) {
return 0;
}
-int AGOSEngine_PN::saveFile(char *name) {
+int AGOSEngine_PN::saveFile(const Common::String &name) {
Common::OutSaveFile *f;
sysftodb();
haltAnimation();
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index 60a1376f25..e98cd2795a 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -370,7 +370,7 @@ void AGOSEngine_PN::opn_opcode30() {
void AGOSEngine_PN::opn_opcode31() {
int a, slot = 0;
- char bf[60];
+ Common::String bf;
if ((a = varval()) > 2) {
setScriptReturn(false);
@@ -381,10 +381,10 @@ void AGOSEngine_PN::opn_opcode31() {
case 0:
getFilename();
slot = matchSaveGame(_saveFile, countSaveGames());
- strcpy(bf, genSaveName(slot));
+ bf = genSaveName(slot);
break;
case 1:
- strcpy(bf, "pn.sav");
+ bf = "pn.sav";
break;
case 2:
// NOTE: Is this case ever used?
@@ -404,7 +404,7 @@ void AGOSEngine_PN::opn_opcode31() {
}
void AGOSEngine_PN::opn_opcode32() {
- char bf[60];
+ Common::String bf;
int a, slot;
a = varval();
@@ -419,12 +419,12 @@ void AGOSEngine_PN::opn_opcode32() {
getFilename();
slot = matchSaveGame(_saveFile, curSlot);
if (slot != -1)
- strcpy(bf, genSaveName(slot));
+ bf = genSaveName(slot);
else
- strcpy(bf, genSaveName(curSlot));
+ bf = genSaveName(curSlot);
break;
case 1:
- strcpy(bf, "pn.sav");
+ bf = "pn.sav";
break;
case 2:
// NOTE: Is this case ever used?
diff --git a/engines/drascula/actors.cpp b/engines/drascula/actors.cpp
index 9d5d6550fa..e0983809fa 100644
--- a/engines/drascula/actors.cpp
+++ b/engines/drascula/actors.cpp
@@ -135,7 +135,7 @@ void DrasculaEngine::startWalking() {
else
characterMoved = 0;
}
- startTime = getTime();
+ _startTime = getTime();
}
void DrasculaEngine::moveCharacters() {
@@ -239,7 +239,7 @@ void DrasculaEngine::moveCharacters() {
factor_red[curY + curHeight], frontSurface, screenSurface);
}
} else if (characterMoved == 1) {
- curPos[0] = _frameX[num_frame];
+ curPos[0] = _frameX[_characterFrame];
curPos[1] = frame_y + DIF_MASK_HARE;
curPos[2] = curX;
curPos[3] = curY;
@@ -369,13 +369,11 @@ void DrasculaEngine::quadrant_4() {
}
void DrasculaEngine::increaseFrameNum() {
- timeDiff = getTime() - startTime;
-
- if (timeDiff >= 6) {
- startTime = getTime();
- num_frame++;
- if (num_frame == 6)
- num_frame = 0;
+ if (getTime() - _startTime >= 6) {
+ _startTime = getTime();
+ _characterFrame++;
+ if (_characterFrame == 6)
+ _characterFrame = 0;
if (curDirection == kDirectionUp) {
curX -= stepX;
diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp
index 52cab6cd32..1145c8c3ff 100644
--- a/engines/drascula/animation.cpp
+++ b/engines/drascula/animation.cpp
@@ -426,7 +426,7 @@ void DrasculaEngine::animation_2_1() {
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
- roomNumber = 16;
+ _roomNumber = 16;
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
@@ -512,7 +512,7 @@ void DrasculaEngine::animation_2_1() {
// room number to -1 for the same purpose
// Also check animation_9_6(), where the same hack was used by
// the original
- roomNumber = -1;
+ _roomNumber = -1;
if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit())
break;
pause(8);
@@ -734,7 +734,7 @@ void DrasculaEngine::animation_14_2() {
void DrasculaEngine::asco() {
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
black();
updateRoom();
updateScreen();
@@ -1661,7 +1661,7 @@ void DrasculaEngine::animation_9_6() {
// We set the room number to -1 for the same purpose.
// Also check animation_2_1(), where the same hack was used
// by the original
- roomNumber = -2;
+ _roomNumber = -2;
loadPic("nota2.alg", bgSurface, HALF_PAL);
black();
trackProtagonist = 1;
@@ -2176,9 +2176,9 @@ void DrasculaEngine::animation_5_4(){
void DrasculaEngine::animation_6_4() {
debug(4, "animation_6_4()");
- int prevRoom = roomNumber;
+ int prevRoom = _roomNumber;
- roomNumber = 26;
+ _roomNumber = 26;
clearRoom();
loadPic(26, bgSurface, HALF_PAL);
loadPic("aux26.alg", drawSurface3);
@@ -2191,11 +2191,11 @@ void DrasculaEngine::animation_6_4() {
updateScreen();
pause(40);
talk_igor(26, kIgorFront);
- roomNumber = prevRoom;
+ _roomNumber = prevRoom;
clearRoom();
loadPic(96, frontSurface);
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
selectVerb(kVerbNone);
updateRoom();
}
@@ -2224,7 +2224,7 @@ void DrasculaEngine::activatePendulum() {
flags[1] = 2;
hare_se_ve = 0;
- roomNumber = 102;
+ _roomNumber = 102;
loadPic(102, bgSurface, HALF_PAL);
loadPic("an_p1.alg", drawSurface3);
loadPic("an_p2.alg", extraSurface);
diff --git a/engines/drascula/console.cpp b/engines/drascula/console.cpp
index 426b2ade67..c0d2748ec3 100644
--- a/engines/drascula/console.cpp
+++ b/engines/drascula/console.cpp
@@ -41,7 +41,7 @@ bool Console::Cmd_Room(int argc, const char **argv) {
int roomNum = atoi(argv[1]);
- _vm->loadedDifferentChapter = 0;
+ _vm->_loadedDifferentChapter = false;
_vm->enterRoom(roomNum);
_vm->selectVerb(kVerbNone);
_vm->clearRoom();
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index d045d683fc..95a5f7d87f 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -216,7 +216,7 @@ void DrasculaEngine::converse(int index) {
phrase3_bottom = phrase2_bottom + 8 * print_abc_opc(phrase3, phrase2_bottom + 2, game3);
phrase4_bottom = phrase3_bottom + 8 * print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionUnselected);
- if (mouseY > 0 && mouseY < phrase1_bottom) {
+ if (_mouseY > 0 && _mouseY < phrase1_bottom) {
if (game1 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game1 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -224,13 +224,13 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase1, 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game1 = kDialogOptionClicked;
talk(phrase1, sound1);
response(answer1);
}
- } else if (mouseY > phrase1_bottom && mouseY < phrase2_bottom) {
+ } else if (_mouseY > phrase1_bottom && _mouseY < phrase2_bottom) {
if (game2 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game2 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -238,13 +238,13 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase2, phrase1_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game2 = kDialogOptionClicked;
talk(phrase2, sound2);
response(answer2);
}
- } else if (mouseY > phrase2_bottom && mouseY < phrase3_bottom) {
+ } else if (_mouseY > phrase2_bottom && _mouseY < phrase3_bottom) {
if (game3 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game3 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -252,16 +252,16 @@ void DrasculaEngine::converse(int index) {
print_abc_opc(phrase3, phrase2_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
game3 = kDialogOptionClicked;
talk(phrase3, sound3);
response(answer3);
}
- } else if (mouseY > phrase3_bottom && mouseY < phrase4_bottom) {
+ } else if (_mouseY > phrase3_bottom && _mouseY < phrase4_bottom) {
print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionSelected);
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
talk(phrase4, sound4);
breakOut = 1;
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index 804881cf9a..cde00baa32 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -91,10 +91,10 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam
_color = 0;
blinking = 0;
- mouseX = 0;
- mouseY = 0;
- leftMouseButton = 0;
- rightMouseButton = 0;
+ _mouseX = 0;
+ _mouseY = 0;
+ _leftMouseButton = 0;
+ _rightMouseButton = 0;
*textName = 0;
_rnd = new Common::RandomSource("drascula");
@@ -197,7 +197,7 @@ Common::Error DrasculaEngine::run() {
syncSoundSettings();
currentChapter = 1; // values from 1 to 6 will start each part of game
- loadedDifferentChapter = 0;
+ _loadedDifferentChapter = false;
setTotalPlayTime(0);
// Check if a save is loaded from the launcher
@@ -218,7 +218,7 @@ Common::Error DrasculaEngine::run() {
curX = -1;
characterMoved = 0;
trackProtagonist = 3;
- num_frame = 0;
+ _characterFrame = 0;
hare_se_ve = 1;
checkFlags = 1;
doBreak = 0;
@@ -231,9 +231,6 @@ Common::Error DrasculaEngine::run() {
curWidth = CHARACTER_WIDTH;
feetHeight = FEET_HEIGHT;
- talkHeight = TALK_HEIGHT;
- talkWidth = TALK_WIDTH;
-
hasAnswer = 0;
savedTime = 0;
breakOut = 0;
@@ -246,7 +243,7 @@ Common::Error DrasculaEngine::run() {
globalSpeed = 0;
curExcuseLook = 0;
curExcuseAction = 0;
- roomNumber = 0;
+ _roomNumber = 0;
for (i = 0; i < 8; i++)
actorFrames[i] = 0;
@@ -268,7 +265,7 @@ Common::Error DrasculaEngine::run() {
loadPic("aux13.alg", bgSurface, COMPLETE_PAL);
loadPic(96, frontSurface);
} else if (currentChapter == 4) {
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
animation_castle();
loadPic(96, frontSurface);
clearRoom();
@@ -330,7 +327,7 @@ void DrasculaEngine::endChapter() {
bool DrasculaEngine::runCurrentChapter() {
int n;
- rightMouseButton = 0;
+ _rightMouseButton = 0;
previousMusic = -1;
@@ -360,14 +357,14 @@ bool DrasculaEngine::runCurrentChapter() {
if (currentChapter == 1) {
pickObject(28);
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
animation_1_1();
selectVerb(kVerbNone);
loadPic("2aux62.alg", drawSurface2);
trackProtagonist = 1;
objExit = 104;
- if (loadedDifferentChapter != 0) {
+ if (_loadedDifferentChapter) {
if (!loadGame(_currentSaveSlot)) {
return true;
}
@@ -383,7 +380,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(kItemPhone);
trackProtagonist = 3;
objExit = 162;
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
enterRoom(14);
else {
if (!loadGame(_currentSaveSlot)) {
@@ -401,7 +398,7 @@ bool DrasculaEngine::runCurrentChapter() {
flags[1] = 1;
trackProtagonist = 1;
objExit = 99;
- if (loadedDifferentChapter == 0)
+ if (!_loadedDifferentChapter)
enterRoom(20);
else {
if (!loadGame(_currentSaveSlot)) {
@@ -415,7 +412,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(kItemReefer2);
addObject(kItemOneCoin2);
objExit = 100;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(21);
trackProtagonist = 0;
curX = 235;
@@ -437,7 +434,7 @@ bool DrasculaEngine::runCurrentChapter() {
addObject(20);
trackProtagonist = 1;
objExit = 100;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(45);
} else {
if (!loadGame(_currentSaveSlot)) {
@@ -450,7 +447,7 @@ bool DrasculaEngine::runCurrentChapter() {
trackProtagonist = 1;
objExit = 104;
- if (loadedDifferentChapter == 0) {
+ if (!_loadedDifferentChapter) {
enterRoom(58);
animation_1_6();
} else {
@@ -480,13 +477,13 @@ bool DrasculaEngine::runCurrentChapter() {
// lead to an incorrect setting of the protagonist's tracking flag (above). This
// made the character start walking off screen, as his actual position was
// different than the displayed one
- if (roomNumber == 3 && (curX == 279) && (curY + curHeight == 101)) {
+ if (_roomNumber == 3 && (curX == 279) && (curY + curHeight == 101)) {
gotoObject(178, 121);
gotoObject(169, 135);
- } else if (roomNumber == 14 && (curX == 214) && (curY + curHeight == 121)) {
+ } else if (_roomNumber == 14 && (curX == 214) && (curY + curHeight == 121)) {
walkToObject = 1;
gotoObject(190, 130);
- } else if (roomNumber == 14 && (curX == 246) && (curY + curHeight == 112)) {
+ } else if (_roomNumber == 14 && (curX == 246) && (curY + curHeight == 112)) {
walkToObject = 1;
gotoObject(190, 130);
}
@@ -518,12 +515,12 @@ bool DrasculaEngine::runCurrentChapter() {
checkObjects();
#ifdef _WIN32_WCE
- if (rightMouseButton) {
+ if (_rightMouseButton) {
if (_menuScreen) {
#else
- if (rightMouseButton == 1 && _menuScreen) {
+ if (_rightMouseButton == 1 && _menuScreen) {
#endif
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
if (currentChapter == 2) {
loadPic(menuBackground, cursorSurface);
@@ -549,10 +546,10 @@ bool DrasculaEngine::runCurrentChapter() {
// Do not show the inventory screen in chapter 5, if the right mouse button is clicked
// while the plug (object 16) is held
// Fixes bug #2059621 - "DRASCULA: Plug bug"
- if (rightMouseButton == 1 && !_menuScreen &&
+ if (_rightMouseButton == 1 && !_menuScreen &&
!(currentChapter == 5 && pickedObject == 16)) {
#endif
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
characterMoved = 0;
if (trackProtagonist == 2)
@@ -580,19 +577,19 @@ bool DrasculaEngine::runCurrentChapter() {
}
#endif
- if (leftMouseButton == 1 && _menuBar) {
+ if (_leftMouseButton == 1 && _menuBar) {
delay(100);
selectVerbFromBar();
- } else if (leftMouseButton == 1 && takeObject == 0) {
+ } else if (_leftMouseButton == 1 && takeObject == 0) {
delay(100);
if (verify1())
return true;
- } else if (leftMouseButton == 1 && takeObject == 1) {
+ } else if (_leftMouseButton == 1 && takeObject == 1) {
if (verify2())
return true;
}
- _menuBar = (mouseY < 24 && !_menuScreen) ? true : false;
+ _menuBar = (_mouseY < 24 && !_menuScreen) ? true : false;
Common::KeyCode key = getScan();
if (key == Common::KEYCODE_F1 && !_menuScreen) {
@@ -644,11 +641,11 @@ bool DrasculaEngine::runCurrentChapter() {
} else if (key == Common::KEYCODE_TILDE || key == Common::KEYCODE_BACKQUOTE) {
_console->attach();
_console->onFrame();
- } else if (currentChapter == 6 && key == Common::KEYCODE_0 && roomNumber == 61) {
+ } else if (currentChapter == 6 && key == Common::KEYCODE_0 && _roomNumber == 61) {
loadPic("alcbar.alg", bgSurface, 255);
}
- if (leftMouseButton != 0 || rightMouseButton != 0 || key != 0)
+ if (_leftMouseButton != 0 || _rightMouseButton != 0 || key != 0)
framesWithoutAction = 0;
if (framesWithoutAction == 15000) {
@@ -670,8 +667,8 @@ bool DrasculaEngine::verify1() {
removeObject();
else {
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX >= _objectX1[l] && mouseY >= _objectY1[l]
- && mouseX <= _objectX2[l] && mouseY <= _objectY2[l] && doBreak == 0) {
+ if (_mouseX >= _objectX1[l] && _mouseY >= _objectY1[l]
+ && _mouseX <= _objectX2[l] && _mouseY <= _objectY2[l] && doBreak == 0) {
if (exitRoom(l))
return true;
if (doBreak == 1)
@@ -679,13 +676,13 @@ bool DrasculaEngine::verify1() {
}
}
- if (mouseX > curX && mouseY > curY
- && mouseX < curX + curWidth && mouseY < curY + curHeight)
+ if (_mouseX > curX && _mouseY > curY
+ && _mouseX < curX + curWidth && _mouseY < curY + curHeight)
doBreak = 1;
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l] && doBreak == 0) {
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l] && doBreak == 0) {
roomX = roomObjX[l];
roomY = roomObjY[l];
trackFinal = trackObj[l];
@@ -696,8 +693,8 @@ bool DrasculaEngine::verify1() {
}
if (doBreak == 0) {
- roomX = CLIP(mouseX, floorX1, floorX2);
- roomY = CLIP(mouseY, floorY1 + feetHeight, floorY2);
+ roomX = CLIP(_mouseX, floorX1, floorX2);
+ roomY = CLIP(_mouseY, floorY1 + feetHeight, floorY2);
startWalking();
}
doBreak = 0;
@@ -718,8 +715,8 @@ bool DrasculaEngine::verify2() {
return true;
} else {
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l] && visible[l] == 1) {
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l] && visible[l] == 1) {
trackFinal = trackObj[l];
walkToObject = 1;
gotoObject(roomObjX[l], roomObjY[l]);
@@ -779,20 +776,20 @@ void DrasculaEngine::updateEvents() {
case Common::EVENT_KEYUP:
break;
case Common::EVENT_MOUSEMOVE:
- mouseX = event.mouse.x;
- mouseY = event.mouse.y;
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
break;
case Common::EVENT_LBUTTONDOWN:
- leftMouseButton = 1;
+ _leftMouseButton = 1;
break;
case Common::EVENT_LBUTTONUP:
- leftMouseButton = 0;
+ _leftMouseButton = 0;
break;
case Common::EVENT_RBUTTONDOWN:
// We changed semantic and react only on button up event
break;
case Common::EVENT_RBUTTONUP:
- rightMouseButton = 1;
+ _rightMouseButton = 1;
break;
default:
break;
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index c4d1c4c761..944191b5fb 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -403,7 +403,7 @@ public:
int actorFrames[8];
int previousMusic, roomMusic;
- int roomNumber;
+ int _roomNumber;
char roomDisk[20];
char currentData[20];
int numRoomObjs;
@@ -428,18 +428,17 @@ public:
int flags[NUM_FLAGS];
int frame_y;
- int curX, curY, characterMoved, curDirection, trackProtagonist, num_frame;
+ int curX, curY, characterMoved, curDirection, trackProtagonist, _characterFrame;
int hare_se_ve; // TODO: what is this for?
int roomX, roomY, checkFlags;
int doBreak;
int stepX, stepY;
int curHeight, curWidth, feetHeight;
- int talkHeight, talkWidth;
int floorX1, floorY1, floorX2, floorY2;
int lowerLimit, upperLimit;
int trackFinal, walkToObject;
int objExit;
- int timeDiff, startTime;
+ int _startTime;
int hasAnswer;
int savedTime;
int breakOut;
@@ -454,14 +453,11 @@ public:
int framesWithoutAction;
int term_int;
int currentChapter;
- int loadedDifferentChapter;
+ bool _loadedDifferentChapter;
int _currentSaveSlot;
int _color;
int musicStopped;
- int mouseX;
- int mouseY;
- int leftMouseButton;
- int rightMouseButton;
+ int _mouseX, _mouseY, _leftMouseButton, _rightMouseButton;
Common::KeyState _keyBuffer[KEYBUFSIZE];
int _keyBufferHead;
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 31d03a94a7..b28de669b6 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -82,7 +82,7 @@ void DrasculaEngine::moveCursor() {
} else if (!_menuScreen && _color != kColorLightGreen)
color_abc(kColorLightGreen);
if (_hasName && !_menuScreen)
- centerText(textName, mouseX, mouseY);
+ centerText(textName, _mouseX, _mouseY);
if (_menuScreen)
showMenu();
else if (_menuBar)
@@ -417,8 +417,8 @@ void DrasculaEngine::screenSaver() {
delete stream;
updateEvents();
- xr = mouseX;
- yr = mouseY;
+ xr = _mouseX;
+ yr = _mouseY;
while (!shouldQuit()) {
// efecto(bgSurface);
@@ -480,18 +480,18 @@ void DrasculaEngine::screenSaver() {
// end of efecto()
updateEvents();
- if (rightMouseButton == 1 || leftMouseButton == 1)
+ if (_rightMouseButton == 1 || _leftMouseButton == 1)
break;
- if (mouseX != xr)
+ if (_mouseX != xr)
break;
- if (mouseY != yr)
+ if (_mouseY != yr)
break;
}
// fin_ghost();
free(copia);
free(ghost);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
showCursor();
}
diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp
index fca8040f59..f0b6d12027 100644
--- a/engines/drascula/interface.cpp
+++ b/engines/drascula/interface.cpp
@@ -51,7 +51,7 @@ bool DrasculaEngine::isCursorVisible() {
void DrasculaEngine::selectVerbFromBar() {
for (int n = 0; n < 7; n++) {
- if (mouseX > _verbBarX[n] && mouseX < _verbBarX[n + 1] && n > 0) {
+ if (_mouseX > _verbBarX[n] && _mouseX < _verbBarX[n + 1] && n > 0) {
selectVerb(n);
return;
}
@@ -143,7 +143,7 @@ void DrasculaEngine::clearMenu() {
int n, verbActivated = 1;
for (n = 0; n < 7; n++) {
- if (mouseX > _verbBarX[n] && mouseX < _verbBarX[n + 1])
+ if (_mouseX > _verbBarX[n] && _mouseX < _verbBarX[n + 1])
verbActivated = 0;
copyRect(OBJWIDTH * n, OBJHEIGHT * verbActivated, _verbBarX[n], 2,
OBJWIDTH, OBJHEIGHT, cursorSurface, screenSurface);
@@ -165,8 +165,8 @@ void DrasculaEngine::showMap() {
_hasName = false;
for (int l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l]
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l]
&& visible[l] == 1) {
strcpy(textName, objName[l]);
_hasName = true;
diff --git a/engines/drascula/objects.cpp b/engines/drascula/objects.cpp
index f9f68c3317..35dfd3162a 100644
--- a/engines/drascula/objects.cpp
+++ b/engines/drascula/objects.cpp
@@ -91,8 +91,8 @@ void DrasculaEngine::gotoObject(int pointX, int pointY) {
updateRoom();
updateScreen();
- // roomNumber -2 is end credits. Do not show cursor there
- if (cursorVisible && roomNumber != -2)
+ // _roomNumber -2 is end credits. Do not show cursor there
+ if (cursorVisible && _roomNumber != -2)
showCursor();
}
@@ -100,8 +100,8 @@ void DrasculaEngine::checkObjects() {
int l, veo = 0;
for (l = 0; l < numRoomObjs; l++) {
- if (mouseX > _objectX1[l] && mouseY > _objectY1[l]
- && mouseX < _objectX2[l] && mouseY < _objectY2[l]
+ if (_mouseX > _objectX1[l] && _mouseY > _objectY1[l]
+ && _mouseX < _objectX2[l] && _mouseY < _objectY2[l]
&& visible[l] == 1 && isDoor[l] == 0) {
strcpy(textName, objName[l]);
_hasName = true;
@@ -109,8 +109,8 @@ void DrasculaEngine::checkObjects() {
}
}
- if (mouseX > curX + 2 && mouseY > curY + 2
- && mouseX < curX + curWidth - 2 && mouseY < curY + curHeight - 2) {
+ if (_mouseX > curX + 2 && _mouseY > curY + 2
+ && _mouseX < curX + curWidth - 2 && _mouseY < curY + curHeight - 2) {
if (currentChapter == 2 || veo == 0) {
strcpy(textName, "hacker");
_hasName = true;
@@ -223,9 +223,9 @@ int DrasculaEngine::whichObject() {
int n;
for (n = 1; n < ARRAYSIZE(inventoryObjects); n++) {
- if (mouseX > _itemLocations[n].x && mouseY > _itemLocations[n].y &&
- mouseX < _itemLocations[n].x + OBJWIDTH &&
- mouseY < _itemLocations[n].y + OBJHEIGHT) {
+ if (_mouseX > _itemLocations[n].x && _mouseY > _itemLocations[n].y &&
+ _mouseX < _itemLocations[n].x + OBJWIDTH &&
+ _mouseY < _itemLocations[n].y + OBJHEIGHT) {
return n;
}
}
@@ -237,69 +237,69 @@ void DrasculaEngine::updateVisible() {
if (currentChapter == 1) {
// nothing
} else if (currentChapter == 2) {
- if (roomNumber == 2 && flags[40] == 0)
+ if (_roomNumber == 2 && flags[40] == 0)
visible[3] = 0;
- else if (roomNumber == 3 && flags[3] == 1)
+ else if (_roomNumber == 3 && flags[3] == 1)
visible[8] = 0;
- else if (roomNumber == 6 && flags[1] == 1 && flags[10] == 0) {
+ else if (_roomNumber == 6 && flags[1] == 1 && flags[10] == 0) {
visible[2] = 0;
visible[4] = 1;
- } else if (roomNumber == 7 && flags[35] == 1)
+ } else if (_roomNumber == 7 && flags[35] == 1)
visible[3] = 0;
- else if (roomNumber == 14 && flags[5] == 1)
+ else if (_roomNumber == 14 && flags[5] == 1)
visible[4] = 0;
- else if (roomNumber == 18 && flags[28] == 1)
+ else if (_roomNumber == 18 && flags[28] == 1)
visible[2] = 0;
} else if (currentChapter == 3) {
// nothing
} else if (currentChapter == 4) {
- if (roomNumber == 23 && flags[0] == 0 && flags[11] == 0)
+ if (_roomNumber == 23 && flags[0] == 0 && flags[11] == 0)
visible[2] = 1;
- if (roomNumber == 23 && flags[0] == 1 && flags[11] == 0)
+ if (_roomNumber == 23 && flags[0] == 1 && flags[11] == 0)
visible[2] = 0;
- if (roomNumber == 21 && flags[10] == 1)
+ if (_roomNumber == 21 && flags[10] == 1)
visible[2] = 0;
- if (roomNumber == 22 && flags[26] == 1) {
+ if (_roomNumber == 22 && flags[26] == 1) {
visible[2] = 0;
visible[1] = 1;
}
- if (roomNumber == 22 && flags[27] == 1)
+ if (_roomNumber == 22 && flags[27] == 1)
visible[3] = 0;
- if (roomNumber == 26 && flags[21] == 0)
+ if (_roomNumber == 26 && flags[21] == 0)
strcpy(objName[2], _textmisc[0]);
- if (roomNumber == 26 && flags[18] == 1)
+ if (_roomNumber == 26 && flags[18] == 1)
visible[2] = 0;
- if (roomNumber == 26 && flags[12] == 1)
+ if (_roomNumber == 26 && flags[12] == 1)
visible[1] = 0;
- if (roomNumber == 35 && flags[14] == 1)
+ if (_roomNumber == 35 && flags[14] == 1)
visible[2] = 0;
- if (roomNumber == 35 && flags[17] == 1)
+ if (_roomNumber == 35 && flags[17] == 1)
visible[3] = 1;
- if (roomNumber == 35 && flags[15] == 1)
+ if (_roomNumber == 35 && flags[15] == 1)
visible[1] = 0;
} else if (currentChapter == 5) {
- if (roomNumber == 49 && flags[6] == 1)
+ if (_roomNumber == 49 && flags[6] == 1)
visible[2] = 0;
- if (roomNumber == 49 && flags[6] == 0)
+ if (_roomNumber == 49 && flags[6] == 0)
visible[1] = 0;
- if (roomNumber == 49 && flags[6] == 1)
+ if (_roomNumber == 49 && flags[6] == 1)
visible[1] = 1;
- if (roomNumber == 45 && flags[6] == 1)
+ if (_roomNumber == 45 && flags[6] == 1)
visible[3] = 1;
- if (roomNumber == 53 && flags[2] == 1)
+ if (_roomNumber == 53 && flags[2] == 1)
visible[3] = 0;
- if (roomNumber == 54 && flags[13] == 1)
+ if (_roomNumber == 54 && flags[13] == 1)
visible[3] = 0;
- if (roomNumber == 55 && flags[8] == 1)
+ if (_roomNumber == 55 && flags[8] == 1)
visible[1] = 0;
} else if (currentChapter == 6) {
- if (roomNumber == 58 && flags[8] == 0)
+ if (_roomNumber == 58 && flags[8] == 0)
isDoor[1] = 0;
- if (roomNumber == 58 && flags[8] == 1)
+ if (_roomNumber == 58 && flags[8] == 1)
isDoor[1] = 1;
- if (roomNumber == 59)
+ if (_roomNumber == 59)
isDoor[1] = 0;
- if (roomNumber == 60) {
+ if (_roomNumber == 60) {
trackDrascula = 0;
drasculaX = 155;
drasculaY = 69;
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index 9f707eaa07..25f3da0080 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -1087,7 +1087,7 @@ bool DrasculaEngine::room_102(int fl) {
void DrasculaEngine::updateRefresh() {
// Check generic updaters
for (int i = 0; i < _roomUpdatesSize; i++) {
- if (_roomUpdates[i].roomNum == roomNumber) {
+ if (_roomUpdates[i].roomNum == _roomNumber) {
if (_roomUpdates[i].flag < 0 ||
flags[_roomUpdates[i].flag] == _roomUpdates[i].flagValue) {
if (_roomUpdates[i].type == 0) {
@@ -1107,25 +1107,25 @@ void DrasculaEngine::updateRefresh() {
// Call room-specific updater
char rm[20];
- sprintf(rm, "update_%d", roomNumber);
+ sprintf(rm, "update_%d", _roomNumber);
for (uint i = 0; i < _roomHandlers->roomUpdaters.size(); i++) {
if (!strcmp(rm, _roomHandlers->roomUpdaters[i]->desc)) {
- debug(8, "Calling room updater %d", roomNumber);
+ debug(8, "Calling room updater %d", _roomNumber);
(this->*(_roomHandlers->roomUpdaters[i]->proc))();
break;
}
}
- if (roomNumber == 10)
+ if (_roomNumber == 10)
showMap();
- else if (roomNumber == 45)
+ else if (_roomNumber == 45)
showMap();
}
void DrasculaEngine::updateRefresh_pre() {
// Check generic preupdaters
for (int i = 0; i < _roomPreUpdatesSize; i++) {
- if (_roomPreUpdates[i].roomNum == roomNumber) {
+ if (_roomPreUpdates[i].roomNum == _roomNumber) {
if (_roomPreUpdates[i].flag < 0 ||
flags[_roomPreUpdates[i].flag] == _roomPreUpdates[i].flagValue) {
if (_roomPreUpdates[i].type == 0) {
@@ -1145,16 +1145,16 @@ void DrasculaEngine::updateRefresh_pre() {
// Call room-specific preupdater
char rm[20];
- sprintf(rm, "update_%d_pre", roomNumber);
+ sprintf(rm, "update_%d_pre", _roomNumber);
for (uint i = 0; i < _roomHandlers->roomPreupdaters.size(); i++) {
if (!strcmp(rm, _roomHandlers->roomPreupdaters[i]->desc)) {
- debug(8, "Calling room preupdater %d", roomNumber);
+ debug(8, "Calling room preupdater %d", _roomNumber);
(this->*(_roomHandlers->roomPreupdaters[i]->proc))();
break;
}
}
- if (currentChapter == 1 && roomNumber == 16)
+ if (currentChapter == 1 && _roomNumber == 16)
placeBJ();
}
@@ -1577,12 +1577,12 @@ bool DrasculaEngine::checkAction(int fl) {
hasAnswer = 0;
} else if (currentChapter == 2) {
// Note: the original check was strcmp(num_room, "18.alg")
- if (pickedObject == 11 && fl == 50 && flags[22] == 0 && roomNumber != 18)
+ if (pickedObject == 11 && fl == 50 && flags[22] == 0 && _roomNumber != 18)
talk(315);
else
hasAnswer = 0;
} else if (currentChapter == 3) {
- if (roomNumber == 13) {
+ if (_roomNumber == 13) {
if (room(13, fl)) {
showCursor();
return true;
@@ -1590,13 +1590,13 @@ bool DrasculaEngine::checkAction(int fl) {
} else
hasAnswer = 0;
} else if (currentChapter == 4) {
- if (roomNumber == 28)
+ if (_roomNumber == 28)
talk(178);
else if (pickedObject == 8 && fl == 50 && flags[18] == 0)
talk(481);
else if (pickedObject == 12 && fl == 50 && flags[18] == 0)
talk(487);
- else if (roomNumber == 21) {
+ else if (_roomNumber == 21) {
if (room(21, fl)) {
showCursor();
return true;
@@ -1604,7 +1604,7 @@ bool DrasculaEngine::checkAction(int fl) {
} else
hasAnswer = 0;
} else if (currentChapter == 5) {
- if (roomNumber == 56) {
+ if (_roomNumber == 56) {
if (room(56, fl)) {
showCursor();
return true;
@@ -1616,9 +1616,9 @@ bool DrasculaEngine::checkAction(int fl) {
talk(308);
else if (pickedObject == kVerbLook && fl == 50 && flags[0] == 0)
talk(310);
- else if (roomNumber == 102)
+ else if (_roomNumber == 102)
room(102, fl);
- else if (roomNumber == 60) {
+ else if (_roomNumber == 60) {
if (room(60, fl)) {
showCursor();
return true;
@@ -1632,7 +1632,7 @@ bool DrasculaEngine::checkAction(int fl) {
if (hasAnswer == 0) {
hasAnswer = 1;
- room(roomNumber, fl);
+ room(_roomNumber, fl);
}
if (hasAnswer == 0 && (_hasName || _menuScreen))
@@ -1684,7 +1684,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
TextResourceParser p(stream, DisposeAfterUse::YES);
- p.parseInt(roomNumber);
+ p.parseInt(_roomNumber);
p.parseInt(roomMusic);
p.parseString(roomDisk);
p.parseInt(palLevel);
@@ -1778,7 +1778,7 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
loadPic(roomDisk, drawSurface3);
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
copyBackground(0, 171, 0, 0, OBJWIDTH, OBJHEIGHT, backSurface, drawSurface3);
@@ -1808,14 +1808,14 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
}
- if (roomNumber == 24) {
+ if (_roomNumber == 24) {
for (l = floorY1 - 1; l > 74; l--) {
factor_red[l] = (int)(upperLimit - pequegnez);
pequegnez = pequegnez + chiquez;
}
}
- if (currentChapter == 5 && roomNumber == 54) {
+ if (currentChapter == 5 && _roomNumber == 54) {
for (l = floorY1 - 1; l > 84; l--) {
factor_red[l] = (int)(upperLimit - pequegnez);
pequegnez = pequegnez + chiquez;
@@ -1853,13 +1853,13 @@ void DrasculaEngine::enterRoom(int roomIndex) {
isDoor[7] = 0;
if (currentChapter == 2) {
- if (roomNumber == 14 && flags[39] == 1)
+ if (_roomNumber == 14 && flags[39] == 1)
roomMusic = 16;
- else if (roomNumber == 15 && flags[39] == 1)
+ else if (_roomNumber == 15 && flags[39] == 1)
roomMusic = 16;
- if (roomNumber == 14 && flags[5] == 1)
+ if (_roomNumber == 14 && flags[5] == 1)
roomMusic = 0;
- else if (roomNumber == 15 && flags[5] == 1)
+ else if (_roomNumber == 15 && flags[5] == 1)
roomMusic = 0;
if (previousMusic != roomMusic && roomMusic != 0)
@@ -1872,21 +1872,21 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
if (currentChapter == 2) {
- if (roomNumber == 9 || roomNumber == 2 || roomNumber == 14 || roomNumber == 18)
+ if (_roomNumber == 9 || _roomNumber == 2 || _roomNumber == 14 || _roomNumber == 18)
savedTime = getTime();
}
if (currentChapter == 4) {
- if (roomNumber == 26)
+ if (_roomNumber == 26)
savedTime = getTime();
}
- if (currentChapter == 4 && roomNumber == 24 && flags[29] == 1)
+ if (currentChapter == 4 && _roomNumber == 24 && flags[29] == 1)
animation_7_4();
if (currentChapter == 5) {
- if (roomNumber == 45)
+ if (_roomNumber == 45)
hare_se_ve = 0;
- if (roomNumber == 49 && flags[7] == 0) {
+ if (_roomNumber == 49 && flags[7] == 0) {
playTalkSequence(4); // sequence 4, chapter 5
}
}
diff --git a/engines/drascula/saveload.cpp b/engines/drascula/saveload.cpp
index 996c9d3f03..61d6f0b4af 100644
--- a/engines/drascula/saveload.cpp
+++ b/engines/drascula/saveload.cpp
@@ -263,7 +263,7 @@ bool DrasculaEngine::loadGame(int slot) {
if (savedChapter != currentChapter) {
_currentSaveSlot = slot;
currentChapter = savedChapter - 1;
- loadedDifferentChapter = 1;
+ _loadedDifferentChapter = true;
delete in;
return false;
}
@@ -283,7 +283,7 @@ bool DrasculaEngine::loadGame(int slot) {
takeObject = in->readSint32LE();
pickedObject = in->readSint32LE();
- loadedDifferentChapter = 0;
+ _loadedDifferentChapter = false;
if (!sscanf(currentData, "%d.ald", &roomNum)) {
error("Bad save format");
}
@@ -383,10 +383,10 @@ bool DrasculaEngine::saveLoadScreen() {
updateScreen();
updateEvents();
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
// Check if the user has clicked on a save slot
for (n = 0; n < NUM_SAVES; n++) {
- if (mouseX > 115 && mouseY > 27 + (9 * n) && mouseX < 115 + 175 && mouseY < 27 + 10 + (9 * n)) {
+ if (_mouseX > 115 && _mouseY > 27 + (9 * n) && _mouseX < 115 + 175 && _mouseY < 27 + 10 + (9 * n)) {
selectedSlot = n;
selectedName = _saveNames[selectedSlot];
if (selectedName.empty()) {
@@ -399,14 +399,14 @@ bool DrasculaEngine::saveLoadScreen() {
}
// Check if the user has clicked in the text area above the save slots
- if (mouseX > 117 && mouseY > 15 && mouseX < 295 && mouseY < 24 && !selectedName.empty()) {
+ if (_mouseX > 117 && _mouseY > 15 && _mouseX < 295 && _mouseY < 24 && !selectedName.empty()) {
selectedName = enterName(selectedName);
if (!selectedName.empty())
_saveNames[selectedSlot] = selectedName; // update save name
}
// Check if the user has clicked a button
- if (mouseX > 208 && mouseY > 123 && mouseX < 282 && mouseY < 149) {
+ if (_mouseX > 208 && _mouseY > 123 && _mouseX < 282 && _mouseY < 149) {
// "Save" button
if (selectedName.empty()) {
print_abc("Please select a slot", 117, 15);
@@ -415,14 +415,14 @@ bool DrasculaEngine::saveLoadScreen() {
} else {
selectVerb(kVerbNone);
clearRoom();
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
updateRoom();
updateScreen();
saveGame(selectedSlot + 1, _saveNames[selectedSlot]);
return true;
}
- } else if (mouseX > 125 && mouseY > 123 && mouseX < 199 && mouseY < 149) {
+ } else if (_mouseX > 125 && _mouseY > 123 && _mouseX < 199 && _mouseY < 149) {
// "Load" button
if (selectedName.empty()) {
print_abc("Please select a slot", 117, 15);
@@ -431,19 +431,19 @@ bool DrasculaEngine::saveLoadScreen() {
} else {
return loadGame(selectedSlot + 1);
}
- } else if (mouseX > 168 && mouseY > 154 && mouseX < 242 && mouseY < 180) {
+ } else if (_mouseX > 168 && _mouseY > 154 && _mouseX < 242 && _mouseY < 180) {
// "Play" button
break;
}
- } // if (leftMouseButton == 1)
+ } // if (_leftMouseButton == 1)
- leftMouseButton = 0;
+ _leftMouseButton = 0;
delay(10);
}
selectVerb(kVerbNone);
clearRoom();
- loadPic(roomNumber, bgSurface, HALF_PAL);
+ loadPic(_roomNumber, bgSurface, HALF_PAL);
return true;
}
diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp
index 112f6fd06c..59b5e1d237 100644
--- a/engines/drascula/sound.cpp
+++ b/engines/drascula/sound.cpp
@@ -36,9 +36,9 @@ namespace Drascula {
void DrasculaEngine::updateVolume(Audio::Mixer::SoundType soundType, int prevVolume) {
int vol = _mixer->getVolumeForSoundType(soundType) / 16;
- if (mouseY < prevVolume && vol < 15)
+ if (_mouseY < prevVolume && vol < 15)
vol++;
- if (mouseY > prevVolume && vol > 0)
+ if (_mouseY > prevVolume && vol > 0)
vol--;
_mixer->setVolumeForSoundType(soundType, vol * 16);
}
@@ -78,23 +78,23 @@ void DrasculaEngine::volumeControls() {
while (getScan())
;
- if (rightMouseButton == 1) {
+ if (_rightMouseButton == 1) {
// Clear this to avoid going straight to the inventory
- rightMouseButton = 0;
+ _rightMouseButton = 0;
delay(100);
break;
}
- if (leftMouseButton == 1) {
+ if (_leftMouseButton == 1) {
delay(100);
- if (mouseX > 80 && mouseX < 121) {
+ if (_mouseX > 80 && _mouseX < 121) {
updateVolume(Audio::Mixer::kPlainSoundType, masterVolumeY);
}
- if (mouseX > 136 && mouseX < 178) {
+ if (_mouseX > 136 && _mouseX < 178) {
updateVolume(Audio::Mixer::kSpeechSoundType, voiceVolumeY);
}
- if (mouseX > 192 && mouseX < 233) {
+ if (_mouseX > 192 && _mouseX < 233) {
updateVolume(Audio::Mixer::kMusicSoundType, musicVolumeY);
}
}
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index a326852e96..6aabd91c6a 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -381,11 +381,11 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
int face;
if (currentChapter == 6) {
- if (flags[0] == 0 && roomNumber == 102) {
+ if (flags[0] == 0 && _roomNumber == 102) {
talk_pen(said, filename, 0);
return;
}
- if (flags[0] == 0 && roomNumber == 58) {
+ if (flags[0] == 0 && _roomNumber == 58) {
talk_pen(said, filename, 1);
return;
}
@@ -397,7 +397,7 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
}
if (currentChapter == 4) {
- if (roomNumber == 24 || flags[29] == 0) {
+ if (_roomNumber == 24 || flags[29] == 0) {
color_abc(kColorYellow);
}
} else {
@@ -413,59 +413,59 @@ void DrasculaEngine::talk(const char *said, const char *filename) {
updateRefresh_pre();
if (currentChapter == 2)
- copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, talkHeight - 1, screenSurface, drawSurface3);
+ copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, TALK_HEIGHT - 1, screenSurface, drawSurface3);
else
copyBackground(curX, curY, OBJWIDTH + 1, 0, (int)(((float)curWidth / 100) * factor_red[MIN(201, curY + curHeight)]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
screenSurface, drawSurface3);
moveCharacters();
if (currentChapter == 2) {
if (!strcmp(menuBackground, "99.alg") || !strcmp(menuBackground, "994.alg"))
- copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, talkHeight - 1, drawSurface3, screenSurface);
+ copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, TALK_HEIGHT - 1, drawSurface3, screenSurface);
} else {
copyBackground(OBJWIDTH + 1, 0, curX, curY, (int)(((float)curWidth / 100) * factor_red[MIN(201, curY + curHeight)]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[MIN(201, curY + curHeight)]),
drawSurface3, screenSurface);
}
if (trackProtagonist == 0) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, talkWidth, talkHeight,
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk, curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight,
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk, curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight,
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT,
frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk,
talkOffset + curX + (int)((12.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth, talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
frontSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 3) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, talkWidth, talkHeight,
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, TALK_WIDTH, TALK_HEIGHT,
frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk,
talkOffset + curX + (int)((8.0f / 100) * factor_red[MIN(201, curY + curHeight)]),
- curY, talkWidth,talkHeight, factor_red[MIN(201, curY + curHeight)],
+ curY, TALK_WIDTH,TALK_HEIGHT, factor_red[MIN(201, curY + curHeight)],
frontSurface, screenSurface);
updateRefresh();
}
@@ -827,47 +827,47 @@ void DrasculaEngine::talk_sync(const char *said, const char *filename, const cha
updateRefresh_pre();
if (currentChapter == 2)
- copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, talkHeight - 1, screenSurface, drawSurface3);
+ copyBackground(curX, curY, OBJWIDTH + 1, 0, curWidth, TALK_HEIGHT - 1, screenSurface, drawSurface3);
else
copyBackground(curX, curY, OBJWIDTH + 1, 0, (int)(((float)curWidth / 100) * factor_red[curY + curHeight]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[curY + curHeight]), screenSurface, drawSurface3);
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[curY + curHeight]), screenSurface, drawSurface3);
moveCharacters();
if (currentChapter == 2) {
if (curHeight != 56)
- copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, talkHeight - 1, drawSurface3, screenSurface);
+ copyBackground(OBJWIDTH + 1, 0, curX, curY, curWidth, TALK_HEIGHT - 1, drawSurface3, screenSurface);
} else
copyBackground(OBJWIDTH + 1, 0, curX, curY, (int)(((float)curWidth / 100) * factor_red[curY + curHeight]),
- (int)(((float)(talkHeight - 1) / 100) * factor_red[curY + curHeight]), drawSurface3, screenSurface);
+ (int)(((float)(TALK_HEIGHT - 1) / 100) * factor_red[curY + curHeight]), drawSurface3, screenSurface);
if (trackProtagonist == 0) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, talkWidth, talkHeight, extraSurface, screenSurface);
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 8, curY - 1, TALK_WIDTH, TALK_HEIGHT, extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk, (int)(curX + (8.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 1) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight, extraSurface, screenSurface);
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT, extraSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk, (int)(curX + (12.0f / 100) * factor_red[curY + curHeight]),
- curY, talkWidth, talkHeight, factor_red[curY + curHeight], extraSurface, screenSurface);
+ curY, TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], extraSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 2) {
if (currentChapter == 2)
- copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, talkWidth, talkHeight, frontSurface, screenSurface);
+ copyRect(x_talk_izq[face], y_mask_talk, curX + 12, curY, TALK_WIDTH, TALK_HEIGHT, frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_izq[face], y_mask_talk,
(int)(talkOffset + curX + (12.0f / 100) * factor_red[curY + curHeight]), curY,
- talkWidth, talkHeight, factor_red[curY + curHeight], frontSurface, screenSurface);
+ TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], frontSurface, screenSurface);
updateRefresh();
} else if (trackProtagonist == 3) {
if (currentChapter == 2)
- copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, talkWidth, talkHeight, frontSurface, screenSurface);
+ copyRect(x_talk_dch[face], y_mask_talk, curX + 8, curY, TALK_WIDTH, TALK_HEIGHT, frontSurface, screenSurface);
else
reduce_hare_chico(x_talk_dch[face], y_mask_talk,
(int)(talkOffset + curX + (8.0f / 100) * factor_red[curY + curHeight]), curY,
- talkWidth, talkHeight, factor_red[curY + curHeight], frontSurface, screenSurface);
+ TALK_WIDTH, TALK_HEIGHT, factor_red[curY + curHeight], frontSurface, screenSurface);
updateRefresh();
}
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 8140817eb3..975c6c2a21 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -418,6 +418,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
_sound->stopSound();
_sound->stopBackgroundMyst();
+ _video->stopVideos();
if (linkSrcSound)
_sound->playSoundBlocking(linkSrcSound);
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index f17d765c99..dc5f433ce7 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -691,6 +691,7 @@ void Myst::toggleVar(uint16 var) {
else
_state.courtyardImageBoxes |= mask;
}
+ break;
case 41: // Vault white page
if (_globals.ending != 4) {
if (_dockVaultState == 1) {
diff --git a/engines/mortevielle/actions.cpp b/engines/mortevielle/actions.cpp
index 2a66100e17..b68dd48b0f 100644
--- a/engines/mortevielle/actions.cpp
+++ b/engines/mortevielle/actions.cpp
@@ -91,31 +91,41 @@ void MortevielleEngine::fctMove() {
oldMenu = (_menu._moveMenu[menuChoice]._menuId << 8) | _menu._moveMenu[menuChoice]._actionId;
}
- if (_coreVar._currPlace == MOUNTAIN) {
+ switch (_coreVar._currPlace) {
+ case MOUNTAIN:
if (menuChoice == 1)
gotoManorFront();
else if (menuChoice == 2)
checkManorDistance();
_menu.setDestinationText(_coreVar._currPlace);
return;
- } else if (_coreVar._currPlace == INSIDE_WELL) {
+ case INSIDE_WELL:
if (menuChoice == 1)
floodedInWell();
else if (menuChoice == 2)
gotoManorBack();
_menu.setDestinationText(_coreVar._currPlace);
return;
- } else if ((_coreVar._currPlace == BUREAU) && (menuChoice == 1))
- menuChoice = 6;
- else if (_coreVar._currPlace == KITCHEN) {
+ case BUREAU:
+ if (menuChoice == 1)
+ menuChoice = 6;
+ break;
+ case KITCHEN:
if (menuChoice == 2)
menuChoice = 6;
else if (menuChoice == 5)
menuChoice = 16;
- } else if ((_coreVar._currPlace == CELLAR) && (menuChoice == 3))
- menuChoice = 6;
- else if (((_coreVar._currPlace == LANDING) || (_coreVar._currPlace == ROOM26)) && (menuChoice == 4))
- menuChoice = 6;
+ break;
+ case CELLAR:
+ if (menuChoice == 3)
+ menuChoice = 6;
+ break;
+ case LANDING:
+ case ROOM26:
+ if (menuChoice == 4)
+ menuChoice = 6;
+ break;
+ }
if ((_coreVar._currPlace > MOUNTAIN) && (_coreVar._currPlace != ROOM26))
menuChoice += 10;
@@ -132,32 +142,40 @@ void MortevielleEngine::fctMove() {
else if ((_coreVar._currPlace == WELL) && (menuChoice > 13) && (menuChoice != 17))
menuChoice = 15;
- if (menuChoice == 1)
+ switch (menuChoice) {
+ case 1:
_coreVar._currPlace = BUREAU;
- else if (menuChoice == 2)
+ break;
+ case 2:
_coreVar._currPlace = KITCHEN;
- else if (menuChoice == 3)
+ break;
+ case 3:
_coreVar._currPlace = CELLAR;
- else if (menuChoice == 4)
+ break;
+ case 4:
_coreVar._currPlace = LANDING;
- else if (menuChoice == 5)
- menuChoice = 12;
- else if (menuChoice == 6)
- menuChoice = 11;
-
- if (menuChoice == 11)
- gotoDiningRoom();
- else if (menuChoice == 12)
+ break;
+ case 5:
+ case 12:
gotoManorFront();
- else if (menuChoice == 13)
+ break;
+ case 6:
+ case 11:
+ gotoDiningRoom();
+ break;
+ case 13:
_coreVar._currPlace = CHAPEL;
- else if (menuChoice == 14)
+ break;
+ case 14:
_coreVar._currPlace = WELL;
- else if (menuChoice == 15)
+ break;
+ case 15:
checkManorDistance();
- else if (menuChoice == 16)
+ break;
+ case 16:
gotoManorBack();
- else if (menuChoice == 17) {
+ break;
+ case 17:
if ((_coreVar._wellObjectId != 120) && (_coreVar._wellObjectId != 140))
_crep = 997;
else if (_coreVar._wellObjectId == 120)
@@ -169,7 +187,9 @@ void MortevielleEngine::fctMove() {
_coreVar._currPlace = INSIDE_WELL;
prepareDisplayText();
}
+ break;
}
+
if ((menuChoice < 5) || (menuChoice == 13) || (menuChoice == 14))
prepareDisplayText();
resetRoomVariables(_coreVar._currPlace);
@@ -503,9 +523,12 @@ void MortevielleEngine::fctSearch() {
setCoordinates(7);
if (_num != 0) {
int i;
- for (i = 1; (i <= 6) && (_num != _openObjects[i]); i++)
- ;
- if (_num == _openObjects[i]) {
+ for (i = 1; i <= 6; i++) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
if (_currBitIndex > 0)
_coreVar._faithScore += 3;
@@ -584,7 +607,7 @@ void MortevielleEngine::fctOpen() {
if (_caff == ROOM26) {
if (_roomDoorId != OWN_ROOM) {
- _currAction = OPCODE_ENTER;
+ _currAction = _menu._opcodeEnter;
_syn = true;
} else
_crep = 997;
@@ -606,9 +629,20 @@ void MortevielleEngine::fctOpen() {
_coreVar._faithScore += 2;
++_openObjCount;
int i;
- for (i = 1; (i <= 6) && (_openObjects[i] != 0) && (_openObjects[i] != _num); i++)
- ;
- if (_openObjects[i] != _num) {
+ for (i = 1; (i <= 6); i++) {
+ if ((_openObjects[i] == 0) || (_openObjects[i] == _num))
+ break;
+ }
+
+ if (i > 6) {
+ warning("Unexpected action: Too many open objects");
+ return;
+ }
+
+ if (_openObjects[i] == _num)
+ // display "Already Opened"
+ _crep = 18;
+ else {
if (!( ((_num == 3) && ((_coreVar._currPlace == OWN_ROOM)
|| (_coreVar._currPlace == JULIA_ROOM)
|| (_coreVar._currPlace == BLUE_ROOM)
@@ -641,9 +675,7 @@ void MortevielleEngine::fctOpen() {
_crep = _tabdon[kAouvr + (tmpPlace * 7) + _num - 1];
if (_crep == 254)
_crep = 999;
- } else
- // display "Already Opened"
- _crep = 18;
+ }
}
}
@@ -702,10 +734,10 @@ void MortevielleEngine::fctPlace() {
_soundManager.startSpeech(6, -9, 1);
// Do you want to enter the hidden passage?
- int answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
if (answer == 1) {
Common::String alertTxt = getString(582);
- _dialogManager.show(alertTxt, 1);
+ _dialogManager.show(alertTxt);
bool enterPassageFl = _dialogManager.showKnowledgeCheck();
_mouse.hideMouse();
@@ -732,7 +764,7 @@ void MortevielleEngine::fctPlace() {
displayAnimFrame(1, 2);
displayAnimFrame(1, 1);
alertTxt = getString(577);
- _dialogManager.show(alertTxt, 1);
+ _dialogManager.show(alertTxt);
displayAnimFrame(2, 1);
_crep = 166;
}
@@ -801,7 +833,7 @@ void MortevielleEngine::fctTurn() {
if ((_coreVar._currPlace == ATTIC) && (_coreVar._atticRodHoleObjectId == 159) && (_coreVar._atticBallHoleObjectId == 141)) {
handleDescriptionText(2, 167);
_soundManager.startSpeech(7, 9, 1);
- int answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
if (answer == 1)
_endGame = true;
else
@@ -811,7 +843,7 @@ void MortevielleEngine::fctTurn() {
handleDescriptionText(2, 175);
clearVerbBar();
_soundManager.startSpeech(6, -9, 1);
- int answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
if (answer == 1) {
_coreVar._currPlace = CRYPT;
prepareDisplayText();
@@ -884,9 +916,12 @@ void MortevielleEngine::fctClose() {
setCoordinates(7);
if (_num != 0) {
int i;
- for (i = 1; (i <= 6) && (_num != _openObjects[i]); ++i)
- ;
- if (_num == _openObjects[i]) {
+ for (i = 1; i <= 6; ++i) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
displayAnimFrame(2, _num);
_crep = 998;
_openObjects[i] = 0;
@@ -914,7 +949,7 @@ void MortevielleEngine::fctKnock() {
displayTextInVerbBar(getEngineString(S_HIT));
if (_coreVar._currPlace == LANDING) {
- _dialogManager.show(getEngineString(S_BEFORE_USE_DEP_MENU), 1);
+ _dialogManager.show(getEngineString(S_BEFORE_USE_DEP_MENU));
return;
}
@@ -979,9 +1014,12 @@ void MortevielleEngine::fctSelfPut() {
_crep = 997;
else {
int i;
- for (i = 1; (i <= 6) && (_num != _openObjects[i]); i++)
- ;
- if (_num == _openObjects[i]) {
+ for (i = 1; i <= 6; i++) {
+ if (_num == _openObjects[i])
+ break;
+ }
+
+ if (i <= 6) {
_curSearchObjId = objId;
_crep = 999;
} else
@@ -1002,12 +1040,15 @@ void MortevielleEngine::fctSelfPut() {
if (_num == 1) {
if (_coreVar._atticBallHoleObjectId != 0)
_crep = 188;
- else
+ else {
_coreVar._atticBallHoleObjectId = _coreVar._selectedObjectId;
+ displayAnimFrame(1, 7);
+ }
} else if (_coreVar._atticRodHoleObjectId != 0) {
_crep = 188;
} else {
_coreVar._atticRodHoleObjectId = _coreVar._selectedObjectId;
+ displayAnimFrame(1, 6);
}
}
@@ -1220,7 +1261,7 @@ void MortevielleEngine::fctSleep() {
if (hour > 23)
hour = 0;
prepareRoom();
- answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ answer = _dialogManager.show(getEngineString(S_YES_NO));
_anyone = false;
} while (answer != 1);
_crep = 998;
@@ -1310,7 +1351,7 @@ void MortevielleEngine::fctWait() {
return;
}
handleDescriptionText(2, 102);
- answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ answer = _dialogManager.show(getEngineString(S_YES_NO));
} while (answer != 2);
_crep = 998;
if (!_anyone)
@@ -1408,7 +1449,7 @@ void MortevielleEngine::fctDiscuss() {
return;
_mouse.getMousePosition(x, y, click);
- x *= (3 - _resolutionScaler);
+ x *= (3 - kResolutionScaler);
if (x > 319)
cx = 41;
else
@@ -1626,7 +1667,7 @@ void MortevielleEngine::askRestart() {
_day = 0;
handleDescriptionText(2, 180);
- int answer = _dialogManager.show(getEngineString(S_YES_NO), 1);
+ int answer = _dialogManager.show(getEngineString(S_YES_NO));
_quitGame = (answer != 1);
}
diff --git a/engines/mortevielle/detection.cpp b/engines/mortevielle/detection.cpp
index 7d0f3c4d88..ee9cb40c99 100644
--- a/engines/mortevielle/detection.cpp
+++ b/engines/mortevielle/detection.cpp
@@ -30,12 +30,17 @@ namespace Mortevielle {
struct MortevielleGameDescription {
ADGameDescription desc;
Common::Language originalLanguage;
+ uint8 dataFeature;
};
uint32 MortevielleEngine::getGameFlags() const { return _gameDescription->desc.flags; }
Common::Language MortevielleEngine::getLanguage() const { return _gameDescription->desc.language; }
+Common::Language MortevielleEngine::getOriginalLanguage() const { return _gameDescription->originalLanguage; }
+
+bool MortevielleEngine::useOriginalData() const { return _gameDescription->dataFeature == kUseOriginalData; }
+
}
static const PlainGameDescriptor MortevielleGame[] = {
@@ -51,6 +56,9 @@ public:
MortevielleGame) {
_md5Bytes = 512;
_singleid = "mortevielle";
+ // Use kADFlagUseExtraAsHint to distinguish between original and improved versions
+ // (i.e. use or not of the game data file).
+ _flags = kADFlagUseExtraAsHint;
}
virtual const char *getName() const {
return "Mortevielle";
diff --git a/engines/mortevielle/detection_tables.h b/engines/mortevielle/detection_tables.h
index 9bb5fbea87..8d0cd5630c 100644
--- a/engines/mortevielle/detection_tables.h
+++ b/engines/mortevielle/detection_tables.h
@@ -37,7 +37,7 @@ static const MortevielleGameDescription MortevielleGameDescriptions[] = {
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO0()
- }, Common::FR_FRA
+ }, Common::FR_FRA, kUseOriginalData
},
// German
{
@@ -53,7 +53,24 @@ static const MortevielleGameDescription MortevielleGameDescriptions[] = {
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO0()
- }, Common::DE_DEU
+ }, Common::DE_DEU, kUseOriginalData
+ },
+
+ // German, improved translation
+ {
+ {
+ "mortevielle",
+ "Improved Translation",
+ {
+ {"menual.mor", 0, "792aea282b07a1d74c4a4abeabc90c19", 144},
+ {"dxx.mor", 0, "949e68e829ecd5ad29e36a00347a9e7e", 207744},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ }, Common::DE_DEU, kUseEngineDataFile
},
// DOS English version doesn't exist. Technically, they are French or German versions,
@@ -73,7 +90,7 @@ static const MortevielleGameDescription MortevielleGameDescriptions[] = {
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO0()
- }, Common::FR_FRA
+ }, Common::FR_FRA, kUseEngineDataFile
},
// English on top of German version
@@ -90,10 +107,10 @@ static const MortevielleGameDescription MortevielleGameDescriptions[] = {
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO0()
- }, Common::DE_DEU
+ }, Common::DE_DEU, kUseEngineDataFile
},
- { AD_TABLE_END_MARKER , Common::EN_ANY}
+ { AD_TABLE_END_MARKER , Common::EN_ANY, kUseEngineDataFile}
};
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/dialogs.cpp b/engines/mortevielle/dialogs.cpp
index abaf38c59b..9a2ade60ab 100644
--- a/engines/mortevielle/dialogs.cpp
+++ b/engines/mortevielle/dialogs.cpp
@@ -39,7 +39,7 @@ namespace Mortevielle {
* Alert function - Show
* @remarks Originally called 'do_alert'
*/
-int DialogManager::show(const Common::String &msg, int n) {
+int DialogManager::show(const Common::String &msg) {
// Make a copy of the current screen surface for later restore
_vm->_backgroundSurface.copyFrom(_vm->_screenSurface);
@@ -57,13 +57,12 @@ int DialogManager::show(const Common::String &msg, int n) {
decodeAlertDetails(msg, caseNumb, lignNumb, colNumb, alertStr, caseStr);
- int i = 0;
Common::Point curPos;
if (alertStr == "") {
drawAlertBox(10, 5, colNumb);
} else {
drawAlertBox(8, 7, colNumb);
- i = 0;
+ int i = 0;
_vm->_screenSurface._textPos.y = 70;
do {
curPos.x = 320;
@@ -71,10 +70,7 @@ int DialogManager::show(const Common::String &msg, int n) {
while ((alertStr[i + 1] != '\174') && (alertStr[i + 1] != '\135')) {
++i;
displayStr += alertStr[i];
- if (_vm->_resolutionScaler == 2)
- curPos.x -= 3;
- else
- curPos.x -= 5;
+ curPos.x -= 3;
}
_vm->_screenSurface.putxy(curPos.x, _vm->_screenSurface._textPos.y);
_vm->_screenSurface._textPos.y += 6;
@@ -95,12 +91,12 @@ int DialogManager::show(const Common::String &msg, int n) {
int limit[3][3];
memset(&limit[0][0], 0, sizeof(int) * 3 * 3);
- limit[1][1] = ((uint)(coldep) / 2) * _vm->_resolutionScaler;
+ limit[1][1] = ((uint)(coldep) / 2) * kResolutionScaler;
limit[1][2] = limit[1][1] + 40;
if (caseNumb == 1) {
limit[2][1] = limit[2][2];
} else {
- limit[2][1] = ((uint)(320 + ((uint)esp >> 1)) / 2) * _vm->_resolutionScaler;
+ limit[2][1] = ((uint)(320 + ((uint)esp >> 1)) / 2) * kResolutionScaler;
limit[2][2] = (limit[2][1]) + 40;
}
_vm->_mouse.showMouse();
@@ -168,10 +164,10 @@ int DialogManager::show(const Common::String &msg, int n) {
_vm->setMouseClick(false);
_vm->_mouse.hideMouse();
if (!test3) {
- id = n;
- setPosition(n, coldep, esp);
+ id = 1;
+ setPosition(1, coldep, esp);
Common::String tmp4(" ");
- tmp4 += buttonStr[n];
+ tmp4 += buttonStr[1];
tmp4 += " ";
_vm->_screenSurface.drawString(tmp4, 1);
}
@@ -221,10 +217,7 @@ void DialogManager::decodeAlertDetails(Common::String inputStr, int &choiceNumb,
}
choiceListStr = Common::String(inputStr.c_str() + i);
- if (_vm->_resolutionScaler == 2)
- col *= 6;
- else
- col *= 10;
+ col *= 6;
}
void DialogManager::setPosition(int ji, int coldep, int esp) {
@@ -235,13 +228,13 @@ void DialogManager::setPosition(int ji, int coldep, int esp) {
* Alert function - Draw Alert Box
* @remarks Originally called 'fait_boite'
*/
-void DialogManager::drawAlertBox(int lidep, int nli, int tx) {
- if (tx > 640)
- tx = 640;
- int x = 320 - ((uint)tx / 2);
- int y = (lidep - 1) * 8;
- int xx = x + tx;
- int yy = y + (nli * 8);
+void DialogManager::drawAlertBox(int firstLine, int lineNum, int width) {
+ if (width > 640)
+ width = 640;
+ int x = 320 - ((uint)width / 2);
+ int y = (firstLine - 1) * 8;
+ int xx = x + width;
+ int yy = y + (lineNum * 8);
_vm->_screenSurface.fillRect(15, Common::Rect(x, y, xx, yy));
_vm->_screenSurface.fillRect(0, Common::Rect(x, y + 2, xx, y + 4));
_vm->_screenSurface.fillRect(0, Common::Rect(x, yy - 4, xx, yy - 2));
@@ -302,11 +295,7 @@ bool DialogManager::showKnowledgeCheck() {
_vm->_mouse.hideMouse();
_vm->clearScreen();
_vm->_mouse.showMouse();
- int dialogHeight;
- if (_vm->_resolutionScaler == 1)
- dialogHeight = 29;
- else
- dialogHeight = 23;
+ int dialogHeight = 23;
_vm->_screenSurface.fillRect(15, Common::Rect(0, 14, 630, dialogHeight));
Common::String tmpStr = _vm->getString(textIndexArr[indx]);
_vm->_text.displayStr(tmpStr, 20, 15, 100, 2, 0);
@@ -335,7 +324,7 @@ bool DialogManager::showKnowledgeCheck() {
}
for (int j = 1; j <= lastOption - firstOption + 1; ++j) {
- coor[j]._rect = Common::Rect(45 * _vm->_resolutionScaler, 27 + j * 8, (maxLength * 3 + 55) * _vm->_resolutionScaler, 34 + j * 8);
+ coor[j]._rect = Common::Rect(45 * kResolutionScaler, 27 + j * 8, (maxLength * 3 + 55) * kResolutionScaler, 34 + j * 8);
coor[j]._enabled = true;
while ((int)choiceArray[j].size() < maxLength) {
@@ -343,11 +332,7 @@ bool DialogManager::showKnowledgeCheck() {
}
}
coor[lastOption - firstOption + 2]._enabled = false;
- int rep;
- if (_vm->_resolutionScaler == 1)
- rep = 10;
- else
- rep = 6;
+ int rep = 6;
_vm->_screenSurface.drawBox(80, 33, 40 + (maxLength * rep), (lastOption - firstOption) * 8 + 16, 15);
rep = 0;
@@ -431,12 +416,6 @@ void DialogManager::checkForF8(int SpeechNum, bool drawFrame2Fl) {
_vm->_key = waitForF3F8();
if (_vm->shouldQuit())
return;
-
- if (_vm->_newGraphicalDevice != _vm->_currGraphicalDevice) {
- _vm->_currGraphicalDevice = _vm->_newGraphicalDevice;
- _vm->clearScreen();
- displayIntroScreen(drawFrame2Fl);
- }
} while (_vm->_key != 66); // keycode for F8
}
@@ -483,7 +462,7 @@ void DialogManager::displayIntroFrame2() {
_vm->displayPicture(&_vm->_curAnim[_vm->_crep], 63, 12);
_vm->_crep = _vm->getAnimOffset(2, 1);
_vm->displayPicture(&_vm->_curAnim[_vm->_crep], 63, 12);
- _vm->_largestClearScreen = (_vm->_resolutionScaler == 1);
+ _vm->_largestClearScreen = false;
_vm->handleDescriptionText(2, kDialogStringIndex + 143);
}
diff --git a/engines/mortevielle/dialogs.h b/engines/mortevielle/dialogs.h
index af667e40c5..3f30851960 100644
--- a/engines/mortevielle/dialogs.h
+++ b/engines/mortevielle/dialogs.h
@@ -48,11 +48,11 @@ private:
void decodeAlertDetails(Common::String inputStr, int &choiceNumb, int &lineNumb, int &col, Common::String &choiceStr, Common::String &choiceListStr);
void setPosition(int ji, int coldep, int esp);
- void drawAlertBox(int lidep, int nli, int tx);
+ void drawAlertBox(int firstLine, int lineNum, int width);
void setButtonText(Common::String c, int coldep, int nbcase, Common::String *str, int esp);
public:
void setParent(MortevielleEngine *vm);
- int show(const Common::String &msg, int n);
+ int show(const Common::String &msg);
void drawF3F8();
void checkForF8(int SpeechNum, bool drawFrame2Fl);
int waitForF3F8();
diff --git a/engines/mortevielle/graphics.cpp b/engines/mortevielle/graphics.cpp
index 059f5a9be8..daf7926438 100644
--- a/engines/mortevielle/graphics.cpp
+++ b/engines/mortevielle/graphics.cpp
@@ -1015,11 +1015,6 @@ void ScreenSurface::writeCharacter(const Common::Point &pt, unsigned char ch, in
* simulate the original 640x400 surface, all Y values have to be doubled
*/
void ScreenSurface::drawBox(int x, int y, int dx, int dy, int col) {
- if (_vm->_resolutionScaler == 1) {
- x = (uint)x >> 1;
- dx = (uint)dx >> 1;
- }
-
Graphics::Surface destSurface = lockArea(Common::Rect(x, y * 2, x + dx, (y + dy) * 2));
destSurface.hLine(0, 0, dx, col);
@@ -1078,11 +1073,7 @@ void ScreenSurface::drawString(const Common::String &l, int command) {
_vm->_mouse.hideMouse();
Common::Point pt = _textPos;
- int charWidth;
- if (_vm->_resolutionScaler == 2)
- charWidth = 6;
- else
- charWidth = 10;
+ int charWidth = 6;
int x = pt.x + charWidth * l.size();
int color = 0;
@@ -1118,7 +1109,7 @@ void ScreenSurface::drawString(const Common::String &l, int command) {
* Gets the width in pixels of the specified string
*/
int ScreenSurface::getStringWidth(const Common::String &s) {
- int charWidth = (_vm->_resolutionScaler == 2) ? 6 : 10;
+ int charWidth = 6;
return s.size() * charWidth;
}
@@ -1165,13 +1156,7 @@ void ScreenSurface::drawLine(int x, int y, int xx, int yy, int coul) {
* @remarks Originally called 'paint_rect'
*/
void ScreenSurface::drawRectangle(int x, int y, int dx, int dy) {
- int co;
-
- if (_vm->_currGraphicalDevice == MODE_CGA)
- co = 3;
- else
- co = 11;
- _vm->_screenSurface.fillRect(co, Common::Rect(x, y, x + dx, y + dy));
+ _vm->_screenSurface.fillRect(11, Common::Rect(x, y, x + dx, y + dy));
}
void ScreenSurface::setParent(MortevielleEngine *vm) {
diff --git a/engines/mortevielle/menu.cpp b/engines/mortevielle/menu.cpp
index f32c551ddb..641a527c98 100644
--- a/engines/mortevielle/menu.cpp
+++ b/engines/mortevielle/menu.cpp
@@ -48,34 +48,164 @@ const byte menuConstants[8][4] = {
{62, 46, 13, 10}
};
+Menu::Menu() {
+ _opcodeAttach = _opcodeWait = _opcodeForce = _opcodeSleep = OPCODE_NONE;
+ _opcodeListen = _opcodeEnter = _opcodeClose = _opcodeSearch = OPCODE_NONE;
+ _opcodeKnock = _opcodeScratch = _opcodeRead = _opcodeEat = OPCODE_NONE;
+ _opcodePlace = _opcodeOpen = _opcodeTake = _opcodeLook = OPCODE_NONE;
+ _opcodeSmell = _opcodeSound = _opcodeLeave = _opcodeLift = OPCODE_NONE;
+ _opcodeTurn = _opcodeSHide = _opcodeSSearch = _opcodeSRead = OPCODE_NONE;
+ _opcodeSPut = _opcodeSLook = OPCODE_NONE;
+}
+
+void Menu::readVerbNums(Common::File &f, int dataSize) {
+ // Figure out what language Id is needed
+ byte desiredLanguageId;
+ switch(_vm->getLanguage()) {
+ case Common::EN_ANY:
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ case Common::FR_FRA:
+ desiredLanguageId = MORTDAT_LANG_FRENCH;
+ break;
+ case Common::DE_DEU:
+ desiredLanguageId = MORTDAT_LANG_GERMAN;
+ break;
+ default:
+ warning("Language not supported, switching to English");
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ }
+ // Read in the language
+ byte languageId = f.readByte();
+ --dataSize;
+
+ // If the language isn't correct, then skip the entire block
+ if (languageId != desiredLanguageId) {
+ f.skip(dataSize);
+ return;
+ }
+
+ assert(dataSize == 52);
+ _opcodeAttach = f.readUint16LE();
+ _opcodeWait = f.readUint16LE();
+ _opcodeForce = f.readUint16LE();
+ _opcodeSleep = f.readUint16LE();
+ _opcodeListen = f.readUint16LE();
+ _opcodeEnter = f.readUint16LE();
+ _opcodeClose = f.readUint16LE();
+ _opcodeSearch = f.readUint16LE();
+ _opcodeKnock = f.readUint16LE();
+ _opcodeScratch = f.readUint16LE();
+ _opcodeRead = f.readUint16LE();
+ _opcodeEat = f.readUint16LE();
+ _opcodePlace = f.readUint16LE();
+ _opcodeOpen = f.readUint16LE();
+ _opcodeTake = f.readUint16LE();
+ _opcodeLook = f.readUint16LE();
+ _opcodeSmell = f.readUint16LE();
+ _opcodeSound = f.readUint16LE();
+ _opcodeLeave = f.readUint16LE();
+ _opcodeLift = f.readUint16LE();
+ _opcodeTurn = f.readUint16LE();
+ _opcodeSHide = f.readUint16LE();
+ _opcodeSSearch = f.readUint16LE();
+ _opcodeSRead = f.readUint16LE();
+ _opcodeSPut = f.readUint16LE();
+ _opcodeSLook = f.readUint16LE();
+
+ _actionMenu[0]._menuId = OPCODE_NONE >> 8;
+ _actionMenu[0]._actionId = OPCODE_NONE & 0xFF;
+
+ _actionMenu[1]._menuId = _opcodeSHide >> 8;
+ _actionMenu[1]._actionId = _opcodeSHide & 0xFF;
+
+ _actionMenu[2]._menuId = _opcodeAttach >> 8;
+ _actionMenu[2]._actionId = _opcodeAttach & 0xFF;
+
+ _actionMenu[3]._menuId = _opcodeForce >> 8;
+ _actionMenu[3]._actionId = _opcodeForce & 0xFF;
+
+ _actionMenu[4]._menuId = _opcodeSleep >> 8;
+ _actionMenu[4]._actionId = _opcodeSleep & 0xFF;
+
+ _actionMenu[5]._menuId = _opcodeEnter >> 8;
+ _actionMenu[5]._actionId = _opcodeEnter & 0xFF;
+
+ _actionMenu[6]._menuId = _opcodeClose >> 8;
+ _actionMenu[6]._actionId = _opcodeClose & 0xFF;
+
+ _actionMenu[7]._menuId = _opcodeKnock >> 8;
+ _actionMenu[7]._actionId = _opcodeKnock & 0xFF;
+
+ _actionMenu[8]._menuId = _opcodeEat >> 8;
+ _actionMenu[8]._actionId = _opcodeEat & 0xFF;
+
+ _actionMenu[9]._menuId = _opcodePlace >> 8;
+ _actionMenu[9]._actionId = _opcodePlace & 0xFF;
+
+ _actionMenu[10]._menuId = _opcodeOpen >> 8;
+ _actionMenu[10]._actionId = _opcodeOpen & 0xFF;
+
+ _actionMenu[11]._menuId = _opcodeLeave >> 8;
+ _actionMenu[11]._actionId = _opcodeLeave & 0xFF;
+}
+
/**
* Setup a menu's contents
* @remarks Originally called 'menut'
*/
-void Menu::setText(int menuId, int actionId, Common::String name) {
+void Menu::setText(MenuItem item, Common::String name) {
Common::String s = name;
- while (s.size() < 22)
- s += ' ';
-
- switch (menuId) {
+ switch (item._menuId) {
case MENU_INVENTORY:
- if (actionId != 7) {
- _inventoryStringArray[actionId] = s;
- _inventoryStringArray[actionId].insertChar(' ', 0);
+ if (item._actionId != 7) {
+ while (s.size() < 22)
+ s += ' ';
+
+ _inventoryStringArray[item._actionId] = s;
+ _inventoryStringArray[item._actionId].insertChar(' ', 0);
}
break;
- case MENU_MOVE:
- _moveStringArray[actionId] = s;
+ case MENU_MOVE: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 22)
+ s += ' ';
+
+ _moveStringArray[item._actionId] = s;
+ }
break;
- case MENU_ACTION:
- _actionStringArray[actionId] = s;
+ case MENU_ACTION: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 10)
+ s += ' ';
+
+ _actionStringArray[item._actionId] = s;
+ }
break;
- case MENU_SELF:
- _selfStringArray[actionId] = s;
+ case MENU_SELF: {
+ // If the first character isn't '*' or ' ' then it's missing a heading space
+ char c = s[0];
+ if (c != '*' && c != ' ')
+ s.insertChar(' ', 0);
+
+ while (s.size() < 10)
+ s += ' ';
+
+ _selfStringArray[item._actionId] = s;
+ }
break;
case MENU_DISCUSS:
- _discussStringArray[actionId] = s;
+ _discussStringArray[item._actionId] = s;
break;
default:
break;
@@ -89,7 +219,7 @@ void Menu::setText(int menuId, int actionId, Common::String name) {
void Menu::setDestinationText(int roomId) {
Common::String nomp;
- if (roomId == 26)
+ if (roomId == ROOM26)
roomId = LANDING;
int destinationId = 0;
@@ -97,11 +227,11 @@ void Menu::setDestinationText(int roomId) {
nomp = _vm->getString(_vm->_destinationArray[destinationId][roomId] + kMenuPlaceStringIndex);
while (nomp.size() < 20)
nomp += ' ';
- setText(_moveMenu[destinationId + 1]._menuId, _moveMenu[destinationId + 1]._actionId, nomp);
+ setText(_moveMenu[destinationId + 1], nomp);
}
nomp = "* ";
for (int i = 7; i >= destinationId + 1; --i)
- setText(_moveMenu[i]._menuId, _moveMenu[i]._actionId, nomp);
+ setText(_moveMenu[i], nomp);
}
/**
@@ -109,26 +239,26 @@ void Menu::setDestinationText(int roomId) {
* @param menuId Menu number
* @param actionId Item index
*/
-void Menu::disableMenuItem(int menuId, int actionId) {
- switch (menuId) {
+void Menu::disableMenuItem(MenuItem item) {
+ switch (item._menuId) {
case MENU_INVENTORY:
- if (actionId > 6) {
- _inventoryStringArray[actionId].setChar('<', 0);
- _inventoryStringArray[actionId].setChar('>', 21);
+ if (item._actionId > 6) {
+ _inventoryStringArray[item._actionId].setChar('<', 0);
+ _inventoryStringArray[item._actionId].setChar('>', 21);
} else
- _inventoryStringArray[actionId].setChar('*', 0);
+ _inventoryStringArray[item._actionId].setChar('*', 0);
break;
case MENU_MOVE:
- _moveStringArray[actionId].setChar('*', 0);
+ _moveStringArray[item._actionId].setChar('*', 0);
break;
case MENU_ACTION:
- _actionStringArray[actionId].setChar('*', 0);
+ _actionStringArray[item._actionId].setChar('*', 0);
break;
case MENU_SELF:
- _selfStringArray[actionId].setChar('*', 0);
+ _selfStringArray[item._actionId].setChar('*', 0);
break;
case MENU_DISCUSS:
- _discussStringArray[actionId].setChar('*', 0);
+ _discussStringArray[item._actionId].setChar('*', 0);
break;
default:
break;
@@ -141,25 +271,23 @@ void Menu::disableMenuItem(int menuId, int actionId) {
* @param actionId Item index
* @remarks Originally called menu_enable
*/
-void Menu::enableMenuItem(int menuId, int actionId) {
- switch (menuId) {
+void Menu::enableMenuItem(MenuItem item) {
+ switch (item._menuId) {
case MENU_INVENTORY:
- _inventoryStringArray[actionId].setChar(' ', 0);
- _inventoryStringArray[actionId].setChar(' ', 21);
+ _inventoryStringArray[item._actionId].setChar(' ', 0);
+ _inventoryStringArray[item._actionId].setChar(' ', 21);
break;
case MENU_MOVE:
- _moveStringArray[actionId].setChar(' ', 0);
+ _moveStringArray[item._actionId].setChar(' ', 0);
break;
case MENU_ACTION:
- _actionStringArray[actionId].setChar(' ', 0);
+ _actionStringArray[item._actionId].setChar(' ', 0);
break;
case MENU_SELF:
- _selfStringArray[actionId].setChar(' ', 0);
- // The original sets two times the same value. Skipped
- // _selfStringArray[l].setChar(' ', 0);
+ _selfStringArray[item._actionId].setChar(' ', 0);
break;
case MENU_DISCUSS:
- _discussStringArray[actionId].setChar(' ', 0);
+ _discussStringArray[item._actionId].setChar(' ', 0);
break;
default:
break;
@@ -167,44 +295,33 @@ void Menu::enableMenuItem(int menuId, int actionId) {
}
void Menu::displayMenu() {
- int ind_tabl, k, col;
-
- int pt, x, y, color, msk, num_letr;
-
_vm->_mouse.hideMouse();
-
_vm->_screenSurface.fillRect(7, Common::Rect(0, 0, 639, 10));
- col = 28 * _vm->_resolutionScaler;
- if (_vm->_currGraphicalDevice == MODE_CGA)
- color = 1;
- else
- color = 9;
- num_letr = 0;
- do { // One character after the other
- ++num_letr;
- ind_tabl = 0;
- y = 1;
- do { // One column after the other
- k = 0;
- x = col;
- do { // One line after the other
- msk = 0x80;
- for (pt = 0; pt <= 7; ++pt) {
- if ((_charArr[num_letr - 1][ind_tabl] & msk) != 0) {
+
+ int col = 28 * kResolutionScaler;
+ for (int charNum = 0; charNum < 6; charNum++) {
+ // One character after the other
+ int idx = 0;
+ for (int y = 1; y < 9; ++y) {
+ // One column after the other
+ int x = col;
+ for (int k = 0; k < 3; ++k) {
+ // One line after the other
+ uint msk = 0x80;
+ for (int pt = 0; pt <= 7; ++pt) {
+ if ((_charArr[charNum][idx] & msk) != 0) {
_vm->_screenSurface.setPixel(Common::Point(x + 1, y + 1), 0);
_vm->_screenSurface.setPixel(Common::Point(x, y + 1), 0);
- _vm->_screenSurface.setPixel(Common::Point(x, y), color);
+ _vm->_screenSurface.setPixel(Common::Point(x, y), 9);
}
- msk = (uint)msk >> 1;
+ msk >>= 1;
++x;
}
- ++ind_tabl;
- ++k;
- } while (k != 3);
- ++y;
- } while (y != 9);
- col += 48 * _vm->_resolutionScaler;
- } while (num_letr != 6);
+ ++idx;
+ }
+ }
+ col += 48 * kResolutionScaler;
+ }
_vm->_mouse.showMouse();
}
@@ -280,16 +397,12 @@ void Menu::util(Common::Point pos) {
int ymx = (menuConstants[_msg3 - 1][3] << 3) + 16;
int dxcar = menuConstants[_msg3 - 1][2];
- int xmn = (menuConstants[_msg3 - 1][0] << 2) * _vm->_resolutionScaler;
+ int xmn = (menuConstants[_msg3 - 1][0] << 2) * kResolutionScaler;
- int ix;
- if (_vm->_resolutionScaler == 1)
- ix = 5;
- else
- ix = 3;
- int xmx = dxcar * ix * _vm->_resolutionScaler + xmn + 2;
+ int charWidth = 6;
+ int xmx = dxcar * charWidth + xmn + 2;
if ((pos.x > xmn) && (pos.x < xmx) && (pos.y < ymx) && (pos.y > 15)) {
- ix = (((uint)pos.y >> 3) - 1) + (_msg3 << 8);
+ int ix = (((uint)pos.y >> 3) - 1) + (_msg3 << 8);
if (ix != _msg4) {
invert(1);
_msg4 = ix;
@@ -305,79 +418,70 @@ void Menu::util(Common::Point pos) {
* Draw a menu
*/
void Menu::menuDown(int ii) {
- int cx, xcc, xco;
- int lignNumb;
-
// Make a copy of the current screen surface for later restore
_vm->_backgroundSurface.copyFrom(_vm->_screenSurface);
// Draw the menu
- xco = menuConstants[ii - 1][0];
- lignNumb = menuConstants[ii - 1][3];
+ int minX = menuConstants[ii - 1][0] << 3;
+ int lineNum = menuConstants[ii - 1][3];
_vm->_mouse.hideMouse();
- xco = xco << 3;
- if (_vm->_resolutionScaler == 1)
- cx = 10;
- else
- cx = 6;
- xcc = xco + (menuConstants[ii - 1][2] * cx) + 6;
+ int deltaX = 6;
+ int maxX = minX + (menuConstants[ii - 1][2] * deltaX) + 6;
if ((ii == 4) && (_vm->getLanguage() == Common::EN_ANY))
// Extra width needed for Self menu in English version
- xcc = 435;
-
- _vm->_screenSurface.fillRect(15, Common::Rect(xco, 12, xcc, 10 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.fillRect(0, Common::Rect(xcc, 12, xcc + 4, 10 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.fillRect(0, Common::Rect(xco, 8 + (menuConstants[ii - 1][1] << 1), xcc + 4, 12 + (menuConstants[ii - 1][1] << 1)));
- _vm->_screenSurface.putxy(xco, 16);
- cx = 0;
- do {
- ++cx;
+ maxX = 435;
+
+ _vm->_screenSurface.fillRect(15, Common::Rect(minX, 12, maxX, 10 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface.fillRect(0, Common::Rect(maxX, 12, maxX + 4, 10 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface.fillRect(0, Common::Rect(minX, 8 + (menuConstants[ii - 1][1] << 1), maxX + 4, 12 + (menuConstants[ii - 1][1] << 1)));
+ _vm->_screenSurface.putxy(minX, 16);
+ for (int i = 1; i <= lineNum; i++) {
switch (ii) {
case 1:
- if (_inventoryStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_inventoryStringArray[cx], 4);
+ if (_inventoryStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_inventoryStringArray[i], 4);
break;
case 2:
- if (_moveStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_moveStringArray[cx], 4);
+ if (_moveStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_moveStringArray[i], 4);
break;
case 3:
- if (_actionStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_actionStringArray[cx], 4);
+ if (_actionStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_actionStringArray[i], 4);
break;
case 4:
- if (_selfStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_selfStringArray[cx], 4);
+ if (_selfStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_selfStringArray[i], 4);
break;
case 5:
- if (_discussStringArray[cx][0] != '*')
- _vm->_screenSurface.drawString(_discussStringArray[cx], 4);
+ if (_discussStringArray[i][0] != '*')
+ _vm->_screenSurface.drawString(_discussStringArray[i], 4);
break;
case 6:
- _vm->_screenSurface.drawString(_vm->getEngineString(S_SAVE_LOAD + cx), 4);
+ _vm->_screenSurface.drawString(_vm->getEngineString(S_SAVE_LOAD + i), 4);
break;
case 7: {
Common::String s = _vm->getEngineString(S_SAVE_LOAD + 1);
s += ' ';
- s += (char)(48 + cx);
+ s += (char)(48 + i);
_vm->_screenSurface.drawString(s, 4);
}
break;
case 8:
- if (cx == 1)
+ if (i == 1)
_vm->_screenSurface.drawString(_vm->getEngineString(S_RESTART), 4);
else {
Common::String s = _vm->getEngineString(S_SAVE_LOAD + 2);
s += ' ';
- s += (char)(47 + cx);
+ s += (char)(47 + i);
_vm->_screenSurface.drawString(s, 4);
}
break;
default:
break;
}
- _vm->_screenSurface.putxy(xco, _vm->_screenSurface._textPos.y + 8);
- } while (cx != lignNumb);
+ _vm->_screenSurface.putxy(minX, _vm->_screenSurface._textPos.y + 8);
+ }
_multiTitle = true;
_vm->_mouse.showMouse();
}
@@ -427,24 +531,24 @@ void Menu::updateMenu() {
_vm->_prevPos = curPos;
bool tes = (curPos.y < 11)
- && ((curPos.x >= (28 * _vm->_resolutionScaler) && curPos.x <= (28 * _vm->_resolutionScaler + 24))
- || (curPos.x >= (76 * _vm->_resolutionScaler) && curPos.x <= (76 * _vm->_resolutionScaler + 24))
- || ((curPos.x > 124 * _vm->_resolutionScaler) && (curPos.x < 124 * _vm->_resolutionScaler + 24))
- || ((curPos.x > 172 * _vm->_resolutionScaler) && (curPos.x < 172 * _vm->_resolutionScaler + 24))
- || ((curPos.x > 220 * _vm->_resolutionScaler) && (curPos.x < 220 * _vm->_resolutionScaler + 24))
- || ((curPos.x > 268 * _vm->_resolutionScaler) && (curPos.x < 268 * _vm->_resolutionScaler + 24)));
+ && ((curPos.x >= (28 * kResolutionScaler) && curPos.x <= (28 * kResolutionScaler + 24))
+ || (curPos.x >= (76 * kResolutionScaler) && curPos.x <= (76 * kResolutionScaler + 24))
+ || ((curPos.x > 124 * kResolutionScaler) && (curPos.x < 124 * kResolutionScaler + 24))
+ || ((curPos.x > 172 * kResolutionScaler) && (curPos.x < 172 * kResolutionScaler + 24))
+ || ((curPos.x > 220 * kResolutionScaler) && (curPos.x < 220 * kResolutionScaler + 24))
+ || ((curPos.x > 268 * kResolutionScaler) && (curPos.x < 268 * kResolutionScaler + 24)));
if (tes) {
int ix;
- if (curPos.x < 76 * _vm->_resolutionScaler)
+ if (curPos.x < 76 * kResolutionScaler)
ix = MENU_INVENTORY;
- else if (curPos.x < 124 * _vm->_resolutionScaler)
+ else if (curPos.x < 124 * kResolutionScaler)
ix = MENU_MOVE;
- else if (curPos.x < 172 * _vm->_resolutionScaler)
+ else if (curPos.x < 172 * kResolutionScaler)
ix = MENU_ACTION;
- else if (curPos.x < 220 * _vm->_resolutionScaler)
+ else if (curPos.x < 220 * kResolutionScaler)
ix = MENU_SELF;
- else if (curPos.x < 268 * _vm->_resolutionScaler)
+ else if (curPos.x < 268 * kResolutionScaler)
ix = MENU_DISCUSS;
else
ix = MENU_FILE;
@@ -486,18 +590,37 @@ void Menu::updateMenu() {
}
}
-void Menu::initMenu(MortevielleEngine *vm) {
+void Menu::setParent(MortevielleEngine *vm) {
_vm = vm;
+}
- int i;
+void Menu::initMenu() {
Common::File f;
- bool enMenuLoaded = false;
- if (_vm->getLanguage() == Common::EN_ANY) {
- // Open the mort.dat file
+ bool menuLoaded = false;
+ // First try to read it from mort.dat if useOriginalData() is false
+ if (!_vm->useOriginalData()) {
if (!f.open(MORT_DAT))
warning("File %s not found. Using default menu from game data", MORT_DAT);
else {
+ // Figure out what language Id is needed
+ byte desiredLanguageId;
+ switch(_vm->getLanguage()) {
+ case Common::EN_ANY:
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ case Common::FR_FRA:
+ desiredLanguageId = MORTDAT_LANG_FRENCH;
+ break;
+ case Common::DE_DEU:
+ desiredLanguageId = MORTDAT_LANG_GERMAN;
+ break;
+ default:
+ warning("Language not supported, switching to English");
+ desiredLanguageId = MORTDAT_LANG_ENGLISH;
+ break;
+ }
+
// Validate the data file header
char fileId[4];
f.read(fileId, 4);
@@ -512,12 +635,20 @@ void Menu::initMenu(MortevielleEngine *vm) {
f.read(dataType, 4);
dataSize = f.readUint16LE();
if (!strncmp(dataType, "MENU", 4)) {
- // MENU section
- if (dataSize <= 7 * 24) {
+ // Read in the language
+ byte languageId = f.readByte();
+ --dataSize;
+
+ // If the language isn't correct, then skip the entire block
+ if (languageId != desiredLanguageId) {
+ f.skip(dataSize);
+ continue;
+ }
+ if (dataSize == 6 * 24) {
f.read(_charArr, dataSize);
- enMenuLoaded = true;
+ menuLoaded = true;
} else
- warning("Wrong size %d for menu data. Expected %d or less", dataSize, 7*24);
+ warning("Wrong size %d for menu data. Expected %d or less", dataSize, 6 * 24);
break;
} else {
// Other sections
@@ -527,46 +658,50 @@ void Menu::initMenu(MortevielleEngine *vm) {
}
// Close the file
f.close();
- if (!enMenuLoaded)
- warning("Failed to load English menu. Will use default menu from game data instead");
+ if (!menuLoaded)
+ warning("Failed to load menu from mort.dat. Will use default menu from game data instead.");
}
}
- if (!enMenuLoaded) {
- if (!f.open("menufr.mor"))
+ if (!menuLoaded) {
+ // Load menu from game data using the original language
+ if (_vm->getOriginalLanguage() == Common::FR_FRA) {
+ if (!f.open("menufr.mor"))
+ error("Missing file - menufr.mor");
+ } else { // Common::DE_DEU
if (!f.open("menual.mor"))
- if (!f.open("menu.mor"))
- error("Missing file - menufr.mor or menual.mor or menu.mor");
-
- f.read(_charArr, 7 * 24);
+ error("Missing file - menual.mor");
+ }
+ f.read(_charArr, 6 * 24);
f.close();
}
// Skipped: dialog asking to swap floppy
- for (i = 1; i <= 8; ++i)
+ for (int i = 1; i <= 8; ++i)
_inventoryStringArray[i] = "* ";
_inventoryStringArray[7] = "< -*-*-*-*-*-*-*-*-*- ";
- for (i = 1; i <= 7; ++i)
+ for (int i = 1; i <= 7; ++i)
_moveStringArray[i] = "* ";
- i = 1;
- do {
+ for (int i = 1; i < 22; i++) {
_actionStringArray[i] = _vm->getString(i + kMenuActionStringIndex);
-
+ if ((_actionStringArray[i][0] != '*') && (_actionStringArray[i][0] != ' '))
+ _actionStringArray[i].insertChar(' ', 0);
while (_actionStringArray[i].size() < 10)
_actionStringArray[i] += ' ';
if (i < 9) {
if (i < 6) {
_selfStringArray[i] = _vm->getString(i + kMenuSelfStringIndex);
+ if ((_selfStringArray[i][0] != '*') && (_selfStringArray[i][0] != ' '))
+ _selfStringArray[i].insertChar(' ', 0);
while (_selfStringArray[i].size() < 10)
_selfStringArray[i] += ' ';
}
_discussStringArray[i] = _vm->getString(i + kMenuSayStringIndex) + ' ';
}
- ++i;
- } while (i != 22);
- for (i = 1; i <= 8; ++i) {
+ }
+ for (int i = 1; i <= 8; ++i) {
_discussMenu[i]._menuId = MENU_DISCUSS;
_discussMenu[i]._actionId = i;
if (i < 8) {
@@ -576,7 +711,7 @@ void Menu::initMenu(MortevielleEngine *vm) {
_inventoryMenu[i]._menuId = MENU_INVENTORY;
_inventoryMenu[i]._actionId = i;
if (i > 6)
- disableMenuItem(_inventoryMenu[i]._menuId, _inventoryMenu[i]._actionId);
+ disableMenuItem(_inventoryMenu[i]);
}
_msg3 = OPCODE_NONE;
_msg4 = OPCODE_NONE;
@@ -591,13 +726,21 @@ void Menu::initMenu(MortevielleEngine *vm) {
*/
void Menu::setSearchMenu() {
for (int i = 1; i <= 7; ++i)
- disableMenuItem(MENU_MOVE, _moveMenu[i]._actionId);
+ disableMenuItem(_moveMenu[i]);
for (int i = 1; i <= 11; ++i)
- disableMenuItem(_actionMenu[i]._menuId, _actionMenu[i]._actionId);
+ disableMenuItem(_actionMenu[i]);
+
+ MenuItem miSound;
+ miSound._menuId = _opcodeSound >> 8;
+ miSound._actionId = _opcodeSound & 0xFF;
- setText(OPCODE_SOUND >> 8, OPCODE_SOUND & 0xFF, _vm->getEngineString(S_SUITE));
- setText(OPCODE_LIFT >> 8, OPCODE_LIFT & 0xFF, _vm->getEngineString(S_STOP));
+ MenuItem miLift;
+ miLift._menuId = _opcodeLift >> 8;
+ miLift._actionId = _opcodeLift & 0xFF;
+
+ setText(miSound, _vm->getEngineString(S_SUITE));
+ setText(miLift, _vm->getEngineString(S_STOP));
}
/**
@@ -607,10 +750,18 @@ void Menu::setSearchMenu() {
void Menu::unsetSearchMenu() {
setDestinationText(_vm->_coreVar._currPlace);
for (int i = 1; i <= 11; ++i)
- enableMenuItem(_actionMenu[i]._menuId, _actionMenu[i]._actionId);
+ enableMenuItem(_actionMenu[i]);
+
+ MenuItem miSound;
+ miSound._menuId = _opcodeSound >> 8;
+ miSound._actionId = _opcodeSound & 0xFF;
+
+ MenuItem miLift;
+ miLift._menuId = _opcodeLift >> 8;
+ miLift._actionId = _opcodeLift & 0xFF;
- setText(OPCODE_SOUND >> 8, OPCODE_SOUND & 0xFF, _vm->getEngineString(S_PROBE));
- setText(OPCODE_LIFT >> 8, OPCODE_LIFT & 0xFF, _vm->getEngineString(S_RAISE));
+ setText(miSound, _vm->getEngineString(S_PROBE));
+ setText(miLift, _vm->getEngineString(S_RAISE));
}
/**
@@ -626,15 +777,15 @@ void Menu::setInventoryText() {
++cy;
int r = _vm->_coreVar._inventory[i] + 400;
nomp = _vm->getString(r - 501 + kInventoryStringIndex);
- setText(_inventoryMenu[cy]._menuId, _inventoryMenu[cy]._actionId, nomp);
- enableMenuItem(_inventoryMenu[i]._menuId, _inventoryMenu[i]._actionId);
+ setText(_inventoryMenu[cy], nomp);
+ enableMenuItem(_inventoryMenu[i]);
}
}
if (cy < 6) {
for (int i = cy + 1; i <= 6; ++i) {
- setText(_inventoryMenu[i]._menuId, _inventoryMenu[i]._actionId, " ");
- disableMenuItem(_inventoryMenu[i]._menuId, _inventoryMenu[i]._actionId);
+ setText(_inventoryMenu[i], " ");
+ disableMenuItem(_inventoryMenu[i]);
}
}
}
diff --git a/engines/mortevielle/menu.h b/engines/mortevielle/menu.h
index 2428d8917b..debf5b09b6 100644
--- a/engines/mortevielle/menu.h
+++ b/engines/mortevielle/menu.h
@@ -40,45 +40,28 @@ enum {
MENU_LOAD = 8
};
-enum verbs {OPCODE_NONE = 0, OPCODE_ATTACH = 0x301, OPCODE_WAIT = 0x302, OPCODE_FORCE = 0x303, OPCODE_SLEEP = 0x304, OPCODE_LISTEN = 0x305,
-OPCODE_ENTER = 0x306, OPCODE_CLOSE = 0x307, OPCODE_SEARCH = 0x308, OPCODE_KNOCK = 0x309, OPCODE_SCRATCH = 0x30a,
-OPCODE_READ = 0x30b, OPCODE_EAT = 0x30c, OPCODE_PLACE = 0x30d, OPCODE_OPEN = 0x30e, OPCODE_TAKE = 0x30f,
-OPCODE_LOOK = 0x310, OPCODE_SMELL = 0x311, OPCODE_SOUND = 0x312, OPCODE_LEAVE = 0x313, OPCODE_LIFT = 0x314,
-OPCODE_TURN = 0x315, OPCODE_SHIDE = 0x401, OPCODE_SSEARCH = 0x402, OPCODE_SREAD = 0x403, OPCODE_SPUT = 0x404,
-OPCODE_SLOOK = 0x405};
-
-struct menuItem {
+const int OPCODE_NONE = 0;
+
+struct MenuItem {
int _menuId;
int _actionId;
};
-static const menuItem _actionMenu[12] = {
- {OPCODE_NONE >> 8, OPCODE_NONE & 0xFF},
- {OPCODE_SHIDE >> 8, OPCODE_SHIDE & 0xFF},
- {OPCODE_ATTACH >> 8, OPCODE_ATTACH & 0xFF},
- {OPCODE_FORCE >> 8, OPCODE_FORCE & 0xFF},
- {OPCODE_SLEEP >> 8, OPCODE_SLEEP & 0xFF},
- {OPCODE_ENTER >> 8, OPCODE_ENTER & 0xFF},
- {OPCODE_CLOSE >> 8, OPCODE_CLOSE & 0xFF},
- {OPCODE_KNOCK >> 8, OPCODE_KNOCK & 0xFF},
- {OPCODE_EAT >> 8, OPCODE_EAT & 0xFF},
- {OPCODE_PLACE >> 8, OPCODE_PLACE & 0xFF},
- {OPCODE_OPEN >> 8, OPCODE_OPEN & 0xFF},
- {OPCODE_LEAVE >> 8, OPCODE_LEAVE & 0xFF}
-};
-
class Menu {
private:
MortevielleEngine *_vm;
- byte _charArr[7][24];
+ byte _charArr[6][24];
int _msg3;
int _msg4;
void util(Common::Point pos);
void invert(int indx);
void menuDown(int ii);
+
public:
+ Menu();
+
bool _menuActive;
bool _menuSelected;
bool _multiTitle;
@@ -88,21 +71,51 @@ public:
Common::String _actionStringArray[22];
Common::String _selfStringArray[7];
Common::String _discussStringArray[9];
- menuItem _discussMenu[9];
- menuItem _inventoryMenu[9];
- menuItem _moveMenu[8];
-
- void setText(int menuId, int actionId, Common::String name);
+ MenuItem _discussMenu[9];
+ MenuItem _inventoryMenu[9];
+ MenuItem _moveMenu[8];
+
+ int _opcodeAttach;
+ int _opcodeWait;
+ int _opcodeForce;
+ int _opcodeSleep;
+ int _opcodeListen;
+ int _opcodeEnter;
+ int _opcodeClose;
+ int _opcodeSearch;
+ int _opcodeKnock;
+ int _opcodeScratch;
+ int _opcodeRead;
+ int _opcodeEat;
+ int _opcodePlace;
+ int _opcodeOpen;
+ int _opcodeTake;
+ int _opcodeLook;
+ int _opcodeSmell;
+ int _opcodeSound;
+ int _opcodeLeave;
+ int _opcodeLift;
+ int _opcodeTurn;
+ int _opcodeSHide;
+ int _opcodeSSearch;
+ int _opcodeSRead;
+ int _opcodeSPut;
+ int _opcodeSLook;
+ MenuItem _actionMenu[12];
+
+ void setParent(MortevielleEngine *vm);
+ void readVerbNums(Common::File &f, int dataSize);
+ void setText(MenuItem item, Common::String name);
void setDestinationText(int roomId);
void setInventoryText();
- void disableMenuItem(int menuId, int actionId);
- void enableMenuItem(int menuId, int actionId);
+ void disableMenuItem(MenuItem item);
+ void enableMenuItem(MenuItem item);
void displayMenu();
void drawMenu();
void menuUp(int msgId);
void eraseMenu();
void updateMenu();
- void initMenu(MortevielleEngine *vm);
+ void initMenu();
void setSearchMenu();
void unsetSearchMenu();
diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp
index 7b2a648221..f13f8cb65b 100644
--- a/engines/mortevielle/mortevielle.cpp
+++ b/engines/mortevielle/mortevielle.cpp
@@ -57,6 +57,7 @@ MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescr
_text.setParent(this);
_soundManager.setParent(this);
_savegameManager.setParent(this);
+ _menu.setParent(this);
_lastGameFrame = 0;
_mouseClick = false;
@@ -91,8 +92,6 @@ MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescr
_uptodatePresence = false;
_textColor = 0;
- _currGraphicalDevice = -1;
- _newGraphicalDevice = -1;
_place = -1;
_x26KeyCount = -1;
@@ -179,10 +178,6 @@ Common::ErrorCode MortevielleEngine::initialize() {
// Set up an intermediate screen surface
_screenSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
- // Set the screen mode
- _currGraphicalDevice = MODE_EGA;
- _resolutionScaler = 2;
-
_txxFileFl = false;
// Load texts from TXX files
loadTexts();
@@ -203,8 +198,6 @@ Common::ErrorCode MortevielleEngine::initialize() {
// Setup the mouse cursor
initMouse();
- _currGraphicalDevice = MODE_EGA;
- _newGraphicalDevice = _currGraphicalDevice;
loadPalette();
loadCFIPH();
loadCFIEC();
@@ -219,10 +212,7 @@ Common::ErrorCode MortevielleEngine::initialize() {
testKeyboard();
showConfigScreen();
- _newGraphicalDevice = _currGraphicalDevice;
testKeyboard();
- if (_newGraphicalDevice != _currGraphicalDevice)
- _currGraphicalDevice = _newGraphicalDevice;
clearScreen();
_soundManager.loadNoise();
@@ -273,6 +263,8 @@ Common::ErrorCode MortevielleEngine::loadMortDat() {
readStaticStrings(f, dataSize, kStaticStrings);
} else if ((!strncmp(dataType, "GSTR", 4)) && (!_txxFileFl)) {
readStaticStrings(f, dataSize, kGameStrings);
+ } else if (!strncmp(dataType, "VERB", 4)) {
+ _menu.readVerbNums(f, dataSize);
} else {
// Unknown section
f.skip(dataSize);
@@ -286,6 +278,7 @@ Common::ErrorCode MortevielleEngine::loadMortDat() {
return Common::kNoError;
}
+
/**
* Read in a static strings block, and if the language matches, load up the static strings
*/
@@ -354,10 +347,16 @@ Common::Error MortevielleEngine::run() {
if (loadSlot == 0)
// Show the game introduction
showIntroduction();
+ else {
+ _caff = 51;
+ _text.taffich();
+ }
// Either load the initial game state savegame, or the specified savegame number
adzon();
- _savegameManager.loadSavegame(generateSaveFilename(loadSlot));
+ resetVariables();
+ if (loadSlot != 0)
+ _savegameManager.loadSavegame(generateSaveFilename(loadSlot));
// Run the main game loop
mainGame();
@@ -400,7 +399,7 @@ void MortevielleEngine::mainGame() {
for (_crep = 1; _crep <= _x26KeyCount; ++_crep)
decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
- _menu.initMenu(this);
+ _menu.initMenu();
charToHour();
initGame();
diff --git a/engines/mortevielle/mortevielle.h b/engines/mortevielle/mortevielle.h
index 27a3d5697a..4c096c1f71 100644
--- a/engines/mortevielle/mortevielle.h
+++ b/engines/mortevielle/mortevielle.h
@@ -62,6 +62,11 @@ enum {
MORTDAT_LANG_GERMAN = 2
};
+enum {
+ kUseOriginalData = 0,
+ kUseEngineDataFile = 1
+};
+
// Static string list
enum {
S_YES_NO = 0, S_GO_TO = 1, S_SOMEONE_ENTERS = 2, S_COOL = 3, S_LOURDE = 4,
@@ -115,6 +120,7 @@ const int kMenuSelfStringIndex = 497;
const int kMenuSayStringIndex = 502;
const int kMaxPatt = 20;
+const int kResolutionScaler = 2;
/*
9 "A glance at the forbidden$",
18 "It's already open$",
@@ -129,18 +135,6 @@ enum Places {
DOOR = 25, ROOM26 = 26, COAT_ARMS = 27
};
-enum GraphicModes { MODE_AMSTRAD1512 = 0, MODE_CGA = 1, MODE_EGA = 2, MODE_HERCULES = 3, MODE_TANDY = 4 };
-
-struct nhom {
- byte _id; /* number between 0 and 32 */
- byte _hom[4];
-};
-
-struct CgaPalette {
- byte _p;
- nhom _a[16];
-};
-
struct Pattern {
byte _tay, _tax;
byte _des[kMaxPatt + 1][kMaxPatt + 1];
@@ -180,7 +174,6 @@ private:
Common::StringArray _engineStrings;
Common::StringArray _gameStrings;
- Pattern _patternArr[15];
int _menuOpcode;
bool _inMainGameLoop; // Flag when the main game loop is active
@@ -224,7 +217,6 @@ private:
int _startHour;
int _endHour;
Common::Point _stdPal[91][17];
- CgaPalette _cgaPal[91];
int _x26KeyCount;
int _roomDoorId;
@@ -257,7 +249,6 @@ private:
void mainGame();
void playGame();
void handleAction();
- void displayCGAPattern(int n, Pattern *p, nhom *pal);
void loadPalette();
void loadTexts();
void loadCFIEC();
@@ -278,7 +269,6 @@ private:
void getReadDescription(int objId);
void getSearchDescription(int objId);
int checkLeaveSecretPassage();
- void changeGraphicalDevice(int newDevice);
void startDialog(int16 rep);
void endSearch();
int convertCharacterIndexToBitIndex(int characterIndex);
@@ -419,8 +409,6 @@ public:
bool _blo;
bool _destinationOk;
bool _largestClearScreen;
- int _currGraphicalDevice;
- int _newGraphicalDevice;
float _addFix;
int _savedBitIndex;
int _numpal;
@@ -432,7 +420,6 @@ public:
int _caff;
int _crep;
- int _resolutionScaler;
byte _destinationArray[7][25];
byte *_curPict;
@@ -461,6 +448,8 @@ public:
virtual Common::Error run();
uint32 getGameFlags() const;
Common::Language getLanguage() const;
+ Common::Language getOriginalLanguage() const;
+ bool useOriginalData() const;
static Common::String generateSaveFilename(const Common::String &target, int slot);
Common::String generateSaveFilename(int slot) { return generateSaveFilename(_targetName, slot); }
diff --git a/engines/mortevielle/mouse.cpp b/engines/mortevielle/mouse.cpp
index dfc9ccd706..9eb4e129c0 100644
--- a/engines/mortevielle/mouse.cpp
+++ b/engines/mortevielle/mouse.cpp
@@ -65,8 +65,8 @@ void MouseHandler::showMouse() {
* @remarks Originally called 'pos_mouse'
*/
void MouseHandler::setMousePosition(Common::Point newPos) {
- if (newPos.x > 314 * _vm->_resolutionScaler)
- newPos.x = 314 * _vm->_resolutionScaler;
+ if (newPos.x > 314 * kResolutionScaler)
+ newPos.x = 314 * kResolutionScaler;
else if (newPos.x < 0)
newPos.x = 0;
if (newPos.y > 199)
@@ -138,16 +138,16 @@ void MouseHandler::moveMouse(bool &funct, char &key) {
cy = 190;
break;
case '9':
- cx = 315 * _vm->_resolutionScaler;
+ cx = 315 * kResolutionScaler;
cy = 1;
break;
case '3':
cy = 190;
- cx = 315 * _vm->_resolutionScaler;
+ cx = 315 * kResolutionScaler;
break;
case '5':
cy = 100;
- cx = 155 * _vm->_resolutionScaler;
+ cx = 155 * kResolutionScaler;
break;
case ' ':
case '\15':
@@ -201,27 +201,27 @@ void MouseHandler::moveMouse(bool &funct, char &key) {
}
break;
case 'I':
- cx = _vm->_resolutionScaler * 32;
+ cx = kResolutionScaler * 32;
cy = 8;
break;
case 'D':
- cx = 80 * _vm->_resolutionScaler;
+ cx = 80 * kResolutionScaler;
cy = 8;
break;
case 'A':
- cx = 126 * _vm->_resolutionScaler;
+ cx = 126 * kResolutionScaler;
cy = 8;
break;
case 'S':
- cx = 174 * _vm->_resolutionScaler;
+ cx = 174 * kResolutionScaler;
cy = 8;
break;
case 'P':
- cx = 222 * _vm->_resolutionScaler;
+ cx = 222 * kResolutionScaler;
cy = 8;
break;
case 'F':
- cx = _vm->_resolutionScaler * 270;
+ cx = kResolutionScaler * 270;
cy = 8;
break;
case '\23':
diff --git a/engines/mortevielle/outtext.cpp b/engines/mortevielle/outtext.cpp
index 99c06c7c4c..d50f4005de 100644
--- a/engines/mortevielle/outtext.cpp
+++ b/engines/mortevielle/outtext.cpp
@@ -53,7 +53,6 @@ int TextHandler::nextWord(int p, const char *ch, int &tab) {
* @remarks Originally called 'afftex'
*/
void TextHandler::displayStr(Common::String inputStr, int x, int y, int dx, int dy, int typ) {
- int tab;
Common::String s;
int i, j;
@@ -61,10 +60,7 @@ void TextHandler::displayStr(Common::String inputStr, int x, int y, int dx, int
inputStr += '$';
_vm->_screenSurface.putxy(x, y);
- if (_vm->_resolutionScaler == 1)
- tab = 10;
- else
- tab = 6;
+ int tab = 6;
dx *= 6;
dy *= 6;
int xc = x;
@@ -168,14 +164,11 @@ void TextHandler::loadAniFile(Common::String filename, int32 skipSize, int lengt
}
void TextHandler::taffich() {
- static const byte rang[16] = {15, 14, 11, 7, 13, 12, 10, 6, 9, 5, 3, 1, 2, 4, 8, 0};
-
static const byte tran1[] = { 121, 121, 138, 139, 120 };
static const byte tran2[] = { 150, 150, 152, 152, 100, 110, 159, 100, 100 };
int cx, drawingSize, npal;
int32 drawingStartPos;
- int alllum[16];
int a = _vm->_caff;
if ((a >= 153) && (a <= 161))
@@ -272,21 +265,6 @@ void TextHandler::taffich() {
npal = a + 37;
}
loadPictureFile(filename, altFilename, drawingStartPos, drawingSize);
- if (_vm->_currGraphicalDevice == MODE_HERCULES) {
- for (int i = 0; i <= 15; ++i) {
- int palh = READ_LE_UINT16(&_vm->_curPict[2 + (i << 1)]);
- alllum[i] = (palh & 15) + (((uint)palh >> 12) & 15) + (((uint)palh >> 8) & 15);
- }
- for (int i = 0; i <= 15; ++i) {
- int k = 0;
- for (int j = 0; j <= 15; ++j) {
- if (alllum[j] > alllum[k])
- k = j;
- }
- _vm->_curPict[2 + (k << 1)] = rang[i];
- alllum[k] = -1;
- }
- }
_vm->_numpal = npal;
_vm->setPal(npal);
@@ -314,7 +292,7 @@ void TextHandler::taffich() {
loadAniFile(filename, drawingStartPos, drawingSize);
}
_vm->_mouse.showMouse();
- if ((a < COAT_ARMS) && ((_vm->_maff < COAT_ARMS) || (_vm->_coreVar._currPlace == LANDING)) && (_vm->_currAction != OPCODE_ENTER)) {
+ if ((a < COAT_ARMS) && ((_vm->_maff < COAT_ARMS) || (_vm->_coreVar._currPlace == LANDING)) && (_vm->_currAction != _vm->_menu._opcodeEnter)) {
if ((a == ATTIC) || (a == CELLAR))
_vm->displayAloneText();
else if (!_vm->_blo)
diff --git a/engines/mortevielle/saveload.cpp b/engines/mortevielle/saveload.cpp
index 651ed07b65..c14a03cd60 100644
--- a/engines/mortevielle/saveload.cpp
+++ b/engines/mortevielle/saveload.cpp
@@ -72,15 +72,16 @@ void SavegameManager::sync_save(Common::Serializer &sz) {
* Inner code for loading a saved game
* @remarks Originally called 'takesav'
*/
-void SavegameManager::loadSavegame(const Common::String &filename) {
+bool SavegameManager::loadSavegame(const Common::String &filename) {
// Try loading first from the save area
Common::SeekableReadStream *stream = g_system->getSavefileManager()->openForLoading(filename);
Common::File f;
if (stream == NULL) {
- if (!f.open(filename))
- error("Unable to open save file '%s'", filename.c_str());
-
+ if (!f.open(filename)) {
+ warning("Unable to open save file '%s'", filename.c_str());
+ return false;
+ }
stream = f.readStream(f.size());
f.close();
}
@@ -107,6 +108,8 @@ void SavegameManager::loadSavegame(const Common::String &filename) {
// Close the stream
delete stream;
+
+ return true;
}
/**
@@ -115,14 +118,15 @@ void SavegameManager::loadSavegame(const Common::String &filename) {
Common::Error SavegameManager::loadGame(const Common::String &filename) {
g_vm->_mouse.hideMouse();
g_vm->displayEmptyHand();
- loadSavegame(filename);
-
- /* Initialization */
- g_vm->charToHour();
- g_vm->initGame();
- g_vm->gameLoaded();
- g_vm->_mouse.showMouse();
- return Common::kNoError;
+ if (loadSavegame(filename)) {
+ /* Initialization */
+ g_vm->charToHour();
+ g_vm->initGame();
+ g_vm->gameLoaded();
+ g_vm->_mouse.showMouse();
+ return Common::kNoError;
+ } else
+ return Common::kUnknownError;
}
/**
diff --git a/engines/mortevielle/saveload.h b/engines/mortevielle/saveload.h
index 0121a04d8e..79747e6889 100644
--- a/engines/mortevielle/saveload.h
+++ b/engines/mortevielle/saveload.h
@@ -57,7 +57,7 @@ private:
void sync_save(Common::Serializer &sz);
public:
void setParent(MortevielleEngine *vm);
- void loadSavegame(const Common::String &filename);
+ bool loadSavegame(const Common::String &filename);
Common::Error loadGame(const Common::String &filename);
Common::Error saveGame(int n, const Common::String &saveName);
Common::Error loadGame(int slot);
diff --git a/engines/mortevielle/sound.cpp b/engines/mortevielle/sound.cpp
index 3bea96b92f..b670246726 100644
--- a/engines/mortevielle/sound.cpp
+++ b/engines/mortevielle/sound.cpp
@@ -741,6 +741,10 @@ void SoundManager::startSpeech(int rep, int ht, int typ) {
uint16 savph[501];
int tempo;
+ // Hack to avoid a crash in the ending version. To be removed when the speech are implemented
+ if ((rep == 141) && (typ == 0))
+ return;
+
if (_vm->_soundOff)
return;
diff --git a/engines/mortevielle/utils.cpp b/engines/mortevielle/utils.cpp
index fff53dbc30..5ca29d849c 100644
--- a/engines/mortevielle/utils.cpp
+++ b/engines/mortevielle/utils.cpp
@@ -67,9 +67,10 @@ bool MortevielleEngine::keyPressed() {
* @remarks Originally called 'get_ch'
*/
int MortevielleEngine::getChar() {
+ bool end = false;
// If there isn't any pending keypress, wait until there is
- while (!shouldQuit() && _keypresses.empty()) {
- keyPressed();
+ while (!shouldQuit() && !end) {
+ end = keyPressed();
}
// Return the top keypress
@@ -283,10 +284,6 @@ void MortevielleEngine::handleAction() {
_menu.eraseMenu();
_menu._menuDisplayed = false;
- if ((inkey == '\1') || (inkey == '\3') || (inkey == '\5') || (inkey == '\7') || (inkey == '\11')) {
- changeGraphicalDevice((uint)((int)inkey - 1) >> 1);
- return;
- }
if (_menu._menuSelected && (_currMenu == MENU_SAVE)) {
Common::String saveName = Common::String::format("Savegame #%d", _currAction & 15);
_savegameManager.saveGame(_currAction & 15, saveName);
@@ -294,7 +291,7 @@ void MortevielleEngine::handleAction() {
if (_menu._menuSelected && (_currMenu == MENU_LOAD))
_savegameManager.loadGame((_currAction & 15) - 1);
if (inkey == '\103') { /* F9 */
- temps = _dialogManager.show(_hintPctMessage, 1);
+ temps = _dialogManager.show(_hintPctMessage);
return;
} else if (inkey == '\77') {
if ((_menuOpcode != OPCODE_NONE) && ((_currMenu == MENU_ACTION) || (_currMenu == MENU_SELF))) {
@@ -327,9 +324,9 @@ void MortevielleEngine::handleAction() {
if (_mouse._pos.y < 12)
return;
- if ((_currAction == OPCODE_SOUND) || (_currAction == OPCODE_LIFT)) {
+ if ((_currAction == _menu._opcodeSound) || (_currAction == _menu._opcodeLift)) {
handledOpcodeFl = true;
- if ((_currAction == OPCODE_LIFT) || (_obpart)) {
+ if ((_currAction == _menu._opcodeLift) || (_obpart)) {
endSearch();
_caff = _coreVar._currPlace;
_crep = 998;
@@ -506,48 +503,48 @@ void MortevielleEngine::showPeoplePresent(int bitIndex) {
int xp = 580 - (_screenSurface.getStringWidth("LEO") / 2);
for (int i = 1; i <= 8; ++i)
- _menu.disableMenuItem(_menu._discussMenu[i]._menuId, _menu._discussMenu[i]._actionId);
+ _menu.disableMenuItem(_menu._discussMenu[i]);
clearUpperRightPart();
if ((bitIndex & 128) == 128) {
_screenSurface.putxy(xp, 24);
_screenSurface.drawString("LEO", 4);
- _menu.enableMenuItem(_menu._discussMenu[1]._menuId, _menu._discussMenu[1]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[1]);
}
if ((bitIndex & 64) == 64) {
_screenSurface.putxy(xp, 32);
_screenSurface.drawString("PAT", 4);
- _menu.enableMenuItem(_menu._discussMenu[2]._menuId, _menu._discussMenu[2]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[2]);
}
if ((bitIndex & 32) == 32) {
_screenSurface.putxy(xp, 40);
_screenSurface.drawString("GUY", 4);
- _menu.enableMenuItem(_menu._discussMenu[3]._menuId, _menu._discussMenu[3]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[3]);
}
if ((bitIndex & 16) == 16) {
_screenSurface.putxy(xp, 48);
_screenSurface.drawString("EVA", 4);
- _menu.enableMenuItem(_menu._discussMenu[4]._menuId, _menu._discussMenu[4]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[4]);
}
if ((bitIndex & 8) == 8) {
_screenSurface.putxy(xp, 56);
_screenSurface.drawString("BOB", 4);
- _menu.enableMenuItem(_menu._discussMenu[5]._menuId, _menu._discussMenu[5]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[5]);
}
if ((bitIndex & 4) == 4) {
_screenSurface.putxy(xp, 64);
_screenSurface.drawString("LUC", 4);
- _menu.enableMenuItem(_menu._discussMenu[6]._menuId, _menu._discussMenu[6]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[6]);
}
if ((bitIndex & 2) == 2) {
_screenSurface.putxy(xp, 72);
_screenSurface.drawString("IDA", 4);
- _menu.enableMenuItem(_menu._discussMenu[7]._menuId, _menu._discussMenu[7]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[7]);
}
if ((bitIndex & 1) == 1) {
_screenSurface.putxy(xp, 80);
_screenSurface.drawString("MAX", 4);
- _menu.enableMenuItem(_menu._discussMenu[8]._menuId, _menu._discussMenu[8]._actionId);
+ _menu.enableMenuItem(_menu._discussMenu[8]);
}
_currBitIndex = bitIndex;
}
@@ -701,7 +698,7 @@ int MortevielleEngine::getPresenceStatsRedRoom() {
*/
void MortevielleEngine::displayAloneText() {
for (int i = 1; i <= 8; ++i)
- _menu.disableMenuItem(_menu._discussMenu[i]._menuId, _menu._discussMenu[i]._actionId);
+ _menu.disableMenuItem(_menu._discussMenu[i]);
Common::String sYou = getEngineString(S_YOU);
Common::String sAre = getEngineString(S_ARE);
@@ -1338,7 +1335,7 @@ void MortevielleEngine::startDialog(int16 rep) {
_mouse.hideMouse();
Common::String dialogStr = getString(rep + kDialogStringIndex);
- _text.displayStr(dialogStr, 230, 4, 65, 24, 5);
+ _text.displayStr(dialogStr, 230, 4, 65, 26, 5);
_dialogManager.drawF3F8();
key = 0;
@@ -1450,31 +1447,6 @@ void MortevielleEngine::floodedInWell() {
}
/**
- * Engine function - Change Graphical Device
- * @remarks Originally called 'change_gd'
- */
-void MortevielleEngine::changeGraphicalDevice(int newDevice) {
- _mouse.hideMouse();
- _currGraphicalDevice = newDevice;
- clearScreen();
- _mouse.initMouse();
- _mouse.showMouse();
- drawRightFrame();
- prepareRoom();
- drawClock();
- if (_currBitIndex != 0)
- showPeoplePresent(_currBitIndex);
- else
- displayAloneText();
- clearDescriptionBar();
- clearVerbBar();
- _maff = 68;
- drawPictureWithText();
- handleDescriptionText(2, _crep);
- _menu.displayMenu();
-}
-
-/**
* Called when a savegame has been loaded.
* @remarks Originally called 'antegame'
*/
@@ -1536,79 +1508,79 @@ void MortevielleEngine::handleOpcode() {
_keyPressedEsc = false;
if (!_anyone) {
if (_uptodatePresence) {
- if ((_currMenu == MENU_MOVE) || (_currAction == OPCODE_LEAVE) || (_currAction == OPCODE_SLEEP) || (_currAction == OPCODE_EAT)) {
+ if ((_currMenu == MENU_MOVE) || (_currAction == _menu._opcodeLeave) || (_currAction == _menu._opcodeSleep) || (_currAction == _menu._opcodeEat)) {
_controlMenu = 4;
menuUp();
return;
}
}
+
if (_currMenu == MENU_MOVE)
fctMove();
- if (_currMenu == MENU_DISCUSS)
+ else if (_currMenu == MENU_DISCUSS)
fctDiscuss();
- if (_currMenu == MENU_INVENTORY)
+ else if (_currMenu == MENU_INVENTORY)
fctInventoryTake();
- if (_currAction == OPCODE_ATTACH)
+ else if (_currAction == _menu._opcodeAttach)
fctAttach();
- if (_currAction == OPCODE_WAIT)
+ else if (_currAction == _menu._opcodeWait)
fctWait();
- if (_currAction == OPCODE_FORCE)
+ else if (_currAction == _menu._opcodeForce)
fctForce();
- if (_currAction == OPCODE_SLEEP)
+ else if (_currAction == _menu._opcodeSleep)
fctSleep();
- if (_currAction == OPCODE_LISTEN)
+ else if (_currAction == _menu._opcodeListen)
fctListen();
- if (_currAction == OPCODE_ENTER)
+ else if (_currAction == _menu._opcodeEnter)
fctEnter();
- if (_currAction == OPCODE_CLOSE)
+ else if (_currAction == _menu._opcodeClose)
fctClose();
- if (_currAction == OPCODE_SEARCH)
+ else if (_currAction == _menu._opcodeSearch)
fctSearch();
- if (_currAction == OPCODE_KNOCK)
+ else if (_currAction == _menu._opcodeKnock)
fctKnock();
- if (_currAction == OPCODE_SCRATCH)
+ else if (_currAction == _menu._opcodeScratch)
fctScratch();
- if (_currAction == OPCODE_READ)
+ else if (_currAction == _menu._opcodeRead)
fctRead();
- if (_currAction == OPCODE_EAT)
+ else if (_currAction == _menu._opcodeEat)
fctEat();
- if (_currAction == OPCODE_PLACE)
+ else if (_currAction == _menu._opcodePlace)
fctPlace();
- if (_currAction == OPCODE_OPEN)
+ else if (_currAction == _menu._opcodeOpen)
fctOpen();
- if (_currAction == OPCODE_TAKE)
+ else if (_currAction == _menu._opcodeTake)
fctTake();
- if (_currAction == OPCODE_LOOK)
+ else if (_currAction == _menu._opcodeLook)
fctLook();
- if (_currAction == OPCODE_SMELL)
+ else if (_currAction == _menu._opcodeSmell)
fctSmell();
- if (_currAction == OPCODE_SOUND)
+ else if (_currAction == _menu._opcodeSound)
fctSound();
- if (_currAction == OPCODE_LEAVE)
+ else if (_currAction == _menu._opcodeLeave)
fctLeave();
- if (_currAction == OPCODE_LIFT)
+ else if (_currAction == _menu._opcodeLift)
fctLift();
- if (_currAction == OPCODE_TURN)
+ else if (_currAction == _menu._opcodeTurn)
fctTurn();
- if (_currAction == OPCODE_SSEARCH)
+ else if (_currAction == _menu._opcodeSSearch)
fctSelfSearch();
- if (_currAction == OPCODE_SREAD)
+ else if (_currAction == _menu._opcodeSRead)
fctSelfRead();
- if (_currAction == OPCODE_SPUT)
+ else if (_currAction == _menu._opcodeSPut)
fctSelfPut();
- if (_currAction == OPCODE_SLOOK)
+ else if (_currAction == _menu._opcodeSLook)
fctSelftLook();
+
_hiddenHero = false;
- if (_currAction == OPCODE_SHIDE)
+ if (_currAction == _menu._opcodeSHide)
fctSelfHide();
- } else {
- if (_anyone) {
- interactNPC();
- _anyone = false;
- menuUp();
- return;
- }
+ } else if (_anyone) {
+ interactNPC();
+ _anyone = false;
+ menuUp();
+ return;
}
int hour, day, minute;
updateHour(day, hour, minute);
@@ -1620,12 +1592,10 @@ void MortevielleEngine::handleOpcode() {
if ((_coreVar._faithScore > 99) && (hour > 8) && (hour < 16)) {
_crep = 1501;
loseGame();
- }
- if ((_coreVar._faithScore > 99) && (hour > 0) && (hour < 9)) {
+ } else if ((_coreVar._faithScore > 99) && (hour > 0) && (hour < 9)) {
_crep = 1508;
loseGame();
- }
- if ((day > 1) && (hour > 8) && (!_loseGame)) {
+ } else if ((day > 1) && (hour > 8) && (!_loseGame)) {
_crep = 1502;
loseGame();
}
@@ -1708,19 +1678,12 @@ void MortevielleEngine::clearVerbBar() {
* @remarks Originally called 'clsf10'
*/
void MortevielleEngine::clearUpperRightPart() {
- int x1, x2;
Common::String st;
_mouse.hideMouse();
- if (_resolutionScaler == 1) {
- x2 = 634;
- x1 = 534;
- } else {
- x2 = 600;
- x1 = 544;
- }
+
// Clear ambiance description
- _screenSurface.fillRect(15, Common::Rect(x1, 93, x2, 98));
+ _screenSurface.fillRect(15, Common::Rect(544, 93, 600, 98));
if (_coreVar._faithScore < 33)
st = getEngineString(S_COOL);
else if (_coreVar._faithScore < 66)
@@ -1728,7 +1691,7 @@ void MortevielleEngine::clearUpperRightPart() {
else if (_coreVar._faithScore > 65)
st = getEngineString(S_MALSAINE);
- x1 = 580 - (_screenSurface.getStringWidth(st) / 2);
+ int x1 = 580 - (_screenSurface.getStringWidth(st) / 2);
_screenSurface.putxy(x1, 92);
_screenSurface.drawString(st, 4);
@@ -1750,7 +1713,7 @@ int MortevielleEngine::getRandomNumber(int minval, int maxval) {
* @remarks Originally called 'aldepl'
*/
void MortevielleEngine::showMoveMenuAlert() {
- _dialogManager.show(getEngineString(S_USE_DEP_MENU), 1);
+ _dialogManager.show(getEngineString(S_USE_DEP_MENU));
}
/**
@@ -1980,46 +1943,9 @@ void MortevielleEngine::resetVariables() {
* @remarks Originally called 'writepal'
*/
void MortevielleEngine::setPal(int n) {
- switch (_currGraphicalDevice) {
- case MODE_TANDY:
- case MODE_EGA:
- case MODE_AMSTRAD1512:
- for (int i = 1; i <= 16; ++i) {
- _curPict[(2 * i)] = _stdPal[n][i].x;
- _curPict[(2 * i) + 1] = _stdPal[n][i].y;
- }
- break;
- case MODE_CGA: {
- nhom pal[16];
- for (int i = 0; i < 16; ++i) {
- pal[i] = _cgaPal[n]._a[i];
- }
-
- if (n < 89)
- palette(_cgaPal[n]._p);
-
- for (int i = 0; i <= 15; ++i)
- displayCGAPattern(i, &_patternArr[pal[i]._id], pal);
- }
- break;
- default:
- break;
- }
-}
-
-/**
- * Engine function - Display a CGA pattern, using a specified palette
- * @remarks Originally called 'outbloc'
- */
-void MortevielleEngine::displayCGAPattern(int n, Pattern *p, nhom *pal) {
- int addr = n * 404 + 0xd700;
-
- WRITE_LE_UINT16(&_curPict[addr], p->_tax);
- WRITE_LE_UINT16(&_curPict[addr + 2], p->_tay);
- addr += 4;
- for (int i = 0; i < p->_tax; ++i) {
- for (int j = 0; j < p->_tay; ++j)
- _curPict[addr + j * p->_tax + i] = pal[n]._hom[p->_des[i + 1][j + 1]];
+ for (int i = 1; i <= 16; ++i) {
+ _curPict[(2 * i)] = _stdPal[n][i].x;
+ _curPict[(2 * i) + 1] = _stdPal[n][i].y;
}
}
@@ -2029,7 +1955,6 @@ void MortevielleEngine::displayCGAPattern(int n, Pattern *p, nhom *pal) {
*/
void MortevielleEngine::loadPalette() {
Common::File f;
- byte b;
if (!f.open("fxx.mor")) {
if (f.open("mfxx.mor"))
@@ -2055,27 +1980,8 @@ void MortevielleEngine::loadPalette() {
if (!f.open("cxx.mor"))
error("Missing file - cxx.mor");
- for (int j = 0; j <= 90; ++j) {
- _cgaPal[j]._p = f.readByte();
- for (int i = 0; i <= 15; ++i) {
- nhom &with = _cgaPal[j]._a[i];
-
- b = f.readByte();
- with._id = (uint)b >> 4;
- with._hom[0] = ((uint)b >> 2) & 3;
- with._hom[1] = b & 3;
- }
- }
+ // Skip CGA Palette and Patterns
- _cgaPal[10]._a[9] = _cgaPal[10]._a[5];
- for (int j = 0; j <= 14; ++j) {
- _patternArr[j]._tax = f.readByte();
- _patternArr[j]._tay = f.readByte();
- for (int i = 1; i <= 20; ++i) {
- for (int k = 1; k <= 20; ++k)
- _patternArr[j]._des[i][k] = f.readByte();
- }
- }
f.close();
}
@@ -2088,8 +1994,8 @@ void MortevielleEngine::loadTexts() {
Common::File ntpFile;
_txxFileFl = false;
- if (getLanguage() == Common::EN_ANY) {
- warning("English version expected - Switching to DAT file");
+ if (!useOriginalData()) {
+ warning("Using improved translation from DAT file");
return;
}
@@ -2216,13 +2122,11 @@ void MortevielleEngine::showTitleScreen() {
_caff = 51;
_text.taffich();
testKeyboard();
- if (_newGraphicalDevice != _currGraphicalDevice)
- _currGraphicalDevice = _newGraphicalDevice;
clearScreen();
draw(0, 0);
Common::String cpr = "COPYRIGHT 1989 : LANKHOR";
- _screenSurface.putxy(104 + 72 * _resolutionScaler, 185);
+ _screenSurface.putxy(104 + 72 * kResolutionScaler, 185);
_screenSurface.drawString(cpr, 0);
}
@@ -2243,9 +2147,6 @@ void MortevielleEngine::draw(int x, int y) {
*/
void MortevielleEngine::drawRightFrame() {
setPal(89);
- if (_currGraphicalDevice == MODE_HERCULES)
- _curPict[14] = 15;
-
_mouse.hideMouse();
displayPicture(_rightFramePict, 0, 0);
_mouse.showMouse();
@@ -2418,21 +2319,16 @@ void MortevielleEngine::drawClock() {
const int x = 580;
const int y = 123;
const int rg = 9;
- int hourColor;
_mouse.hideMouse();
_screenSurface.drawRectangle(570, 118, 20, 10);
_screenSurface.drawRectangle(578, 114, 6, 18);
- if ((_currGraphicalDevice == MODE_CGA) || (_currGraphicalDevice == MODE_HERCULES))
- hourColor = 0;
- else
- hourColor = 1;
if (_minute == 0)
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)x >> 1) * _resolutionScaler, (y - rg), hourColor);
+ _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y - rg), 1);
else
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)x >> 1) * _resolutionScaler, (y + rg), hourColor);
+ _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)x >> 1) * kResolutionScaler, (y + rg), 1);
int hour12 = _hour;
if (hour12 > 12)
@@ -2440,7 +2336,7 @@ void MortevielleEngine::drawClock() {
if (hour12 == 0)
hour12 = 12;
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)(x + cv[0][hour12 - 1]) >> 1) * _resolutionScaler, y + cv[1][hour12 - 1], hourColor);
+ _screenSurface.drawLine(((uint)x >> 1) * kResolutionScaler, y, ((uint)(x + cv[0][hour12 - 1]) >> 1) * kResolutionScaler, y + cv[1][hour12 - 1], 1);
_mouse.showMouse();
_screenSurface.putxy(568, 154);
@@ -2486,20 +2382,6 @@ Common::String MortevielleEngine::copy(const Common::String &s, int idx, size_t
* @remarks Originally called 'hirs'
*/
void MortevielleEngine::clearScreen() {
- // Note: The original used this to set the graphics mode and clear the screen, both at
- // the start of the game, and whenever the screen need to be cleared. As such, this
- // method is deprecated in favour of clearing the screen
- debugC(1, kMortevielleCore, "TODO: hirs is deprecated in favour of ScreenSurface::clearScreen");
-
- if (_currGraphicalDevice == MODE_TANDY) {
- _screenSurface.fillRect(0, Common::Rect(0, 0, 639, 200));
- _resolutionScaler = 1;
- } else if (_currGraphicalDevice == MODE_CGA) {
- palette(1);
- _resolutionScaler = 1;
- } else
- _resolutionScaler = 2;
-
_screenSurface.clearScreen();
}
@@ -2540,12 +2422,6 @@ void MortevielleEngine::displayControlMenu() {
void MortevielleEngine::displayPicture(const byte *pic, int x, int y) {
GfxSurface surface;
surface.decode(pic);
-
- if (_currGraphicalDevice == MODE_HERCULES) {
- _curPict[2] = 0;
- _curPict[32] = 15;
- }
-
_screenSurface.drawPicture(surface, x, y);
}
@@ -2592,14 +2468,8 @@ int MortevielleEngine::getAnimOffset(int frameNum, int animNum) {
* @remarks Originally called 'text1'
*/
void MortevielleEngine::displayTextInDescriptionBar(int x, int y, int nb, int mesgId) {
- int co;
-
- if (_resolutionScaler == 1)
- co = 10;
- else
- co = 6;
Common::String tmpStr = getString(mesgId);
- if ((y == 182) && ((int) tmpStr.size() * co > nb * 6))
+ if ((y == 182) && ((int) tmpStr.size() > nb))
y = 176;
_text.displayStr(tmpStr, x, y, nb, 20, _textColor);
}
@@ -2612,7 +2482,7 @@ void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
if ((mesgId > 499) && (mesgId < 563)) {
Common::String tmpStr = getString(mesgId - 501 + kInventoryStringIndex);
- if ((int) tmpStr.size() > ((58 + (_resolutionScaler - 1) * 37) << 1))
+ if ((int) tmpStr.size() > ((58 + (kResolutionScaler - 1) * 37) << 1))
_largestClearScreen = true;
else
_largestClearScreen = false;
@@ -2629,7 +2499,7 @@ void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
displayTextInDescriptionBar(8, 182, 103, mesgId);
if ((mesgId == 68) || (mesgId == 69))
_coreVar._availableQuestion[40] = '*';
- if ((mesgId == 104) && (_caff == CELLAR)) {
+ else if ((mesgId == 104) && (_caff == CELLAR)) {
_coreVar._availableQuestion[36] = '*';
if (_coreVar._availableQuestion[39] == '*') {
_coreVar._pctHintFound[3] = '*';
@@ -2721,7 +2591,7 @@ void MortevielleEngine::resetOpenObjects() {
void MortevielleEngine::displayTextBlock(Common::String text) {
// Some dead code was present in the original: removed
_screenSurface.putxy(8, 177);
- int tlig = 59 + (_resolutionScaler - 1) * 36;
+ int tlig = 59 + (kResolutionScaler - 1) * 36;
if ((int)text.size() < tlig)
_screenSurface.drawString(text, 5);
@@ -2758,8 +2628,8 @@ void MortevielleEngine::displayItemInHand(int objId) {
if (objId != 500)
strp = getString(objId - 501 + kInventoryStringIndex);
- _menu.setText(_menu._inventoryMenu[8]._menuId, _menu._inventoryMenu[8]._actionId, strp);
- _menu.disableMenuItem(_menu._inventoryMenu[8]._menuId, _menu._inventoryMenu[8]._actionId);
+ _menu.setText(_menu._inventoryMenu[8], strp);
+ _menu.disableMenuItem(_menu._inventoryMenu[8]);
}
/**
@@ -2906,34 +2776,54 @@ int MortevielleEngine::getPresence(int roomId) {
displayAloneText();
else {
int h = 0;
- if (roomId == DINING_ROOM)
+ switch (roomId) {
+ case DINING_ROOM:
pres = getPresenceStatsDiningRoom(h);
- else if (roomId == BUREAU)
+ break;
+ case BUREAU:
pres = getPresenceStatsBureau(h);
- else if (roomId == KITCHEN)
+ break;
+ case KITCHEN:
pres = getPresenceStatsKitchen();
- else if ((roomId == ATTIC) || (roomId == CELLAR))
+ break;
+ case ATTIC:
+ case CELLAR:
pres = getPresenceStatsAttic();
- else if ((roomId == LANDING) || (roomId == ROOM26))
+ break;
+ case LANDING:
+ case ROOM26:
pres = getPresenceStatsLanding();
- else if (roomId == CHAPEL)
+ break;
+ case CHAPEL:
pres = getPresenceStatsChapel(h);
+ break;
+ }
pres += _coreVar._faithScore;
rand = getRandomNumber(1, 100);
if (rand > pres) {
displayAloneText();
retVal = 0;
} else {
- if (roomId == DINING_ROOM)
+ switch (roomId) {
+ case DINING_ROOM:
pres = setPresenceDiningRoom(h);
- else if (roomId == BUREAU)
+ break;
+ case BUREAU:
pres = setPresenceBureau(h);
- else if ((roomId == KITCHEN) || (roomId == ATTIC) || (roomId == CELLAR))
+ break;
+ case KITCHEN:
+ case ATTIC:
+ case CELLAR:
pres = setPresenceKitchen();
- else if ((roomId == LANDING) || (roomId == ROOM26))
+ break;
+ case LANDING:
+ case ROOM26:
pres = setPresenceLanding();
- else if (roomId == CHAPEL)
+ break;
+ case CHAPEL:
pres = setPresenceChapel(h);
+ break;
+ }
retVal = pres;
}
}
@@ -2947,10 +2837,7 @@ int MortevielleEngine::getPresence(int roomId) {
* @remarks Originally called 'writetp'
*/
void MortevielleEngine::displayQuestionText(Common::String s, int cmd) {
- if (_resolutionScaler == 2)
- _screenSurface.drawString(s, cmd);
- else
- _screenSurface.drawString(copy(s, 1, 25), cmd);
+ _screenSurface.drawString(s, cmd);
}
/**
@@ -3000,18 +2887,27 @@ void MortevielleEngine::drawPicture() {
displayAnimFrame(1, _openObjects[i]);
}
- if (_caff == ATTIC) {
+ switch (_caff) {
+ case ATTIC:
if (_coreVar._atticBallHoleObjectId == 141)
displayAnimFrame(1, 7);
if (_coreVar._atticRodHoleObjectId == 159)
displayAnimFrame(1, 6);
- } else if ((_caff == CELLAR) && (_coreVar._cellarObjectId == 151))
- displayAnimFrame(1, 2);
- else if ((_caff == SECRET_PASSAGE) && (_coreVar._secretPassageObjectId == 143))
- displayAnimFrame(1, 1);
- else if ((_caff == WELL) && (_coreVar._wellObjectId != 0))
- displayAnimFrame(1, 1);
+ break;
+ case CELLAR:
+ if (_coreVar._cellarObjectId == 151)
+ displayAnimFrame(1, 2);
+ break;
+ case SECRET_PASSAGE:
+ if (_coreVar._secretPassageObjectId == 143)
+ displayAnimFrame(1, 1);
+ break;
+ case WELL:
+ if (_coreVar._wellObjectId != 0)
+ displayAnimFrame(1, 1);
+ break;
+ }
}
if (_caff < ROOM26)
@@ -3319,12 +3215,12 @@ void MortevielleEngine::displayStatusArrow() {
return;
if (getMouseClick())
- inRect = (_mouse._pos.x < 256 * _resolutionScaler) && (_mouse._pos.y < 176) && (_mouse._pos.y > 12);
+ inRect = (_mouse._pos.x < 256 * kResolutionScaler) && (_mouse._pos.y < 176) && (_mouse._pos.y > 12);
prepareRoom();
} while (!(qust || inRect || _anyone));
if (qust && (touch == '\103'))
- _dialogManager.show(_hintPctMessage, 1);
+ _dialogManager.show(_hintPctMessage);
} while (!((touch == '\73') || ((touch == '\104') && (_x != 0) && (_y != 0)) || (_anyone) || (inRect)));
if (touch == '\73')
@@ -3376,10 +3272,10 @@ void MortevielleEngine::setCoordinates(int sx) {
cy = 1;
do {
cb += 2;
- sx = _tabdon[a + cb] * _resolutionScaler;
+ sx = _tabdon[a + cb] * kResolutionScaler;
sy = _tabdon[(a + cb + 1)];
cb += 2;
- ix = _tabdon[a + cb] * _resolutionScaler;
+ ix = _tabdon[a + cb] * kResolutionScaler;
iy = _tabdon[(a + cb + 1)];
++cy;
} while (!(((_x >= sx) && (_x <= ix) && (_y >= sy) && (_y <= iy)) || (cy > ib)));
@@ -3400,7 +3296,7 @@ void MortevielleEngine::displayLookScreen(int objId) {
int mdes = _caff;
_caff = objId;
- if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_currAction == OPCODE_SLOOK)) {
+ if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_currAction == _menu._opcodeSLook)) {
drawPictureWithText();
if ((_caff > 29) && (_caff < 33))
handleDescriptionText(2, _caff);
@@ -3465,17 +3361,8 @@ int MortevielleEngine::checkLeaveSecretPassage() {
* @remarks Originally called 'fenat'
*/
void MortevielleEngine::displayStatusInDescriptionBar(char stat) {
- int color;
-
_mouse.hideMouse();
- if (_currGraphicalDevice == MODE_CGA)
- color = 2;
- else if (_currGraphicalDevice == MODE_HERCULES)
- color = 1;
- else
- color = 12;
-
- _screenSurface.writeCharacter(Common::Point(306, 193), stat, color);
+ _screenSurface.writeCharacter(Common::Point(306, 193), stat, 12);
_screenSurface.drawBox(300, 191, 16, 8, 15);
_mouse.showMouse();
}
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 09c348f273..883a4d965b 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -105,9 +105,8 @@ static const PlainGameDescriptor s_sciGameTitles[] = {
// === SCI2.1 games ========================================================
{"chest", "Inside the Chest"}, // aka Behind the Developer's Shield
{"gk2", "The Beast Within: A Gabriel Knight Mystery"},
- // TODO: Inside The Chest/Behind the Developer's Shield
{"kq7", "King's Quest VII: The Princeless Bride"},
- // TODO: King's Questions
+ {"kquestions", "King's Questions"},
{"lsl6hires", "Leisure Suit Larry 6: Shape Up or Slip Out!"},
{"mothergoosehires","Mixed-Up Mother Goose Deluxe"},
{"phantasmagoria", "Phantasmagoria"},
@@ -161,6 +160,7 @@ static const GameIdStrToEnum s_gameIdStrToEnum[] = {
{ "kq5", GID_KQ5 },
{ "kq6", GID_KQ6 },
{ "kq7", GID_KQ7 },
+ { "kquestions", GID_KQUESTIONS },
{ "laurabow", GID_LAURABOW },
{ "laurabow2", GID_LAURABOW2 },
{ "lighthouse", GID_LIGHTHOUSE },
@@ -242,6 +242,7 @@ static const OldNewIdTableEntry s_oldNewTable[] = {
// kq5 is the same
// kq6 is the same
{ "kq7cd", "kq7", SCI_VERSION_NONE },
+ { "quizgame-demo", "kquestions", SCI_VERSION_NONE },
{ "mm1", "laurabow", SCI_VERSION_NONE },
{ "cb1", "laurabow", SCI_VERSION_NONE },
{ "lb2", "laurabow2", SCI_VERSION_NONE },
diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h
index 7c4638a992..92e77cead9 100644
--- a/engines/sci/detection_tables.h
+++ b/engines/sci/detection_tables.h
@@ -1656,6 +1656,14 @@ static const struct ADGameDescription SciGameDescriptions[] = {
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) },
+ // King's Questions mini-game from the King's Quest Collection
+ // SCI interpreter version 2.000.000
+ {"kquestions", "", {
+ {"resource.000", 0, "9b1cddecd4f0720d83661ba7aed28891", 162697},
+ {"resource.map", 0, "93a2251fa64e729d7a7d2fe56b217c8e", 502},
+ AD_LISTEND},
+ Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO3(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_FB01_MIDI) },
+
#endif // ENABLE_SCI32
// Laura Bow - English Amiga
diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index 6005ac50be..c26c787fbd 100644
--- a/engines/sci/engine/features.cpp
+++ b/engines/sci/engine/features.cpp
@@ -467,9 +467,9 @@ bool GameFeatures::autoDetectSci21KernelType() {
// seen it happen in the RAMA demo, thus we can assume that the
// game is using a SCI2.1 table
- // HACK: The Inside the Chest Demo doesn't have sounds at all, but
- // it's using a SCI2 kernel
- if (g_sci->getGameId() == GID_CHEST) {
+ // HACK: The Inside the Chest Demo and King's Questions minigame
+ // don't have sounds at all, but they're using a SCI2 kernel
+ if (g_sci->getGameId() == GID_CHEST || g_sci->getGameId() == GID_KQUESTIONS) {
_sci21KernelType = SCI_VERSION_2;
return true;
}
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 20c5c52178..d4dddb6faf 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -953,10 +953,10 @@ const uint16 qfg1vgaPatchDialogHeader[] = {
// When clicking on the crusher in room 331, Ego approaches him to talk to him,
// an action that is handled by moveToCrusher::changeState in script 331. The
-// scripts set Ego to move close to the crusher, but when Ego is running instead
+// scripts set Ego to move close to the crusher, but when Ego is sneaking instead
// of walking, the target coordinates specified by script 331 are never reached,
// as Ego is making larger steps, and never reaches the required spot. This is an
-// edge case that can occur when Ego is set to run. Normally, when clicking on
+// edge case that can occur when Ego is set to sneak. Normally, when clicking on
// the crusher, ego is supposed to move close to position 79, 165. We change it
// to 85, 165, which is not an edge case thus the freeze is avoided.
// Fixes bug #3585189.
@@ -976,6 +976,25 @@ const uint16 qfg1vgaPatchMoveToCrusher[] = {
PATCH_END
};
+// Same pathfinding bug as above, where Ego is set to move to an impossible
+// spot when sneaking. In GuardsTrumpet::changeState, we change the final
+// location where Ego is moved from 111, 111 to 114, 114. Fixes bug #3604939.
+const byte qfg1vgaSignatureMoveToCastleGate[] = {
+ 7,
+ 0x51, 0x1f, // class MoveTo
+ 0x36, // push
+ 0x39, 0x6f, // pushi 6f (111 - x)
+ 0x3c, // dup (111 - y)
+ 0x7c, // pushSelf
+ 0
+};
+
+const uint16 qfg1vgaPatchMoveToCastleGate[] = {
+ PATCH_ADDTOOFFSET | +3,
+ 0x39, 0x72, // pushi 72 (114 - x)
+ PATCH_END
+};
+
// script, description, magic DWORD, adjust
const SciScriptSignature qfg1vgaSignatures[] = {
{ 215, "fight event issue", 1, PATCH_MAGICDWORD(0x6d, 0x76, 0x51, 0x07), -1, qfg1vgaSignatureFightEvents, qfg1vgaPatchFightEvents },
@@ -983,6 +1002,7 @@ const SciScriptSignature qfg1vgaSignatures[] = {
{ 814, "window text temp space", 1, PATCH_MAGICDWORD(0x3f, 0xba, 0x87, 0x00), 0, qfg1vgaSignatureTempSpace, qfg1vgaPatchTempSpace },
{ 814, "dialog header offset", 3, PATCH_MAGICDWORD(0x5b, 0x04, 0x80, 0x36), 0, qfg1vgaSignatureDialogHeader, qfg1vgaPatchDialogHeader },
{ 331, "moving to crusher", 1, PATCH_MAGICDWORD(0x51, 0x1f, 0x36, 0x39), 0, qfg1vgaSignatureMoveToCrusher, qfg1vgaPatchMoveToCrusher },
+ { 41, "moving to castle gate", 1, PATCH_MAGICDWORD(0x51, 0x1f, 0x36, 0x39), 0, qfg1vgaSignatureMoveToCastleGate, qfg1vgaPatchMoveToCastleGate },
SCI_SIGNATUREENTRY_TERMINATOR
};
diff --git a/engines/sci/engine/vm_types.cpp b/engines/sci/engine/vm_types.cpp
index 27015d9be4..5327dd1a2e 100644
--- a/engines/sci/engine/vm_types.cpp
+++ b/engines/sci/engine/vm_types.cpp
@@ -28,12 +28,12 @@
namespace Sci {
-reg_t reg_t::lookForWorkaround(const reg_t right) const {
+reg_t reg_t::lookForWorkaround(const reg_t right, const char *operation) const {
SciTrackOriginReply originReply;
SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, arithmeticWorkarounds, &originReply);
if (solution.type == WORKAROUND_NONE)
- error("Invalid arithmetic operation (params: %04x:%04x and %04x:%04x) from method %s::%s (room %d, script %d, localCall %x)",
- PRINT_REG(*this), PRINT_REG(right), originReply.objectName.c_str(),
+ error("Invalid arithmetic operation (%s - params: %04x:%04x and %04x:%04x) from method %s::%s (room %d, script %d, localCall %x)",
+ operation, PRINT_REG(*this), PRINT_REG(right), originReply.objectName.c_str(),
originReply.methodName.c_str(), g_sci->getEngineState()->currentRoomNumber(), originReply.scriptNr,
originReply.localCallOffset);
assert(solution.type == WORKAROUND_FAKE);
@@ -55,7 +55,7 @@ reg_t reg_t::operator+(const reg_t right) const {
case SEG_TYPE_DYNMEM:
return make_reg(getSegment(), getOffset() + right.toSint16());
default:
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "addition");
}
} else if (isNumber() && right.isPointer()) {
// Adding a pointer to a number, flip the order
@@ -64,7 +64,7 @@ reg_t reg_t::operator+(const reg_t right) const {
// Normal arithmetics
return make_reg(0, toSint16() + right.toSint16());
} else {
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "addition");
}
}
@@ -82,14 +82,14 @@ reg_t reg_t::operator*(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toSint16() * right.toSint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "multiplication");
}
reg_t reg_t::operator/(const reg_t right) const {
if (isNumber() && right.isNumber() && !right.isNull())
return make_reg(0, toSint16() / right.toSint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "division");
}
reg_t reg_t::operator%(const reg_t right) const {
@@ -109,21 +109,21 @@ reg_t reg_t::operator%(const reg_t right) const {
result += modulo;
return make_reg(0, result);
} else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "modulo");
}
reg_t reg_t::operator>>(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() >> right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "shift right");
}
reg_t reg_t::operator<<(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() << right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "shift left");
}
reg_t reg_t::operator+(int16 right) const {
@@ -140,7 +140,7 @@ uint16 reg_t::requireUint16() const {
else
// The right parameter is NULL_REG because
// we're not comparing *this with anything here.
- return lookForWorkaround(NULL_REG).toUint16();
+ return lookForWorkaround(NULL_REG, "require unsigned number").toUint16();
}
int16 reg_t::requireSint16() const {
@@ -149,28 +149,28 @@ int16 reg_t::requireSint16() const {
else
// The right parameter is NULL_REG because
// we're not comparing *this with anything here.
- return lookForWorkaround(NULL_REG).toSint16();
+ return lookForWorkaround(NULL_REG, "require signed number").toSint16();
}
reg_t reg_t::operator&(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() & right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise AND");
}
reg_t reg_t::operator|(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() | right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise OR");
}
reg_t reg_t::operator^(const reg_t right) const {
if (isNumber() && right.isNumber())
return make_reg(0, toUint16() ^ right.toUint16());
else
- return lookForWorkaround(right);
+ return lookForWorkaround(right, "bitwise XOR");
}
int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const {
@@ -184,7 +184,7 @@ int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const {
} else if (right.pointerComparisonWithInteger(*this)) {
return -1;
} else
- return lookForWorkaround(right).toSint16();
+ return lookForWorkaround(right, "comparison").toSint16();
}
bool reg_t::pointerComparisonWithInteger(const reg_t right) const {
diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h
index 9a7589e9a7..22bd8beaa1 100644
--- a/engines/sci/engine/vm_types.h
+++ b/engines/sci/engine/vm_types.h
@@ -156,7 +156,7 @@ private:
* - a negative number if *this < right
*/
int cmp(const reg_t right, bool treatAsUnsigned) const;
- reg_t lookForWorkaround(const reg_t right) const;
+ reg_t lookForWorkaround(const reg_t right, const char *operation) const;
bool pointerComparisonWithInteger(const reg_t right) const;
};
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 6f0b34b457..49d6145607 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -37,6 +37,7 @@ const SciWorkaroundEntry arithmeticWorkarounds[] = {
{ GID_ECOQUEST2, 100, 0, 0, "Rain", "points", 0xce0, 0, { WORKAROUND_FAKE, 0 } }, // Same as above, for the Spanish version - bug #3313962
{ GID_FANMADE, 516, 983, 0, "Wander", "setTarget", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_mul: The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #3038913
{ GID_GK1, 800,64992, 0, "Fwd", "doit", -1, 0, { WORKAROUND_FAKE, 1 } }, // op_gt: when Mosely finds Gabriel and Grace near the end of the game, compares the Grooper object with 7
+ { GID_HOYLE4, 700, -1, 1, "Code", "doit", -1, 0, { WORKAROUND_FAKE, 1 } }, // op_add: while bidding in Bridge, an object ("Bid") is added to an object in another segment ("hand3")
{ GID_ICEMAN, 199, 977, 0, "Grooper", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_add: While dancing with the girl
{ GID_MOTHERGOOSE256, -1, 999, 0, "Event", "new", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_and: constantly during the game (SCI1 version)
{ GID_MOTHERGOOSE256, -1, 4, 0, "rm004", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // op_or: when going north and reaching the castle (rooms 4 and 37) - bug #3038228
@@ -74,9 +75,11 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_HOYLE4, -1, 0, 0, NULL, "open", -1, -1, { WORKAROUND_FAKE, 0 } }, // when selecting "Control" from the menu (temp vars 0-3) - bug #3039294
{ GID_HOYLE4, 910, 18, 0, NULL, "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // during tutorial - bug #3042756
{ GID_HOYLE4, 910, 910, 0, NULL, "setup", -1, 3, { WORKAROUND_FAKE, 0 } }, // when selecting "Tutorial" from the main menu - bug #3039294
- { GID_HOYLE4, 700, 718, 0, "compete_tree", "doit", -1, 75, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge - bug #3292332
- { GID_HOYLE4, 700, 716, 0, "other1_tree", "doit", -1, 46, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge
- { GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", -1, 3, { WORKAROUND_FAKE, 0 } }, // sometimes when placing a bid in bridge
+ { GID_HOYLE4, 700, 700, 1, "BridgeHand", "calcQTS", -1, 3, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge (always)
+ { GID_HOYLE4, 700, 710, 1, "BridgeStrategyPlay", "checkSplitTops", -1, 10, { WORKAROUND_FAKE, 0 } }, // while playing bridge, objects LeadReturn_Trump, SecondSeat_Trump, ThirdSeat_Trump and others - bug #3361925
+ { GID_HOYLE4, 700, -1, 1, "BridgeDefense", "think", -1, -1, { WORKAROUND_FAKE, 0 } }, // sometimes while playing bridge, temp var 3, 17 and others, objects LeadReturn_Trump, ThirdSeat_Trump and others
+ { GID_HOYLE4, 700, 730, 1, "BridgeDefense", "beatTheirBest", -1, 3, { WORKAROUND_FAKE, 0 } }, // rarely while playing bridge
+ { GID_HOYLE4, 700, -1, 1, "Code", "doit", -1, -1, { WORKAROUND_FAKE, 0 } }, // when placing a bid in bridge (always), temp var 11, 24, 27, 46, 75, objects compete_tree, compwe_tree, other1_tree, b1 - bugs #3292332 and #3361925
{ GID_HOYLE4, 300, 300, 0, "", "export 2", 0x1d4d, 0, { WORKAROUND_FAKE, 0 } }, // after passing around cards in hearts
{ GID_HOYLE4, 400, 400, 1, "GinHand", "calcRuns", -1, 4, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Gin Rummy (e.g. when knocking and placing a card) - bug #3292334
{ GID_HOYLE4, 500, 17, 1, "Character", "say", -1, 504, { WORKAROUND_FAKE, 0 } }, // sometimes while playing Cribbage (e.g. when the opponent says "Last Card") - bug #3292327
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index af372640da..91c72456a8 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -236,7 +236,9 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
byte *ptr = NULL;
byte *headerPtr = inbuffer + headerPos;
byte *rlePtr = inbuffer + rlePos;
- int16 displaceX, displaceY;
+ // displaceX, displaceY fields are ignored, and may contain garbage
+ // (e.g. pic 261 in Dr. Brain 1 Spanish - bug #3614914)
+ //int16 displaceX, displaceY;
byte priority = _addToFlag ? _priority : 0;
byte clearColor;
bool compression = true;
@@ -251,8 +253,8 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
// Width/height here are always LE, even in Mac versions
width = READ_LE_UINT16(headerPtr + 0);
height = READ_LE_UINT16(headerPtr + 2);
- displaceX = (signed char)headerPtr[4];
- displaceY = (unsigned char)headerPtr[5];
+ //displaceX = (signed char)headerPtr[4];
+ //displaceY = (unsigned char)headerPtr[5];
if (_resourceType == SCI_PICTURE_TYPE_SCI11)
// SCI1.1 uses hardcoded clearcolor for pictures, even if cel header specifies otherwise
clearColor = _screen->getColorWhite();
@@ -262,16 +264,16 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos
} else {
width = READ_SCI11ENDIAN_UINT16(headerPtr + 0);
height = READ_SCI11ENDIAN_UINT16(headerPtr + 2);
- displaceX = READ_SCI11ENDIAN_UINT16(headerPtr + 4); // probably signed?!?
- displaceY = READ_SCI11ENDIAN_UINT16(headerPtr + 6); // probably signed?!?
+ //displaceX = READ_SCI11ENDIAN_UINT16(headerPtr + 4); // probably signed?!?
+ //displaceY = READ_SCI11ENDIAN_UINT16(headerPtr + 6); // probably signed?!?
clearColor = headerPtr[8];
if (headerPtr[9] == 0)
compression = false;
}
#endif
- if (displaceX || displaceY)
- error("unsupported embedded cel-data in picture");
+ //if (displaceX || displaceY)
+ // error("unsupported embedded cel-data in picture");
// We will unpack cel-data into a temporary buffer and then plot it to screen
// That needs to be done cause a mirrored picture may be requested
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 3b9844b326..0a75e115fd 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -138,6 +138,7 @@ enum SciGameId {
GID_KQ5,
GID_KQ6,
GID_KQ7,
+ GID_KQUESTIONS,
GID_LAURABOW,
GID_LAURABOW2,
GID_LIGHTHOUSE,
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 5c148a7b57..4e14473921 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -1485,7 +1485,7 @@ void ScummEngine::playActorSounds() {
int sound;
for (i = 1; i < _numActors; i++) {
- if (_actors[i]->_cost.soundCounter && _actors[i]->isInCurrentRoom() && _actors[i]->_sound) {
+ if (_actors[i]->_cost.soundCounter && _actors[i]->isInCurrentRoom()) {
_currentScript = 0xFF;
if (_game.version == 0) {
sound = v0ActorSounds[i - 1] & 0x3F;
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index aaf84c1471..6717ea9b06 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -299,7 +299,11 @@ static const GameSettings gameVariantsTable[] = {
// Changed o_getResourceSize to cover all resource types
{"farm", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
- {"puttzoo", "", 0, GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "", 0, GID_PUTTZOO, 6, 73, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 72", 0, GID_PUTTZOO, 6, 72, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 98.5", 0, GID_PUTTZOO, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 99", 0, GID_PUTTZOO, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
+ {"puttzoo", "HE 100", 0, GID_PUTTZOO, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
// Added VAR_PLATFORM variable
{"jungle", "", 0, GID_HEGAME, 6, 74, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)},
@@ -860,6 +864,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "puttzoo", "Zoo Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttzoo", "Putt-Putt Saves the Zoo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttzoo", "game", kGenHEPC, Common::EN_ANY, Common::kPlatformIOS, 0 },
+ { "puttzoo", "pp3_unlocked", kGenHEPC, Common::EN_ANY, Common::kPlatformWindows, 0 },
{ "SamsFunShop", "SamsFunShop", kGenHEPC, UNK_LANG, UNK, 0 },
{ "SamsFunShop", "Sam's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 4c1fdaf673..1bb4a28f65 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -1769,11 +1769,8 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
// Check whether lights are turned on or not
const bool lightsOn = _vm->isLightOn();
- if (_vm->_game.features & GF_SMALL_HEADER) {
+ if ((_vm->_game.features & GF_SMALL_HEADER) || _vm->_game.version == 8) {
smap_ptr = ptr;
- } else if (_vm->_game.version == 8) {
- // Skip to the BSTR->WRAP->OFFS chunk
- smap_ptr = ptr + 24;
} else {
smap_ptr = _vm->findResource(MKTAG('S','M','A','P'), ptr);
assert(smap_ptr);
@@ -1887,8 +1884,14 @@ bool Gdi::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width,
smapLen = READ_LE_UINT32(smap_ptr);
if (stripnr * 4 + 4 < smapLen)
offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 4);
+ } else if (_vm->_game.version == 8) {
+ smapLen = READ_BE_UINT32(smap_ptr + 4);
+ // Skip to the BSTR->WRAP->OFFS chunk
+ smap_ptr += 24;
+ if (stripnr * 4 + 8 < smapLen)
+ offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 8);
} else {
- smapLen = READ_BE_UINT32(smap_ptr);
+ smapLen = READ_BE_UINT32(smap_ptr + 4);
if (stripnr * 4 + 8 < smapLen)
offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 8);
}
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index b024154c7f..987f74957c 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -2148,7 +2148,7 @@ void ScummEngine_v100he::o100_systemOps() {
break;
case 132:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 133:
quitGame();
diff --git a/engines/scumm/he/script_v70he.cpp b/engines/scumm/he/script_v70he.cpp
index adb2fcac2e..9259e0db2f 100644
--- a/engines/scumm/he/script_v70he.cpp
+++ b/engines/scumm/he/script_v70he.cpp
@@ -309,7 +309,7 @@ void ScummEngine_v70he::o70_systemOps() {
break;
case 160:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 244:
quitGame();
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index f36f5cc130..42bf9a4bb6 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -158,7 +158,7 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
- if (ah == NULL || ah->data == NULL)
+ if (!ah)
error("readArray: invalid array %d (%d)", array, readVar(array));
if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
@@ -1199,7 +1199,7 @@ void ScummEngine_v72he::o72_systemOps() {
break;
case 160:
// Confirm shutdown
- quitGame();
+ confirmExitDialog();
break;
case 244:
quitGame();
diff --git a/engines/scumm/insane/insane_enemy.cpp b/engines/scumm/insane/insane_enemy.cpp
index 3876966fd1..d711b63342 100644
--- a/engines/scumm/insane/insane_enemy.cpp
+++ b/engines/scumm/insane/insane_enemy.cpp
@@ -1519,6 +1519,7 @@ void Insane::chooseEnemyWeaponAnim(int32 buttons) {
case INV_BOOT:
case INV_HAND:
case INV_DUST:
+ // fallthrough
default:
switchEnemyWeapon();
}
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index a75e864e7a..6983c51f30 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -394,7 +394,7 @@ ScummEngine_v6::ArrayHeader *ScummEngine_v6::getArray(int array) {
int ScummEngine_v6::readArray(int array, int idx, int base) {
ArrayHeader *ah = getArray(array);
- if (ah == NULL || ah->data == NULL)
+ if (!ah)
error("readArray: invalid array %d (%d)", array, readVar(array));
// WORKAROUND bug #645711. This is clearly a script bug, as this script
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index f5609f1b03..979573c5f5 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Sat Aug 3 16:52:02 2013
+ This file was generated by the md5table tool on Thu Aug 15 12:47:39 2013
DO NOT EDIT MANUALLY!
*/
@@ -344,6 +344,7 @@ static const MD5Table md5table[] = {
{ "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformDOS },
{ "79b05f628586837e7166e82b2279bb50", "loom", "PC-Engine", "", -1, Common::JA_JPN, Common::kPlatformPCEngine },
+ { "7b4ee071eecadc2d8cd0c3509110825c", "puttzoo", "HE 100", "Remastered", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "7bad72e332a59f9fcc1d437f4edad32a", "puttcircus", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "7c2e76087027eeee9c8f8985f93a1cc5", "freddi4", "", "Demo", 13584, Common::EN_ANY, Common::kPlatformUnknown },
{ "7c8100e360e8ef05f88069d4cfa0afd1", "puttrace", "HE 99", "Demo", 13108, Common::EN_GRB, Common::kPlatformWindows },
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index a77c1c0141..ca05c90936 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -240,6 +240,7 @@ enum ScummGameId {
GID_FBEAR,
GID_PUTTMOON,
GID_FUNPACK,
+ GID_PUTTZOO,
GID_FREDDI3,
GID_BIRTHDAYRED,
GID_BIRTHDAYYELLOW,
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 77c7daa0df..9c90d7575d 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -714,6 +714,12 @@ void ScummEngine_v99he::resetScummVars() {
VAR(140) = 0;
#endif
}
+
+ if (_game.id == GID_PUTTZOO && _game.heversion == 100 && _game.platform == Common::kPlatformWindows) {
+ // Specific to Nimbus Games version.
+ VAR(156) = 1;
+ VAR(157) = 0;
+ }
}
#endif
diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp
index 590e6c6d81..26e073d407 100644
--- a/engines/testbed/graphics.cpp
+++ b/engines/testbed/graphics.cpp
@@ -927,17 +927,29 @@ TestExitStatus GFXtests::overlayGraphics() {
Graphics::PixelFormat pf = g_system->getOverlayFormat();
- OverlayColor buffer[50 * 100];
- OverlayColor value = pf.RGBToColor(0, 255, 0);
+ byte *buffer = new byte[50 * 100 * pf.bytesPerPixel];
+ const uint32 value = pf.RGBToColor(0, 255, 0);
- for (int i = 0; i < 50 * 100; i++) {
- buffer[i] = value;
+ if (pf.bytesPerPixel == 2) {
+ uint16 *dst = (uint16 *)buffer;
+ for (int i = 50 * 100; i > 0; --i) {
+ *dst++ = value;
+ }
+ } else if (pf.bytesPerPixel == 4) {
+ uint32 *dst = (uint32 *)buffer;
+ for (int i = 50 * 100; i > 0; --i) {
+ *dst++ = value;
+ }
+ } else {
+ error("GFXtests::overlayGraphics: Unsupported color depth: %d", pf.bytesPerPixel);
}
g_system->showOverlay();
- g_system->copyRectToOverlay(buffer, 200, 270, 175, 100, 50);
+ g_system->copyRectToOverlay(buffer, 100 * pf.bytesPerPixel, 270, 175, 100, 50);
g_system->updateScreen();
+ delete[] buffer;
+
g_system->delayMillis(1000);
g_system->hideOverlay();
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index a945672da2..cc8166f295 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -478,6 +478,26 @@ static const TinselGameDescription gameDescriptions[] = {
},
#endif
+ { // Mac English CD, see tracker #3614864
+ {
+ "dw",
+ "CD",
+ {
+ {"dw.scn", 0, "114643df0d1f1530a0a9c5d4e38917bc", 1268553},
+ {"english.smp", 0, NULL, -1},
+ {NULL, 0, NULL, 0}
+ },
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_CD,
+ GUIO0()
+ },
+ GID_DW1,
+ 0,
+ GF_SCNFILES | GF_ENHANCED_AUDIO_SUPPORT,
+ TINSEL_V1,
+ },
+
{ // Mac multilanguage CD
{
"dw",
diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp
index 95598babc6..f1f00599e0 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes0.cpp
@@ -888,6 +888,7 @@ void Scene60::Action1::signal() {
break;
case 4:
remove();
+ break;
case 5:
setDelay(120);
break;
diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp
index 9f1e9ce36e..32d87581c0 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes1.cpp
@@ -3237,7 +3237,7 @@ void Scene190::postInit(SceneObjectList *OwnerList) {
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.disableControl();
- // Initialise objects
+ // Initialize objects
_door.postInit();
_door.setVisage(190);
_door.setStrip(1);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.cpp b/engines/tsage/blue_force/blueforce_scenes5.cpp
index abadc4300a..25accbb8a6 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes5.cpp
@@ -1459,7 +1459,7 @@ void Scene560::postInit(SceneObjectList *OwnerList) {
_lamp.setDetails(Rect(197, 43, 214, 56), 560, 7, 19, 30, 1, NULL);
_item4.setDetails(Rect(121, 18, 156, 54), 560, 8, 20, 31, 1, NULL);
_trophy.setDetails(Rect(259, 52, 275, 63), 560, 10, 22, 33, 1, NULL);
- _watercolours.setDetails(Rect(214, 48, 239, 64), 560, 12, 24, 35, 1, NULL);
+ _waterColors.setDetails(Rect(214, 48, 239, 64), 560, 12, 24, 35, 1, NULL);
_fileCabinets.setDetails(Rect(0, 47, 49, 100), 560, 14, 26, 37, 1, NULL);
_certificate.setDetails(Rect(280, 51, 292, 62), 560, 11, 23, 34, 1, NULL);
_bookcase.setDetails(Rect(176, 0, 319, 103), 560, 9, 21, 32, 1, NULL);
diff --git a/engines/tsage/blue_force/blueforce_scenes5.h b/engines/tsage/blue_force/blueforce_scenes5.h
index 73d323fc54..56bf20c93b 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.h
+++ b/engines/tsage/blue_force/blueforce_scenes5.h
@@ -225,7 +225,7 @@ public:
NamedObject _object6;
PicturePart _picture1, _picture2, _picture3, _picture4;
Computer _computer;
- NamedHotspot _chair, _lamp, _item4, _trophy, _watercolours, _fileCabinets;
+ NamedHotspot _chair, _lamp, _item4, _trophy, _waterColors, _fileCabinets;
NamedHotspot _certificate, _bookcase, _desk, _carpet, _item12, _office;
ASound _sound1;
bool _field380;
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
index 753a835389..9828ca71d4 100644
--- a/engines/tsage/converse.cpp
+++ b/engines/tsage/converse.cpp
@@ -707,7 +707,7 @@ void StripManager::synchronize(Serializer &s) {
for (int i = 0; i < arrSize; ++i)
_obj44List[i].synchronize(s);
- // Synhcronise script data
+ // Synchronize script data
int scriptSize = _script.size();
s.syncAsUint16LE(scriptSize);
if (s.isLoading())
@@ -754,6 +754,9 @@ void StripManager::remove() {
if (_onEnd)
_onEnd();
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _endHandler = NULL;
+
Action::remove();
}
@@ -855,6 +858,11 @@ void StripManager::signal() {
++obj44Idx;
if (_obj44List[obj44Idx]._field16[0]) {
+ // WORKAROUND: The _lookupList isn't always correctly initialized. But it always
+ // seems to be set to the R2_GLOBALS._stripManager_lookupList, so manually set it
+ if (!_lookupList)
+ _lookupList = R2_GLOBALS._stripManager_lookupList;
+
int f16Index = _lookupList[_obj44List[obj44Idx]._field16[0] - 1];
listId = _obj44List[obj44Idx]._field16[f16Index];
@@ -865,13 +873,16 @@ void StripManager::signal() {
choiceStr = (const char *)&_script[0] + _obj44List[obj44Idx]._list[listIdx]._scriptOffset;
} else {
- for (int listIdx = 0; listIdx < OBJ0A_LIST_SIZE; ++listIdx) {
+ for (int listIdx = idx; listIdx < (OBJ0A_LIST_SIZE - 1); ++listIdx) {
obj44._list[listIdx]._id = obj44._list[listIdx + 1]._id;
obj44._list[listIdx]._scriptOffset = obj44._list[listIdx + 1]._scriptOffset;
if (!obj44._list[listIdx + 1]._id)
obj44._list[listIdx]._id = 0;
}
+
+ --idx;
+ continue;
}
}
}
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index 6b4e2963a5..0080226cbe 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -2111,8 +2111,13 @@ int SceneObject::getFrameCount() {
void SceneObject::animEnded() {
_animateMode = ANIM_MODE_NONE;
- if (_endAction)
- _endAction->signal();
+ if (_endAction) {
+ Action *endAction = _endAction;
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _endAction = NULL;
+
+ endAction->signal();
+ }
}
int SceneObject::changeFrame() {
@@ -3992,7 +3997,7 @@ int WalkRegions::indexOf(const Common::Point &pt, const Common::List<int> *index
}
void WalkRegions::synchronize(Serializer &s) {
- // Synchronise the list of disabled regions as a list of values terminated with a '-1'
+ // Synchronize the list of disabled regions as a list of values terminated with a '-1'
int regionId = 0;
if (s.isLoading()) {
_disabledRegions.clear();
@@ -4242,9 +4247,10 @@ void SceneHandler::process(Event &event) {
// Scan the item list to find one the mouse is within
SynchronizedList<SceneItem *>::iterator i;
for (i = g_globals->_sceneItems.begin(); i != g_globals->_sceneItems.end(); ++i) {
- if ((*i)->contains(event.mousePos)) {
+ SceneItem *item = *i;
+ if (item->contains(event.mousePos)) {
// Pass the action to the item
- bool handled = (*i)->startAction(g_globals->_events.getCursor(), event);
+ bool handled = item->startAction(g_globals->_events.getCursor(), event);
if (!handled)
// Item wasn't handled, keep scanning
continue;
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 5c4fa967e5..71ea160cf5 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -26,6 +26,7 @@
#include "tsage/ringworld/ringworld_demo.h"
#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/ringworld2/ringworld2_logic.h"
+#include "tsage/staticres.h"
namespace TsAGE {
@@ -389,7 +390,7 @@ void Ringworld2Globals::reset() {
_scrollFollower = &_player;
// Reset fields
- Common::fill(&_fadePaletteMap[0][0], &_fadePaletteMap[10][256], 0);
+ Common::fill(&_fadePaletteMap[0][0], &_fadePaletteMap[9][256], 0);
Common::fill(&_paletteMap[0], &_paletteMap[4096], 0);
_fadePaletteFlag = false;
@@ -404,7 +405,7 @@ void Ringworld2Globals::reset() {
_v565E7 = 0;
_v565E9 = -5;
_v565EB = 26;
- _v565F5 = 0;
+ _foodCount = 0;
_v565F6 = 0;
_v565F8 = 0;
_v565FA = 0;
@@ -449,7 +450,7 @@ void Ringworld2Globals::reset() {
_v56613[(17 * 4) + 1] = 1;
_v566A6 = 3800;
- _v566A3 = 2;
+ _landerSuitNumber = 2;
_v566A4 = 1;
_v566A5 = 0;
_v566A8 = 5;
@@ -475,15 +476,12 @@ void Ringworld2Globals::reset() {
_v5780E = 0;
_v57810 = 0;
_v57C2C = 0;
- _v565EC[0] = 0;
- _v565EC[1] = 27;
- _v565EC[2] = 27;
- _v565EC[3] = 4;
- _v565EC[4] = 4;
+ _s1550PlayerArea[R2_QUINN] = Common::Point(27, 4);
+ _s1550PlayerArea[R2_SEEKER] = Common::Point(27, 4);
Common::fill(&_scannerFrequencies[0], &_scannerFrequencies[MAX_CHARACTERS], 1);
_speechSubtitles = SPEECH_VOICE | SPEECH_TEXT;
_insetUp = 0;
- _frameEdgeColour = 2;
+ _frameEdgeColor = 2;
Common::fill(&_stripManager_lookupList[0], &_stripManager_lookupList[12], 0);
_stripManager_lookupList[0] = 1;
_stripManager_lookupList[1] = 1;
@@ -496,6 +494,10 @@ void Ringworld2Globals::reset() {
_stripManager_lookupList[10] = 1;
_stripManager_lookupList[11] = 1;
+ // Reset junk/component data in scene 1550
+ Common::copy(&scene1550JunkLocationsDefault[0], &scene1550JunkLocationsDefault[508],
+ &_scene1550JunkLocations[0]);
+
// Reset fields stored in the player class
_player._characterIndex = R2_QUINN;
_player._characterScene[1] = 100;
@@ -519,11 +521,11 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_v565E7);
s.syncAsSint16LE(_v565E9);
s.syncAsSint16LE(_v565EB);
- s.syncAsSint16LE(_v565F5);
+ s.syncAsSint16LE(_foodCount);
s.syncAsSint16LE(_v565F6);
s.syncAsSint16LE(_v565F8);
s.syncAsSint16LE(_v565FA);
- s.syncAsSint16LE(_v566A3);
+ s.syncAsSint16LE(_landerSuitNumber);
s.syncAsSint16LE(_v566A6);
s.syncAsSint16LE(_v56A93);
s.syncAsSint16LE(_scene1925CurrLevel); // _v56A9C
@@ -539,8 +541,12 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsSint16LE(_v57C2C);
s.syncAsSint16LE(_speechSubtitles);
- for (i = 0; i < 5; i++)
- s.syncAsByte(_v565EC[i]);
+ byte temp;
+ s.syncAsByte(temp);
+ s.syncAsByte(_s1550PlayerArea[R2_QUINN].x);
+ s.syncAsByte(_s1550PlayerArea[R2_SEEKER].x);
+ s.syncAsByte(_s1550PlayerArea[R2_QUINN].y);
+ s.syncAsByte(_s1550PlayerArea[R2_SEEKER].y);
for (i = 0; i < MAX_CHARACTERS; ++i)
s.syncAsByte(_scannerFrequencies[i]);
@@ -566,7 +572,10 @@ void Ringworld2Globals::synchronize(Serializer &s) {
s.syncAsByte(_stripManager_lookupList[i]);
s.syncAsSint16LE(_insetUp);
- s.syncAsByte(_frameEdgeColour);
+ s.syncAsByte(_frameEdgeColor);
+
+ for (i = 0; i < 508; i += 4)
+ s.syncAsByte(_scene1550JunkLocations[i + 2]);
}
} // end of namespace Ringworld2
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index ed27ff0556..839895cea5 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -242,11 +242,6 @@ namespace Ringworld2 {
#define SPEECH_TEXT 1
#define SPEECH_VOICE 2
-#define k5A78C 15
-#define k5A78D 16
-#define k5A790 18
-#define k5A791 17
-
class ScannerDialog;
class Ringworld2Globals: public TsAGE2Globals {
@@ -258,7 +253,7 @@ public:
byte _fadePaletteMap[10][256];
byte _paletteMap[4096];
int _insetUp;
- int _frameEdgeColour; // _v421e
+ int _frameEdgeColor; // _v421e
Rect _v5589E;
Rect _v558B6;
int _v558C2;
@@ -269,7 +264,7 @@ public:
int _v565E7;
int _v565E9;
int _v565EB;
- int _v565F5;
+ int _foodCount;
int _v565F6;
int _v565F8;
int _v565FA;
@@ -280,7 +275,7 @@ public:
byte _v566A4;
byte _v566A5;
int _v566A6;
- byte _v566A3;
+ byte _landerSuitNumber;
byte _v566A8;
byte _v566A9;
byte _v566AA;
@@ -304,9 +299,10 @@ public:
int _v57810;
int _v57C2C;
int _speechSubtitles;
- byte _v565EC[5];
+ Common::Point _s1550PlayerArea[3]; // only used for Quinn and Seeker
byte _scannerFrequencies[4];
byte _stripManager_lookupList[12];
+ byte _scene1550JunkLocations[508];
ScannerDialog *_scannerDialog;
Ringworld2Globals();
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index 1815c3d751..2395cc67ed 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -806,20 +806,20 @@ void GfxElement::drawFrame() {
*((byte *)surface.getBasePtr(tempRect.right - 1, tempRect.bottom - 1)) = 0;
// Inner frame border
- surface.hLine(tempRect.left + 2, tempRect.top + 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColour);
- surface.hLine(tempRect.left + 2, tempRect.bottom - 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColour);
- surface.vLine(tempRect.left + 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColour);
- surface.vLine(tempRect.right - 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColour);
- *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColour;
- *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColour;
- *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColour;
- *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColour;
+ surface.hLine(tempRect.left + 2, tempRect.top + 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor);
+ surface.hLine(tempRect.left + 2, tempRect.bottom - 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor);
+ surface.vLine(tempRect.left + 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColor);
+ surface.vLine(tempRect.right - 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColor);
+ *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColor;
+ *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColor;
+ *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColor;
+ *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColor;
gfxManager.unlockSurface();
gfxManager.getSurface().addDirtyRect(tempRect);
} else {
- // Fill dialog content with specified background colour
+ // Fill dialog content with specified background color
gfxManager.fillRect(tempRect, _colors.background);
--tempRect.bottom; --tempRect.right;
diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
index 57fdef6405..e2afa574de 100644
--- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp
+++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp
@@ -234,9 +234,9 @@ void CharacterDialog::show() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
scene->saveCharacter(oldCharacter);
- // Play a transition sound as the character is changed
+ // Play the correctfrequency, if any, of the character being switched to's scanner device
if (R2_GLOBALS._player._characterScene[0] != 300) {
- switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] - 1) {
case 0:
R2_GLOBALS._sound4.stop();
break;
@@ -256,7 +256,7 @@ void CharacterDialog::show() {
break;
}
} else if (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] > 1) {
- switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
@@ -273,7 +273,7 @@ void CharacterDialog::show() {
break;
}
} else if ((R2_GLOBALS._player._characterScene[1] == 300) && (R2_GLOBALS._scannerFrequencies[1] != 1)) {
- switch (R2_GLOBALS._scannerFrequencies[1]) {
+ switch (R2_GLOBALS._scannerFrequencies[1] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
@@ -294,7 +294,7 @@ void CharacterDialog::show() {
} else if (R2_GLOBALS._scannerFrequencies[2] == 1) {
R2_GLOBALS._sound4.stop();
} else {
- switch (R2_GLOBALS._scannerFrequencies[1]) {
+ switch (R2_GLOBALS._scannerFrequencies[1] - 1) {
case 2:
R2_GLOBALS._sound4.play(45);
break;
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index f1f9f9fe5a..a50dccda03 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -133,6 +133,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - Elevator
return new Scene1530();
case 1550:
+ // Spaceport
return new Scene1550();
case 1575:
return new Scene1575();
@@ -337,7 +338,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
// Exclude the bottom area of the screen to allow room for the UI
T2_GLOBALS._interfaceY = UI_INTERFACE_Y;
- // Initialise fields
+ // Initialize fields
_action = NULL;
_field12 = 0;
_sceneMode = 0;
@@ -358,6 +359,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
void SceneExt::remove() {
_sceneAreas.clear();
Scene::remove();
+ R2_GLOBALS._uiElements._active = true;
}
void SceneExt::process(Event &event) {
@@ -382,27 +384,6 @@ void SceneExt::dispatch() {
Scene::dispatch();
}
-void SceneExt::loadScene(int sceneNum) {
- Scene::loadScene(sceneNum);
-
- _v51C34.top = 0;
- _v51C34.bottom = 300;
-
- int prevScene = R2_GLOBALS._sceneManager._previousScene;
- int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
-
- if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50)) ||
- (sceneNumber == 50) || ((prevScene == 205) && (sceneNumber == 100)) ||
- ((prevScene == 180) && (sceneNumber == 100))) {
- // TODO: sub_17875
- R2_GLOBALS._uiElements._active = true;
- R2_GLOBALS._uiElements.show();
- } else {
- // Update the user interface
- R2_GLOBALS._uiElements.updateInventory();
- }
-}
-
bool SceneExt::display(CursorType action, Event &event) {
switch (action) {
case CURSOR_CROSSHAIRS:
@@ -620,7 +601,7 @@ void SceneHandlerExt::postLoad(int priorSceneBeforeLoad, int currentSceneBeforeL
R2_GLOBALS._gfxColors.foreground = 59;
R2_GLOBALS._fontColors.background = 4;
R2_GLOBALS._fontColors.foreground = 15;
- R2_GLOBALS._frameEdgeColour = 2;
+ R2_GLOBALS._frameEdgeColor = 2;
R2_GLOBALS._scenePalette.loadPalette(0);
R2_GLOBALS._scenePalette.setEntry(255, 0xff, 0xff, 0xff);
@@ -664,7 +645,7 @@ void SceneHandlerExt::setupPaletteMaps() {
break;
}
- // Scan for the palette index with the closest matching colour
+ // Scan for the palette index with the closest matching color
int threshold = 769;
int foundIndex = -1;
for (int pIndex2 = 223; pIndex2 >= 0; --pIndex2) {
@@ -970,7 +951,8 @@ void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) {
R2_GLOBALS._events.setCursor(CURSOR_USE);
// Update the user interface if necessary
- T2_GLOBALS._uiElements.updateInventory();
+ T2_GLOBALS._uiElements.updateInventory(
+ (sceneNumber == R2_GLOBALS._player._characterIndex) ? objectNum : 0);
}
/**
@@ -1324,7 +1306,7 @@ GfxSurface SceneActor::getFrame() {
/*--------------------------------------------------------------------------*/
-SceneArea::SceneArea(): EventHandler() {
+SceneArea::SceneArea(): SceneItem() {
_enabled = true;
_insideArea = false;
_savedCursorNum = CURSOR_NONE;
@@ -1428,6 +1410,7 @@ void SceneExit::process(Event &event) {
/*--------------------------------------------------------------------------*/
void SceneAreaObject::remove() {
+ R2_GLOBALS._sceneItems.remove(this);
_object1.remove();
SceneArea::remove();
--R2_GLOBALS._insetUp;
@@ -1437,19 +1420,22 @@ void SceneAreaObject::process(Event &event) {
if (_insetCount == R2_GLOBALS._insetUp) {
CursorType cursor = R2_GLOBALS._events.getCursor();
- if (_bounds.contains(event.mousePos)) {
+ if (_object1._bounds.contains(event.mousePos)) {
// Cursor moving in bounded area
if (cursor == _cursorNum) {
R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
- if (_cursorNum != cursor)
+ if (_cursorNum != cursor) {
// Cursor moved outside bounded area
- R2_GLOBALS._events.setCursor(_savedCursorNum);
-
+ _savedCursorNum = R2_GLOBALS._events.getCursor();
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+
if (event.eventType == EVENT_BUTTON_DOWN) {
- R2_GLOBALS._events.setCursor(_savedCursorNum);
event.handled = true;
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ remove();
}
}
}
@@ -1469,7 +1455,7 @@ void SceneAreaObject::setDetails(int visage, int strip, int frameNumber, const C
}
void SceneAreaObject::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- ((SceneHotspot *)(this))->setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
+ _object1.setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
2, (SceneItem *)NULL);
}
@@ -1881,7 +1867,7 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
default:
// ANIMPALMODE_CURR_PALETTE
- // Use the closest matching colours in the currently active palette to those specified in the animation
+ // Use the closest matching colors in the currently active palette to those specified in the animation
for (int idx = _subData._palStart; idx < (_subData._palStart + _subData._palSize); ++idx) {
byte r = _subData._palData[idx * 3];
byte g = _subData._palData[idx * 3 + 1];
@@ -2269,14 +2255,14 @@ void ScannerDialog::Button::reset() {
scanner._obj5.postInit();
scanner._obj5.setup(4, 4, 1);
- scanner._obj5.setPosition(Common::Point(R2_GLOBALS._v565EC[1] + 145,
- R2_GLOBALS._v565EC[3] + 59));
+ scanner._obj5.setPosition(Common::Point(R2_GLOBALS._s1550PlayerArea[R2_QUINN].x + 145,
+ R2_GLOBALS._s1550PlayerArea[R2_QUINN].y + 59));
scanner._obj5.fixPriority(257);
scanner._obj6.postInit();
scanner._obj6.setup(4, 4, 2);
- scanner._obj6.setPosition(Common::Point(R2_GLOBALS._v565EC[2] + 145,
- R2_GLOBALS._v565EC[4] + 59));
+ scanner._obj6.setPosition(Common::Point(R2_GLOBALS._s1550PlayerArea[R2_SEEKER].x + 145,
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER].y + 59));
scanner._obj6.fixPriority(257);
break;
case 1700:
@@ -2416,7 +2402,7 @@ void ScannerDialog::remove() {
switch (R2_GLOBALS._sceneManager._sceneNumber) {
case 1550:
case 1700:
- R2_GLOBALS._events.setCursor(R2_GLOBALS._player._canWalk ? CURSOR_ARROW : CURSOR_USE);
+ R2_GLOBALS._events.setCursor(R2_GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE);
break;
case 3800:
case 3900: {
diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h
index 1b4b7fca1f..2b2a28aff8 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.h
+++ b/engines/tsage/ringworld2/ringworld2_logic.h
@@ -42,9 +42,8 @@ public:
static Scene *createScene(int sceneNumber);
};
-class SceneArea: public EventHandler {
+class SceneArea: public SceneItem {
public:
- Rect _bounds;
bool _enabled;
bool _insideArea;
CursorType _cursorNum;
@@ -54,9 +53,12 @@ public:
SceneArea();
void setDetails(const Rect &bounds, CursorType cursor);
+ virtual Common::String getClassName() { return "SceneArea"; }
virtual void synchronize(Serializer &s);
virtual void remove();
virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event) { return false; }
+ virtual void doAction(int action) {}
};
class SceneExit: public SceneArea {
@@ -99,7 +101,6 @@ public:
virtual void remove();
virtual void process(Event &event);
virtual void dispatch();
- virtual void loadScene(int sceneNum);
virtual void refreshBackground(int xAmount, int yAmount);
virtual void saveCharacter(int characterIndex);
virtual void restore() {}
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
index 8d35fc7222..1439557d1e 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
@@ -392,11 +392,11 @@ void Scene100::dispatch() {
*
*--------------------------------------------------------------------------*/
-bool Scene125::Object5::startAction(CursorType action, Event &event) {
+bool Scene125::Food::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE)
return true;
- else
- return SceneActor::startAction(action, event);
+
+ return SceneActor::startAction(action, event);
}
/*--------------------------------------------------------------------------*/
@@ -631,9 +631,9 @@ void Scene125::postInit(SceneObjectList *OwnerList) {
_infoDisk.setPosition(Common::Point(47, 167));
}
- _object6.postInit();
- _object6.setup(162, 1, 1);
- _object6.setPosition(Common::Point(214, 168));
+ _foodDispenser.postInit();
+ _foodDispenser.setup(162, 1, 1);
+ _foodDispenser.setPosition(Common::Point(214, 168));
_diskSlot.setDetails(Rect(27, 145, 81, 159), 126, 9, -1, -1, 1, NULL);
_item3.setDetails(Rect(144, 119, 286, 167), 126, 6, 7, 8, 1, NULL);
@@ -656,8 +656,8 @@ void Scene125::signal() {
_icon4.postInit();
_icon4._sceneRegionId = 5;
- _sceneMode = 2;
setAction(&_sequenceManager, this, 127, &_icon1, &_icon2, &_icon3, &_icon4, &R2_GLOBALS._player, NULL);
+ _sceneMode = 2;
break;
case 2:
_icon1.setup(160, 1, 1);
@@ -698,7 +698,7 @@ void Scene125::signal() {
_icon6._sceneRegionId = 8;
consoleAction(5);
- R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 10:
@@ -971,14 +971,17 @@ void Scene125::consoleAction(int id) {
case 15:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 3) {
+ if (R2_GLOBALS._foodCount < 3) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 2);
- _object5.setPosition(Common::Point(216, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 2);
+ _food.setPosition(Common::Point(216, UI_INTERFACE_Y));
- R2_GLOBALS._v565F5 += 2;
- } else if (R2_GLOBALS._v565F5 == 3) {
+ R2_GLOBALS._foodCount += 2;
+
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
+ } else if (R2_GLOBALS._foodCount == 3) {
SceneItem::display2(126, 13);
} else {
SceneItem::display2(126, 14);
@@ -987,13 +990,16 @@ void Scene125::consoleAction(int id) {
case 16:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 4) {
+ if (R2_GLOBALS._foodCount < 4) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 3);
- _object5.setPosition(Common::Point(218, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 3);
+ _food.setPosition(Common::Point(218, UI_INTERFACE_Y));
- ++R2_GLOBALS._v565F5;
+ ++R2_GLOBALS._foodCount;
+
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
} else {
SceneItem::display2(126, 15);
}
@@ -1001,13 +1007,16 @@ void Scene125::consoleAction(int id) {
case 17:
consoleAction(3);
- if (R2_GLOBALS._v565F5 < 4) {
+ if (R2_GLOBALS._foodCount < 4) {
R2_GLOBALS._player.disableControl();
- _object5.postInit();
- _object5.setup(162, 2, 1);
- _object5.setPosition(Common::Point(215, UI_INTERFACE_Y));
+ _food.postInit();
+ _food.setup(162, 2, 1);
+ _food.setPosition(Common::Point(215, UI_INTERFACE_Y));
+
+ ++R2_GLOBALS._foodCount;
- ++R2_GLOBALS._v565F5;
+ _sceneMode = 128;
+ this->setAction(&_sequenceManager, this, 128, &_foodDispenser, &_food, NULL);
} else {
SceneItem::display2(126, 16);
}
@@ -1924,7 +1933,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 4;
R2_GLOBALS._gfxColors.background = 3;
R2_GLOBALS._fontColors.background = 3;
- R2_GLOBALS._frameEdgeColour = 3;
+ R2_GLOBALS._frameEdgeColor = 3;
break;
case 1:
@@ -1933,7 +1942,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 25;
R2_GLOBALS._gfxColors.background = 43;
R2_GLOBALS._fontColors.background = 48;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 2:
@@ -1943,7 +1952,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.background = 136;
R2_GLOBALS._fontColors.background = 48;
R2_GLOBALS._fontColors.foreground = 253;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 3:
@@ -1952,7 +1961,7 @@ void Scene180::restore() {
R2_GLOBALS._gfxColors.foreground = 84;
R2_GLOBALS._gfxColors.background = 118;
R2_GLOBALS._fontColors.background = 47;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
case 14:
@@ -1962,7 +1971,7 @@ void Scene180::restore() {
R2_GLOBALS._fontColors.foreground = 38;
R2_GLOBALS._gfxColors.foreground = 192;
R2_GLOBALS._gfxColors.background = 30;
- R2_GLOBALS._frameEdgeColour = 48;
+ R2_GLOBALS._frameEdgeColor = 48;
break;
default:
@@ -2026,7 +2035,7 @@ void Scene200::EastExit::changeScene() {
Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 206;
scene->setAction(&scene->_sequenceManager, scene, 206, &R2_GLOBALS._player, NULL);
}
@@ -2035,7 +2044,7 @@ void Scene200::WestExit::changeScene() {
Scene200 *scene = (Scene200 *)R2_GLOBALS._sceneManager._scene;
_enabled = false;
- R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.disableControl(CURSOR_WALK);
scene->_sceneMode = 208;
scene->setAction(&scene->_sequenceManager, scene, 208, &R2_GLOBALS._player, NULL);
}
@@ -3142,7 +3151,7 @@ bool Scene300::Doorway::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
if ((R2_GLOBALS._player._characterIndex == R2_QUINN) &&
- (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500)) {
+ (!R2_GLOBALS.getFlag(44) || R2_GLOBALS._player._characterScene[R2_SEEKER] == 500)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 301;
scene->setAction(&scene->_sequenceManager1, scene, 301, &R2_GLOBALS._player, this, NULL);
@@ -3559,7 +3568,7 @@ void Scene300::signal() {
break;
case 16:
- if (_stripManager._field2E8 == 1) {
+ if (_stripManager._exitMode == 1) {
R2_GLOBALS._player.setAction(NULL);
R2_GLOBALS._sceneManager.changeScene(1000);
} else {
@@ -4813,6 +4822,11 @@ void Scene400::dispatch() {
*
*--------------------------------------------------------------------------*/
+Scene500::PanelDialog::Button::Button() {
+ _buttonId = 0;
+ _buttonDown = false;
+}
+
bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
@@ -4835,17 +4849,18 @@ bool Scene500::ControlPanel::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
-bool Scene500::Object2::startAction(CursorType action, Event &event) {
+bool Scene500::Seeker::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
if (action == CURSOR_TALK) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1101 : 1103;
} else {
scene->_stripNumber = R2_GLOBALS.getFlag(26) ? 1102 : 1105;
}
+ scene->_sceneMode = 524;
scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
return true;
} else {
@@ -4853,7 +4868,7 @@ bool Scene500::Object2::startAction(CursorType action, Event &event) {
}
}
-bool Scene500::Object3::startAction(CursorType action, Event &event) {
+bool Scene500::Suit::startAction(CursorType action, Event &event) {
Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -4864,20 +4879,20 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
case CURSOR_USE:
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if ((_strip != 3) && (_strip != 7))
- SceneItem::display2(500, _strip);
+ SceneItem::display2(500, _strip + 25);
else if (R2_GLOBALS.getFlag(26)) {
R2_GLOBALS._player.disableControl();
scene->_stripNumber = 1103;
scene->_sceneMode = 524;
- scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 512, &R2_GLOBALS._player, NULL);
} else if (!R2_GLOBALS.getFlag(28))
SceneItem::display2(500, 41);
- else if (!R2_GLOBALS.getFlag(40))
+ else if (!R2_GLOBALS.getFlag(25))
SceneItem::display2(500, 40);
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 512;
- scene->setAction(&scene->_sequenceManager1, scene, 524, &R2_GLOBALS._player, &scene->_object3, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 512, &R2_GLOBALS._player, &scene->_suit, NULL);
R2_GLOBALS.setFlag(26);
}
} else {
@@ -4893,7 +4908,7 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
else {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 515;
- scene->setAction(&scene->_sequenceManager1, scene, 515, &R2_GLOBALS._player, &scene->_object3, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 515, &R2_GLOBALS._player, &scene->_suit, NULL);
R2_GLOBALS.setFlag(28);
}
return true;
@@ -4903,12 +4918,7 @@ bool Scene500::Object3::startAction(CursorType action, Event &event) {
return true;
default:
- if (action < R2_LAST_INVENT) {
- SceneItem::display2(500, action);
- return true;
- } else {
- return SceneActor::startAction(action, event);
- }
+ return SceneActor::startAction(action, event);
}
}
@@ -4976,7 +4986,7 @@ bool Scene500::AirLock::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = (R2_GLOBALS._player._characterIndex == R2_QUINN) ? 521 : 522;
scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player,
- &scene->_object2, &scene->_airLock, NULL);
+ &scene->_seeker, &scene->_airLock, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -5045,7 +5055,36 @@ bool Scene500::Locker2::startAction(CursorType action, Event &event) {
}
}
-bool Scene500::Object::startAction(CursorType action, Event &event) {
+/*--------------------------------------------------------------------------*/
+
+void Scene500::PanelDialog::setDetails(int visage, int strip, int frameNumber,
+ const Common::Point &pt) {
+ SceneAreaObject::setDetails(visage, strip, frameNumber, pt);
+ SceneAreaObject::setDetails(500, 43, 32, 45);
+
+ _button1.setupButton(1);
+ _button2.setupButton(2);
+ _button3.setupButton(3);
+}
+
+void Scene500::PanelDialog::remove() {
+ Scene500 *scene = (Scene500 *)BF_GLOBALS._sceneManager._scene;
+ scene->_sceneAreas.remove(&_button1);
+ scene->_sceneAreas.remove(&_button2);
+ scene->_sceneAreas.remove(&_button3);
+
+ _button1.remove();
+ _button2.remove();
+ _button3.remove();
+
+ SceneAreaObject::remove();
+
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 511;
+ scene->setAction(&scene->_sequenceManager1, scene, 511, &R2_GLOBALS._player, NULL);
+}
+
+bool Scene500::PanelDialog::Button::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
return false;
} else {
@@ -5053,6 +5092,119 @@ bool Scene500::Object::startAction(CursorType action, Event &event) {
}
}
+void Scene500::PanelDialog::Button::setupButton(int buttonId) {
+ _buttonId = buttonId;
+ _buttonDown = false;
+ SceneActor::postInit();
+ setup(500, 7, 1);
+ fixPriority(251);
+
+ switch (_buttonId) {
+ case 1:
+ setPosition(Common::Point(139, 78));
+ break;
+ case 2:
+ setPosition(Common::Point(139, 96));
+ break;
+ case 3:
+ setPosition(Common::Point(139, 114));
+ break;
+ default:
+ break;
+ }
+
+ Scene500 *scene = (Scene500 *)BF_GLOBALS._sceneManager._scene;
+ scene->_sceneAreas.push_front(this);
+}
+
+void Scene500::PanelDialog::Button::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_buttonId);
+ s.syncAsSint16LE(_buttonDown);
+}
+
+void Scene500::PanelDialog::Button::process(Event &event) {
+ if ((event.eventType == EVENT_BUTTON_DOWN) &&
+ (R2_GLOBALS._events.getCursor() == CURSOR_USE) &&
+ _bounds.contains(event.mousePos) && !_buttonDown) {
+ _buttonDown = true;
+ event.handled = true;
+ setFrame(2);
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && _buttonDown) {
+ setFrame(1);
+ _buttonDown = false;
+ event.handled = true;
+
+ doButtonPress();
+ }
+}
+
+void Scene500::PanelDialog::Button::doButtonPress() {
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+
+ if (R2_GLOBALS.getFlag(28)) {
+ SceneItem::display2(500, 48);
+ } else {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = _buttonId;
+
+ switch (_buttonId) {
+ case 1:
+ if (--R2_GLOBALS._landerSuitNumber == 0)
+ R2_GLOBALS._landerSuitNumber = 3;
+
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 5;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
+ &scene->_suit, &scene->_object8, NULL);
+ } else {
+ scene->_sound1.play(127);
+ scene->_object1.animate(ANIM_MODE_6, scene);
+ }
+ break;
+
+ case 2:
+ if (++R2_GLOBALS._landerSuitNumber == 4)
+ R2_GLOBALS._v566A4 = 1;
+
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 6;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
+ &scene->_suit, &scene->_object8, NULL);
+ } else {
+ scene->_sound1.play(127);
+ scene->_object1.animate(ANIM_MODE_6, scene);
+ }
+ break;
+
+ case 3:
+ if (R2_GLOBALS.getFlag(35)) {
+ scene->_sceneMode = 509;
+ scene->setAction(&scene->_sequenceManager1, scene, 509, &scene->_object1,
+ &scene->_suit, &scene->_object8, NULL);
+ } else {
+ scene->_suit.postInit();
+ scene->_suit.hide();
+ scene->_suit._effect = 1;
+ scene->_suit.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
+ scene->_suit.setup(502, R2_GLOBALS._landerSuitNumber + 2, 1);
+
+ scene->setAction(&scene->_sequenceManager1, scene, 508,
+ &R2_GLOBALS._player, &scene->_object1, &scene->_suit,
+ &scene->_object8, NULL);
+ R2_GLOBALS.setFlag(35);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
/*--------------------------------------------------------------------------*/
void Scene500::postInit(SceneObjectList *OwnerList) {
@@ -5071,23 +5223,23 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._walkRegions.disableRegion(1);
- _object2.postInit();
- _object2._effect = 1;
- _object2.setup(1505, 1, 1);
- _object2._moveDiff.x = 5;
- _object2.setPosition(Common::Point(42, 151));
- _object2.setDetails(500, 34, 35, 36, 1, (SceneItem *)NULL);
+ _seeker.postInit();
+ _seeker._effect = 1;
+ _seeker.setup(1505, 1, 1);
+ _seeker._moveDiff.x = 5;
+ _seeker.setPosition(Common::Point(42, 151));
+ _seeker.setDetails(500, 34, 35, 36, 1, (SceneItem *)NULL);
} else if (R2_GLOBALS._player._characterScene[R2_QUINN] == 500) {
- _object2.postInit();
- _object2._effect = 1;
- _object2.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 1, 1);
- _object2.setPosition(Common::Point(42, 151));
+ _seeker.postInit();
+ _seeker._effect = 1;
+ _seeker.setup(R2_GLOBALS.getFlag(26) ? 1500 : 10, 1, 1);
+ _seeker.setPosition(Common::Point(42, 151));
R2_GLOBALS._walkRegions.disableRegion(1);
R2_GLOBALS._walkRegions.disableRegion(2);
R2_GLOBALS._walkRegions.disableRegion(3);
- _object2.setDetails(500, 37, 38, -1, 1, (SceneItem *)NULL);
+ _seeker.setDetails(500, 37, 38, -1, 1, (SceneItem *)NULL);
}
}
@@ -5167,16 +5319,16 @@ void Scene500::postInit(SceneObjectList *OwnerList) {
} else {
_object8.setup(500, 8, 7);
- _object3.postInit();
- _object3._effect = 1;
- _object3.setPosition(Common::Point(247, 52));
- _object3.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
+ _suit.postInit();
+ _suit._effect = 1;
+ _suit.setPosition(Common::Point(247, 52));
+ _suit.setDetails(500, -1, -1, -1, 2, (SceneItem *)NULL);
if (!R2_GLOBALS.getFlag(26)) {
if (R2_GLOBALS.getFlag(28))
- _object3.setup(502, 7, 2);
+ _suit.setup(502, 7, 2);
else
- _object3.setup(502, R2_GLOBALS._v566A3 + 2, 7);
+ _suit.setup(502, R2_GLOBALS._landerSuitNumber + 2, 7);
}
}
@@ -5222,7 +5374,7 @@ void Scene500::signal() {
_object1.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 6:
@@ -5231,7 +5383,7 @@ void Scene500::signal() {
_object1.animate(ANIM_MODE_5, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 7:
@@ -5239,14 +5391,14 @@ void Scene500::signal() {
_object8.animate(ANIM_MODE_6, this);
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 500:
R2_GLOBALS._sceneManager.changeScene(700);
break;
case 501:
- if (R2_GLOBALS._player._characterScene[R2_MIRANDA] == 500) {
+ if (R2_GLOBALS._player._characterScene[R2_SEEKER] == 500) {
_stripNumber = 1100;
_sceneMode = 523;
setAction(&_sequenceManager1, this, 523, &R2_GLOBALS._player, NULL);
@@ -5277,7 +5429,7 @@ void Scene500::signal() {
break;
case 506:
case 518:
- R2_GLOBALS.setFlag(11);
+ R2_GLOBALS.setFlag(12);
R2_GLOBALS._player.enableControl();
break;
case 507:
@@ -5287,12 +5439,12 @@ void Scene500::signal() {
break;
case 509:
R2_GLOBALS.clearFlag(35);
- _object3.remove();
+ _suit.remove();
R2_GLOBALS._player.enableControl();
break;
case 510:
R2_GLOBALS._player.enableControl();
- _area1.setDetails(500, 6, 1, Common::Point(160, 120));
+ _panelDialog.setDetails(500, 6, 1, Common::Point(160, 120));
R2_GLOBALS._player.enableControl();
break;
case 513:
@@ -5391,22 +5543,22 @@ bool Scene600::Item4::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
scene->_object1.setup2(603, 3, 1, 239, 54, 10, 0);
- scene->_actor3.postInit();
- scene->_actor2.postInit();
+ scene->_stasisField.postInit();
+ scene->_computer.postInit();
scene->_sceneMode = 612;
- scene->setAction(&scene->_sequenceManager1, scene, 612, &scene->_actor3, &scene->_actor2, &R2_GLOBALS._player, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 612, &scene->_stasisField, &scene->_computer, &R2_GLOBALS._player, NULL);
return true;
}
-void Scene600::Actor4::signal() {
+void Scene600::Smoke::signal() {
Common::Point pt(177 + R2_GLOBALS._randomSource.getRandomNumber(5),
108 + R2_GLOBALS._randomSource.getRandomNumber(3));
NpcMover *mover = new NpcMover();
addMover(mover, &pt, this);
}
-bool Scene600::Actor4::startAction(CursorType action, Event &event) {
+bool Scene600::Smoke::startAction(CursorType action, Event &event) {
if (action >= CURSOR_WALK)
// Only action cursors
return SceneActor::startAction(action, event);
@@ -5414,7 +5566,7 @@ bool Scene600::Actor4::startAction(CursorType action, Event &event) {
return false;
}
-GfxSurface Scene600::Actor4::getFrame() {
+GfxSurface Scene600::Smoke::getFrame() {
GfxSurface frame = SceneActor::getFrame();
if (_effect) {
@@ -5435,7 +5587,8 @@ GfxSurface Scene600::Actor4::getFrame() {
}
bool Scene600::Doorway::startAction(CursorType action, Event &event) {
- if ((action < CURSOR_WALK) && (action >= R2CURSORS_START))
+ // Only action cursors
+ if (action < CURSOR_WALK)
return false;
if (action != CURSOR_USE)
@@ -5478,16 +5631,17 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
if (action < CURSOR_WALK) {
switch (action) {
case R2_COM_SCANNER:
+ // If laser is destroyed
if (R2_GLOBALS.getFlag(6)) {
if (R2_GLOBALS.getFlag(8)) {
SceneItem::display(600, 29, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
return true;
} else {
R2_GLOBALS._player.disableControl();
- scene->_actor8.postInit();
- scene->_actor8.setDetails(600, 20, -1, -1, 4, &scene->_laser);
+ scene->_scanner.postInit();
+ scene->_scanner.setDetails(600, 20, -1, -1, 4, &scene->_laser);
scene->_sceneMode = 607;
- scene->setAction(&scene->_sequenceManager1, scene, 607, &R2_GLOBALS._player, &scene->_actor8, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 607, &R2_GLOBALS._player, &scene->_scanner, NULL);
return true;
}
} else {
@@ -5503,21 +5657,22 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
scene->_aerosol.postInit();
scene->_aerosol.setDetails(600, 27, -1, -1, 5, &scene->_laser);
- scene->_actor4.postInit();
- scene->_actor4.setup(601, 3, 1);
- scene->_actor4._effect = 3;
- scene->_actor4._moveDiff = Common::Point(1, 1);
- scene->_actor4._moveRate = 2;
- scene->_actor4._numFrames = 3;
- scene->_actor4.setDetails(600, 24, 25, 26, 5, &scene->_aerosol);
+ scene->_smoke.postInit();
+ scene->_smoke.setup(601, 3, 1);
+ scene->_smoke._effect = 3;
+ scene->_smoke._moveDiff = Common::Point(1, 1);
+ scene->_smoke._moveRate = 2;
+ scene->_smoke._numFrames = 3;
+ scene->_smoke.setDetails(600, 24, 25, 26, 5, &scene->_aerosol);
scene->_sceneMode = 605;
- scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_aerosol, &scene->_actor4, &scene->_doorway, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 605, &R2_GLOBALS._player, &scene->_aerosol, &scene->_smoke, &scene->_doorway, NULL);
return true;
}
break;
case R2_CLAMP:
+ // If cloud is active
if (R2_GLOBALS.getFlag(5)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 606;
@@ -5547,9 +5702,11 @@ bool Scene600::Laser::startAction(CursorType action, Event &event) {
bool Scene600::Aerosol::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
- if ((action < CURSOR_WALK) && (action >= R2CURSORS_START)) {
+ // Only action cursors
+ if (action < CURSOR_WALK)
return false;
- } else if (action == CURSOR_USE) {
+
+ if (action == CURSOR_USE) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 614;
scene->setAction(&scene->_sequenceManager1, scene, 614, &R2_GLOBALS._player, &scene->_aerosol, NULL);
@@ -5574,17 +5731,17 @@ void Scene600::synchronize(Serializer &s) {
s.syncAsByte(_pixelMap[i]);
}
-bool Scene600::Actor8::startAction(CursorType action, Event &event) {
+bool Scene600::Scanner::startAction(CursorType action, Event &event) {
Scene600 *scene = (Scene600 *)R2_GLOBALS._sceneManager._scene;
- if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(9) == 600)) {
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 615;
- scene->setAction(&scene->_sequenceManager1, scene, 615, &R2_GLOBALS._player, &scene->_actor8, NULL);
- } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(9) == 600) && (R2_GLOBALS._scannerFrequencies[1] == 2) && (!R2_GLOBALS.getFlag(8))){
+ scene->setAction(&scene->_sequenceManager1, scene, 615, &R2_GLOBALS._player, &scene->_scanner, NULL);
+ } else if ((action == R2_SONIC_STUNNER) && (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600) && (R2_GLOBALS._scannerFrequencies[1] == 2) && (!R2_GLOBALS.getFlag(8))){
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 608;
- scene->setAction(&scene->_sequenceManager1, scene, 608, &R2_GLOBALS._player, &scene->_actor4, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 608, &R2_GLOBALS._player, &scene->_smoke, NULL);
} else {
return SceneActor::startAction(action, event);
}
@@ -5599,7 +5756,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._walkRegions.enableRegion(3);
_field412 = 0;
- // Initialise pixel map for the obscuring effect
+ // Initialize pixel map for the obscuring effect
ScenePalette &pal = R2_GLOBALS._scenePalette;
uint r, g, b;
for (int i = 0; i < 256; ++i) {
@@ -5618,11 +5775,11 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
_laser.postInit();
_laser.setPosition(Common::Point(246, 41));
- if (R2_INVENTORY.getObjectScene(9) == 600) {
- _actor8.postInit();
- _actor8.setup(602, 5, 1);
- _actor8.setPosition(Common::Point(246, 41));
- _actor8.setDetails(600, 20, -1, -1, 1, (SceneItem *) NULL);
+ if (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600) {
+ _scanner.postInit();
+ _scanner.setup(602, 5, 1);
+ _scanner.setPosition(Common::Point(246, 41));
+ _scanner.setDetails(600, 20, -1, -1, 1, (SceneItem *) NULL);
switch (R2_GLOBALS._scannerFrequencies[1] - 2) {
case 0:
R2_GLOBALS._sound4.play(45);
@@ -5658,7 +5815,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
_object1.setup2(603, 1, 1, 244, 50, 10, 0);
if (R2_GLOBALS.getFlag(5)) {
- if (R2_INVENTORY.getObjectScene(12) == 600) {
+ if (R2_INVENTORY.getObjectScene(R2_AEROSOL) == 600) {
_aerosol.postInit();
_aerosol.setup(602, 2, 2);
_aerosol.setPosition(Common::Point(189, 95));
@@ -5667,23 +5824,25 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
if (R2_GLOBALS.getFlag(8)) {
if (R2_GLOBALS.getFlag(9)) {
- _actor2.postInit();
- _actor2.setup(603, 2, 1);
- _actor2.setPosition(Common::Point(233, 45));
- _actor2.animate(ANIM_MODE_2, NULL);_actor2.fixPriority(11);
+ // Computer is active
+ _computer.postInit();
+ _computer.setup(603, 2, 1);
+ _computer.setPosition(Common::Point(233, 45));
+ _computer.animate(ANIM_MODE_2, NULL);
+ _computer.fixPriority(11);
}
} else {
- _actor4.postInit();
- _actor4.setup(601, 1, 1);
- _actor4.setPosition(Common::Point(180, 110));
- _actor4._moveDiff = Common::Point(1, 1);
- _actor4._moveRate = 2;
- _actor4._numFrames = 3;
- _actor4.animate(ANIM_MODE_2, NULL);
- _actor4.fixPriority(130);
- _actor4._effect = 3;
- _actor4.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
- _actor4.signal();
+ _smoke.postInit();
+ _smoke.setup(601, 1, 1);
+ _smoke.setPosition(Common::Point(180, 110));
+ _smoke._moveDiff = Common::Point(1, 1);
+ _smoke._moveRate = 2;
+ _smoke._numFrames = 3;
+ _smoke.animate(ANIM_MODE_2, NULL);
+ _smoke.fixPriority(130);
+ _smoke._effect = 3;
+ _smoke.setDetails(600, 24, 25, 26, 1, (SceneItem *) NULL);
+ _smoke.signal();
}
}
@@ -5727,7 +5886,7 @@ void Scene600::postInit(SceneObjectList *OwnerList) {
}
void Scene600::remove() {
- if (R2_INVENTORY.getObjectScene(9) == 600)
+ if (R2_INVENTORY.getObjectScene(R2_COM_SCANNER) == 600)
R2_GLOBALS._sound4.fadeOut2(NULL);
SceneExt::remove();
}
@@ -5742,6 +5901,7 @@ void Scene600::signal() {
R2_GLOBALS._sceneManager.changeScene(700);
break;
case 605:
+ // After cloud is active
R2_GLOBALS._player.enableControl();
R2_GLOBALS._walkRegions.enableRegion(6);
R2_GLOBALS._walkRegions.enableRegion(7);
@@ -5751,42 +5911,48 @@ void Scene600::signal() {
R2_INVENTORY.setObjectScene(R2_AEROSOL, 600);
R2_GLOBALS.setFlag(5);
- _actor4._effect = 3;
- _actor4.signal();
+ _smoke._effect = 3;
+ _smoke.signal();
break;
case 606:
- R2_INVENTORY.setObjectScene(15, 600);
+ // After Clamp is put on laser
+ R2_INVENTORY.setObjectScene(R2_CLAMP, 600);
R2_GLOBALS._player.enableControl();
break;
case 607:
- R2_INVENTORY.setObjectScene(9, 600);
+ // After scanner is put on laser
+ R2_INVENTORY.setObjectScene(R2_COM_SCANNER, 600);
R2_GLOBALS._player.enableControl();
break;
case 608:
+ // deactivate cloud
R2_GLOBALS.setFlag(8);
- _actor4.remove();
+ _smoke.remove();
R2_GLOBALS._walkRegions.disableRegion(6);
R2_GLOBALS._walkRegions.disableRegion(9);
R2_GLOBALS._walkRegions.disableRegion(10);
R2_GLOBALS._player.enableControl();
break;
case 612:
+ // Deactivate stasis field
R2_GLOBALS.setFlag(9);
- _actor3.remove();
+ _stasisField.remove();
R2_GLOBALS._sceneItems.remove(&_item4);
- _actor2.setDetails(600, 21, -1, 23, 4, &_item4);
+ _computer.setDetails(600, 21, -1, 23, 4, &_item4);
_background.setDetails(600, 7, -1, -1, 3, (SceneItem *) NULL);
R2_GLOBALS._player.enableControl(CURSOR_USE);
break;
case 614:
+ // Pick up Aerosol
R2_GLOBALS._player.enableControl();
_aerosol.remove();
- R2_INVENTORY.setObjectScene(12, 1);
+ R2_INVENTORY.setObjectScene(R2_AEROSOL, 1);
R2_GLOBALS._walkRegions.disableRegion(7);
break;
case 615:
- _actor8.remove();
- R2_INVENTORY.setObjectScene(9, 1);
+ // Pick up Com Scanner
+ _scanner.remove();
+ R2_INVENTORY.setObjectScene(R2_COM_SCANNER, 1);
R2_GLOBALS._player.enableControl();
break;
default:
@@ -5842,7 +6008,7 @@ void Scene600::dispatch() {
_aSound1.play(40);
Scene::dispatch();
- if ((_actor4._strip == 3) && (_actor4._frame == 3)) {
+ if ((_smoke._strip == 3) && (_smoke._frame == 3)) {
_actor1.setStrip(4);
_actor1.setFrame(1);
}
@@ -5868,26 +6034,26 @@ bool Scene700::Item11::startAction(CursorType action, Event &event) {
return NamedHotspot::startAction(action, event);
}
-bool Scene700::Item12::startAction(CursorType action, Event &event) {
+bool Scene700::HandGrip::startAction(CursorType action, Event &event) {
Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case R2_CABLE_HARNESS:
R2_GLOBALS._player.disableControl();
- scene->_actor5.postInit();
- scene->_actor5.setup(701, 3, 2);
- scene->_actor5.setPosition(Common::Point(243, 98));
- scene->_actor5.setDetails(700, 37, -1, -1, 2, (SceneItem *) NULL);
- scene->_actor5.hide();
+ scene->_cable.postInit();
+ scene->_cable.setup(701, 3, 2);
+ scene->_cable.setPosition(Common::Point(243, 98));
+ scene->_cable.setDetails(700, 37, -1, -1, 2, (SceneItem *) NULL);
+ scene->_cable.hide();
scene->_sceneMode = 20;
break;
case R2_ATTRACTOR_CABLE_HARNESS:
R2_GLOBALS._player.disableControl();
- scene->_actor5.postInit();
- scene->_actor5.setup(701, 2, 8);
- scene->_actor5.setPosition(Common::Point(243, 98));
- scene->_actor5.setDetails(700, 38, -1, -1, 2, (SceneItem *) NULL);
- scene->_actor5.hide();
+ scene->_cable.postInit();
+ scene->_cable.setup(701, 2, 8);
+ scene->_cable.setPosition(Common::Point(243, 98));
+ scene->_cable.setDetails(700, 38, -1, -1, 2, (SceneItem *) NULL);
+ scene->_cable.hide();
scene->_sceneMode = 21;
break;
default:
@@ -5895,7 +6061,7 @@ bool Scene700::Item12::startAction(CursorType action, Event &event) {
break;
}
- scene->setAction(&scene->_sequenceManager, scene, 707, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 707, &R2_GLOBALS._player, &scene->_cable, NULL);
return true;
}
@@ -5947,7 +6113,7 @@ bool Scene700::Actor4::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene700::Actor5::startAction(CursorType action, Event &event) {
+bool Scene700::Cable::startAction(CursorType action, Event &event) {
Scene700 *scene = (Scene700 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -5981,9 +6147,9 @@ bool Scene700::Actor5::startAction(CursorType action, Event &event) {
break;
case R2_ATTRACTOR_UNIT:
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) == 700) {
+ if (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 700) {
scene->_sceneMode = 706;
- scene->setAction(&scene->_sequenceManager, scene, 706, &R2_GLOBALS._player, &scene->_actor5, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 706, &R2_GLOBALS._player, &scene->_cable, NULL);
} else {
scene->_sceneMode = 15;
Common::Point pt(_position.x - 12, _position.y + 1);
@@ -6065,20 +6231,20 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
_actor9.setDetails(700, 33, -1, 35, 1, (SceneItem *) NULL);
if ((R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS) != 1) && (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS) != 1)) {
- _actor5.postInit();
- _actor5.fixPriority(10);
+ _cable.postInit();
+ _cable.fixPriority(10);
switch (R2_INVENTORY.getObjectScene(R2_ATTRACTOR_CABLE_HARNESS)) {
case 0:
switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
case 0:
- _actor5.setup(701, 3, 2);
- _actor5.setPosition(Common::Point(243, 98));
- _actor5.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 3, 2);
+ _cable.setPosition(Common::Point(243, 98));
+ _cable.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
break;
case 700:
- _actor5.setup(701, 3, 1);
- _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
- _actor5.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 3, 1);
+ _cable.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _cable.setDetails(700, 37, -1, -1, 1, (SceneItem *) NULL);
break;
default:
break;
@@ -6088,22 +6254,22 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
switch (R2_INVENTORY.getObjectScene(R2_CABLE_HARNESS)) {
case 0:
if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
- _actor5.setup(701, 2, 1);
+ _cable.setup(701, 2, 1);
else
- _actor5.setup(701, 2, 8);
- _actor5.setPosition(Common::Point(243, 98));
- _actor5.fixPriority(77);
- _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setup(701, 2, 8);
+ _cable.setPosition(Common::Point(243, 98));
+ _cable.fixPriority(77);
+ _cable.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
break;
case 700:
- _actor5.setup(701, 1, 8);
+ _cable.setup(701, 1, 8);
if (R2_GLOBALS._v565E7 == 0) {
- _actor5.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
+ _cable.setPosition(Common::Point(356 - (R2_GLOBALS._v565EB * 8), 148 - (((R2_GLOBALS._v565E9 + 10) / 5) * 4)));
} else {
- _actor5.setup(701, 1, 1);
- _actor5.setPosition(Common::Point(_actor1._position.x + 1, _actor1._position.y + 120));
+ _cable.setup(701, 1, 1);
+ _cable.setPosition(Common::Point(_actor1._position.x + 1, _actor1._position.y + 120));
}
- _actor5.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
+ _cable.setDetails(700, 38, -1, -1, 1, (SceneItem *) NULL);
break;
default:
break;
@@ -6118,7 +6284,7 @@ void Scene700::postInit(SceneObjectList *OwnerList) {
_actor4.setPosition(Common::Point(454, 117));
_actor4.setDetails(700, 27, -1, -1, 1, (SceneItem *) NULL);
- _item12.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, NULL);
+ _handGrip.setDetails(Rect(234, 90, 252, 110), 700, 39, -1, -1, 1, NULL);
_item6.setDetails(Rect(91, 158, 385, 167), 700, 6, -1, 8, 1, NULL);
_item2.setDetails(Rect(47, 115, 149, 124), 700, 40, -1, 41, 1, NULL);
_item3.setDetails(Rect(151, 108, 187, 124), 700, 40, -1, 41, 1, NULL);
@@ -6223,7 +6389,7 @@ void Scene700::signal() {
break;
case 11:
_sceneMode = 12;
- _actor5.remove();
+ _cable.remove();
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
case 12:
@@ -6248,13 +6414,13 @@ void Scene700::signal() {
break;
case 16:
_sceneMode = 17;
- _actor5.setup(701, 1, 8);
- _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
- if ((R2_GLOBALS._v565E5 != 0) && (_actor5._position.x == _actor1._position.x + 1) && (_actor5._position.x == 148 - (((R2_GLOBALS._electromagnetChangeAmount + 10) / 5) * 4))) {
- _actor5.animate(ANIM_MODE_6, NULL);
- Common::Point pt(_actor5._position.x, _actor1._position.y + 120);
+ _cable.setup(701, 1, 8);
+ _cable.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
+ if ((R2_GLOBALS._v565E5 != 0) && (_cable._position.x == _actor1._position.x + 1) && (_cable._position.x == 148 - (((R2_GLOBALS._electromagnetChangeAmount + 10) / 5) * 4))) {
+ _cable.animate(ANIM_MODE_6, NULL);
+ Common::Point pt(_cable._position.x, _actor1._position.y + 120);
NpcMover *mover = new NpcMover();
- _actor5.addMover(mover, &pt, NULL);
+ _cable.addMover(mover, &pt, NULL);
R2_GLOBALS._v565E7 = 1;
}
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
@@ -6274,9 +6440,9 @@ void Scene700::signal() {
R2_GLOBALS._player.enableControl();
break;
case 21:
- _actor5.fixPriority(77);
+ _cable.fixPriority(77);
if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
- _actor5.animate(ANIM_MODE_6, NULL);
+ _cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
R2_GLOBALS._player.enableControl();
@@ -6291,10 +6457,10 @@ void Scene700::signal() {
R2_GLOBALS._sceneManager.changeScene(900);
break;
case 706:
- _actor5.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
- _actor5.fixPriority(77);
+ _cable.setDetails(700, 38, -1, -1, 3, (SceneItem *) NULL);
+ _cable.fixPriority(77);
if ((R2_GLOBALS._v565E5 != 0) && (R2_GLOBALS._electromagnetChangeAmount == 20) && (R2_GLOBALS._electromagnetZoom == 70))
- _actor5.animate(ANIM_MODE_6, NULL);
+ _cable.animate(ANIM_MODE_6, NULL);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 700);
R2_GLOBALS._player.enableControl();
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h
index bc30743aca..a2f2accaba 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.h
@@ -102,7 +102,7 @@ public:
class Scene125: public SceneExt {
/* Objects */
- class Object5: public SceneActor {
+ class Food: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -136,7 +136,7 @@ public:
ASoundExt _sound1;
NamedHotspot _background, _item2, _item3;
DiskSlot _diskSlot;
- SceneActor _object1, _object2, _object3, _object4, _object5, _object6, _infoDisk;
+ SceneActor _object1, _object2, _object3, _object4, _food, _foodDispenser, _infoDisk;
Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
SequenceManager _sequenceManager;
SceneText _sceneText;
@@ -524,6 +524,31 @@ public:
};
class Scene500: public SceneExt {
+ /* Dialogs */
+ class PanelDialog: public SceneAreaObject {
+ class Button: public SceneActor {
+ private:
+ int _buttonId;
+ bool _buttonDown;
+
+ void doButtonPress();
+ public:
+ Button();
+ virtual Common::String getClassName() { return "Scene500_Button"; }
+ virtual void process(Event &event);
+ virtual bool startAction(CursorType action, Event &event);
+ virtual void synchronize(Serializer &s);
+
+ void setupButton(int buttonId);
+ };
+ public:
+ Button _button1, _button2, _button3;
+
+ virtual Common::String getClassName() { return "Scene500_PanelWindow"; }
+ virtual void remove();
+ void setDetails(int visage, int strip, int frameNumber, const Common::Point &pt);
+ };
+
/* Items */
class ControlPanel: public SceneHotspot {
public:
@@ -531,11 +556,11 @@ class Scene500: public SceneExt {
};
/* Objects */
- class Object2: public SceneActor {
+ class Seeker: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object3: public SceneActor {
+ class Suit: public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -570,20 +595,16 @@ class Scene500: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Object: public SceneActor {
- public:
- virtual bool startAction(CursorType action, Event &event);
- };
public:
int _stripNumber;
byte _buffer[2710];
- SpeakerSeeker _seekerSpeaker;
- SpeakerQuinn _quinnSpeaker;
+ SpeakerSeeker500 _seekerSpeaker;
+ SpeakerQuinn500 _quinnSpeaker;
SceneHotspot _background, _item2;
ControlPanel _controlPanel;
SceneActor _object1;
- Object2 _object2;
- Object3 _object3;
+ Seeker _seeker;
+ Suit _suit;
Doorway _doorway;
OxygenTanks _tanks1, _tanks2;
AirLock _airLock;
@@ -592,8 +613,7 @@ public:
SonicStunner _sonicStunner;
Locker1 _locker1;
Locker2 _locker2;
- SceneAreaObject _area1;
- Object _obj1, _obj2, _obj3;
+ PanelDialog _panelDialog;
ASoundExt _sound1;
SequenceManager _sequenceManager1, _sequenceManager2;
public:
@@ -622,7 +642,7 @@ class Scene600 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor4 : public SceneActor {
+ class Smoke : public SceneActor {
public:
virtual void signal();
virtual bool startAction(CursorType action, Event &event);
@@ -640,7 +660,7 @@ class Scene600 : public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor8 : public SceneActor {
+ class Scanner : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -653,13 +673,13 @@ public:
CompartmentHotspot _item5;
BackgroundSceneObject _object1;
SceneActor _actor1;
- SceneActor _actor2;
- SceneActor _actor3;
- Actor4 _actor4;
+ SceneActor _computer;
+ SceneActor _stasisField;
+ Smoke _smoke;
Doorway _doorway;
Laser _laser;
Aerosol _aerosol;
- Actor8 _actor8;
+ Scanner _scanner;
ASoundExt _aSound1;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -679,7 +699,7 @@ class Scene700: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Item12 : public NamedHotspot {
+ class HandGrip : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -696,7 +716,7 @@ class Scene700: public SceneExt {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor5 : public SceneActor {
+ class Cable : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -716,12 +736,12 @@ public:
NamedHotspot _item9;
NamedHotspot _item10;
Item11 _item11;
- Item12 _item12;
+ HandGrip _handGrip;
SceneActor _actor1;
Actor2 _actor2;
Actor3 _actor3;
Actor4 _actor4;
- Actor5 _actor5;
+ Cable _cable;
Actor6 _actor6;
Actor6 _actor7;
Actor6 _actor8;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.cpp b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
index 6ea53d0852..33eb9b9afb 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.cpp
@@ -39,6 +39,7 @@ Scene1000::Scene1000(): SceneExt() {
R2_GLOBALS._uiElements._active = false;
_gameTextSpeaker._displayMode = 9;
_fieldD2E = 0;
+ _field412 = 0;
}
void Scene1000::postInit(SceneObjectList *OwnerList) {
@@ -672,7 +673,7 @@ void Scene1100::synchronize(Serializer &s) {
s.syncAsSint16LE(_field414);
}
-bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
+bool Scene1100::Seeker::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if (action != CURSOR_TALK)
@@ -680,7 +681,7 @@ bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
if (R2_GLOBALS.getFlag(52)) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_field412 = 327;
else
scene->_field412 = 328;
@@ -690,14 +691,14 @@ bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 55;
if (R2_GLOBALS._v565AE >= 3) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start3(329, scene, R2_GLOBALS._stripManager_lookupList);
else
scene->_stripManager.start3(330, scene, R2_GLOBALS._stripManager_lookupList);
} else {
++R2_GLOBALS._v565AE;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start3(304, scene, R2_GLOBALS._stripManager_lookupList);
else
scene->_stripManager.start3(308, scene, R2_GLOBALS._stripManager_lookupList);
@@ -706,7 +707,7 @@ bool Scene1100::Actor16::startAction(CursorType action, Event &event) {
return true;
}
-bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
+bool Scene1100::Trooper::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -714,7 +715,7 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
if (_visage == 1105) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1114;
- scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1114, &R2_GLOBALS._player, &scene->_trooper, NULL);
return true;
} else {
return SceneActor::startAction(action, event);
@@ -725,21 +726,21 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
case R2_PHOTON_STUNNER:
if (_visage == 1105) {
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
scene->_sceneMode = 1112;
- scene->setAction(&scene->_sequenceManager1, scene, 1112, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1112, &R2_GLOBALS._player, &scene->_trooper, NULL);
} else {
scene->_sceneMode = 1115;
- scene->setAction(&scene->_sequenceManager1, scene, 1115, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1115, &R2_GLOBALS._player, &scene->_trooper, NULL);
}
return true;
} else if (_strip == 2) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1113;
- if (R2_GLOBALS._player._characterIndex == 1) {
- scene->setAction(&scene->_sequenceManager1, scene, 1113, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ scene->setAction(&scene->_sequenceManager1, scene, 1113, &R2_GLOBALS._player, &scene->_trooper, NULL);
} else {
- scene->setAction(&scene->_sequenceManager1, scene, 1118, &R2_GLOBALS._player, &scene->_actor17, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, 1118, &R2_GLOBALS._player, &scene->_trooper, NULL);
}
return true;
} else {
@@ -752,7 +753,7 @@ bool Scene1100::Actor17::startAction(CursorType action, Event &event) {
}
}
-bool Scene1100::Actor18::startAction(CursorType action, Event &event) {
+bool Scene1100::Chief::startAction(CursorType action, Event &event) {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if ((action == CURSOR_TALK) && (!R2_GLOBALS.getFlag(54)) && (R2_GLOBALS.getFlag(52))) {
@@ -814,7 +815,7 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.stop();
if (R2_GLOBALS._sceneManager._previousScene == 300) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._player._characterIndex = R2_QUINN;
R2_GLOBALS._player._characterScene[1] = 1100;
R2_GLOBALS._player._characterScene[2] = 1100;
@@ -824,28 +825,28 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.hide();
R2_GLOBALS._player.disableControl();
- _actor16.postInit();
- _actor16.hide();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor16.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ _seeker.postInit();
+ _seeker.hide();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _seeker.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
else
- _actor16.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _seeker.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
- _actor18.postInit();
- _actor18.setup(1113, 3, 1);
- _actor18.setPosition(Common::Point(181, 125));
- _actor18.fixPriority(110);
+ _chief.postInit();
+ _chief.setup(1113, 3, 1);
+ _chief.setPosition(Common::Point(181, 125));
+ _chief.fixPriority(110);
if (R2_GLOBALS.getFlag(54))
- _actor18.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
else
- _actor18.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
- _actor17.postInit();
- _actor17.setup(1105, 3, 1);
- _actor17.setPosition(Common::Point(312, 165));
- _actor17._numFrames = 5;
- _actor17.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+ _trooper.postInit();
+ _trooper.setup(1105, 3, 1);
+ _trooper.setPosition(Common::Point(312, 165));
+ _trooper._numFrames = 5;
+ _trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
_actor1.postInit();
_actor1.setup(1512, 1, 1);
@@ -907,66 +908,66 @@ void Scene1100::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player.animate(ANIM_MODE_1, NULL);
- _actor16.postInit();
+ _seeker.postInit();
if (R2_GLOBALS.getFlag(52)) {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(19, 7, 1);
- _actor16.setup(29, 6, 1);
+ _seeker.setup(29, 6, 1);
} else {
R2_GLOBALS._player.setup(29, 7, 1);
- _actor16.setup(19, 6, 1);
+ _seeker.setup(19, 6, 1);
}
R2_GLOBALS._player.setPosition(Common::Point(140, 124));
- _actor16.setPosition(Common::Point(237, 134));
+ _seeker.setPosition(Common::Point(237, 134));
R2_GLOBALS._player.enableControl();
} else {
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(1107, 2, 1);
- _actor16.setup(1107, 4, 1);
+ _seeker.setup(1107, 4, 1);
R2_GLOBALS._player.setPosition(Common::Point(247, 169));
- _actor16.setPosition(Common::Point(213, 169));
+ _seeker.setPosition(Common::Point(213, 169));
} else {
R2_GLOBALS._player.setup(1107, 4, 1);
- _actor16.setup(1107, 2, 1);
+ _seeker.setup(1107, 2, 1);
R2_GLOBALS._player.setPosition(Common::Point(213, 169));
- _actor16.setPosition(Common::Point(247, 169));
+ _seeker.setPosition(Common::Point(247, 169));
}
R2_GLOBALS._player.enableControl();
R2_GLOBALS._player._canWalk = false;
}
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor16.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _seeker.setDetails(9002, 0, 4, 3, 1, (SceneItem *) NULL);
else
- _actor16.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
+ _seeker.setDetails(9001, 0, 5, 3, 1, (SceneItem *) NULL);
- _actor18.postInit();
- _actor18.setup(1113, 3, 1);
- _actor18.setPosition(Common::Point(181, 125));
- _actor18.fixPriority(110);
+ _chief.postInit();
+ _chief.setup(1113, 3, 1);
+ _chief.setPosition(Common::Point(181, 125));
+ _chief.fixPriority(110);
if (R2_GLOBALS.getFlag(54))
- _actor18.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 4, -1, -1, 1, (SceneItem *) NULL);
else
- _actor18.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
+ _chief.setDetails(1100, 3, -1, -1, 1, (SceneItem *) NULL);
if (!R2_GLOBALS.getFlag(52)) {
- _actor17.postInit();
+ _trooper.postInit();
if (R2_GLOBALS.getFlag(53))
- _actor17.setup(1106, 2, 4);
+ _trooper.setup(1106, 2, 4);
else
- _actor17.setup(1105, 4, 4);
+ _trooper.setup(1105, 4, 4);
- _actor17.setPosition(Common::Point(17, 54));
- _actor17._numFrames = 5;
+ _trooper.setPosition(Common::Point(17, 54));
+ _trooper._numFrames = 5;
if (R2_GLOBALS.getFlag(53))
- _actor17.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL);
+ _trooper.setDetails(1100, 28, -1, -1, 1, (SceneItem *) NULL);
else
- _actor17.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
+ _trooper.setDetails(1100, 22, 23, 24, 1, (SceneItem *) NULL);
- _actor17.fixPriority(200);
+ _trooper.fixPriority(200);
}
_actor1.postInit();
_actor1.setup(1512, 1, 1);
@@ -1026,9 +1027,9 @@ void Scene1100::signal() {
}
break;
case 4:
- _actor18.postInit();
- _actor18.show();
- setAction(&_sequenceManager1, this, 1101, &_actor18, &_actor10, NULL);
+ _chief.postInit();
+ _chief.show();
+ setAction(&_sequenceManager1, this, 1101, &_chief, &_actor10, NULL);
break;
case 5:
_actor13.postInit();
@@ -1054,12 +1055,12 @@ void Scene1100::signal() {
}
break;
case 7:
- setAction(&_sequenceManager1, this, 1103, &_actor18, &_actor10);
+ setAction(&_sequenceManager1, this, 1103, &_chief, &_actor10);
break;
case 8:
R2_GLOBALS._player._effect = 0;
_actor11.postInit();
- setAction(&_sequenceManager1, this, 1105, &R2_GLOBALS._player, &_actor10, &_actor11, &_actor18, NULL);
+ setAction(&_sequenceManager1, this, 1105, &R2_GLOBALS._player, &_actor10, &_actor11, &_chief, NULL);
break;
case 9:
_object1.copySceneToBackground();
@@ -1090,8 +1091,8 @@ void Scene1100::signal() {
// Really nothing
break;
case 13:
- _actor17.postInit();
- R2_GLOBALS._scrollFollower = &_actor17;
+ _trooper.postInit();
+ R2_GLOBALS._scrollFollower = &_trooper;
_actor11.setup(1100, 2, 1);
_actor11.setPosition(Common::Point(408, 121));
@@ -1099,7 +1100,7 @@ void Scene1100::signal() {
_actor10.setup(1100, 3, 5);
_actor10.setPosition(Common::Point(409, 121));
- setAction(&_sequenceManager1, this, 1104, &_actor17, NULL);
+ setAction(&_sequenceManager1, this, 1104, &_trooper, NULL);
break;
case 14:
setAction(&_sequenceManager1, this, 1100, &_actor11, &_actor10, NULL);
@@ -1115,14 +1116,14 @@ void Scene1100::signal() {
break;
case 21: {
R2_GLOBALS._sound2.play(92);
- _actor17.animate(ANIM_MODE_5, NULL);
+ _trooper.animate(ANIM_MODE_5, NULL);
Common::Point pt(187, 45);
NpcMover *mover = new NpcMover();
_actor1.addMover(mover, &pt, this);
}
break;
case 22:
- setAction(&_sequenceManager1, this, 1110, &_actor16, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 1110, &_seeker, &R2_GLOBALS._player, NULL);
break;
case 23:
R2_GLOBALS._player.disableControl();
@@ -1136,46 +1137,49 @@ void Scene1100::signal() {
break;
case 25:
R2_GLOBALS._player.disableControl();
- _stripManager._lookupList[9] = 1;
- _stripManager._lookupList[10] = 1;
- _stripManager._lookupList[11] = 1;
+ R2_GLOBALS._stripManager_lookupList[9] = 1;
+ R2_GLOBALS._stripManager_lookupList[10] = 1;
+ R2_GLOBALS._stripManager_lookupList[11] = 1;
R2_GLOBALS._sound1.play(95);
- setAction(&_sequenceManager1, this, 1111, &_actor17, &R2_GLOBALS._player, &_actor16, NULL);
+ setAction(&_sequenceManager1, this, 1111, &_trooper, &R2_GLOBALS._player, &_seeker, NULL);
break;
case 26:
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(302, this);
break;
case 27:
R2_GLOBALS._player.disableControl();
- setAction(&_sequenceManager1, this, 1120, &_actor16, &R2_GLOBALS._player, NULL);
+ setAction(&_sequenceManager1, this, 1120, &_seeker, &R2_GLOBALS._player, NULL);
break;
case 28:
R2_GLOBALS._player.disableControl();
- R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
+ R2_GLOBALS._events.setCursor(CURSOR_ARROW);
_stripManager.start(303, this);
break;
+ case 29:
+ case 50:
+ R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
+ break;
case 51:
R2_GLOBALS.setFlag(53);
- _actor17.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL);
- // No break on purpose
- case 50:
- // No break on purpose
- case 29:
+ _trooper.setDetails(1100, 28, -1, -1, 3, (SceneItem *) NULL);
+
R2_GLOBALS._player.enableControl(CURSOR_USE);
+ R2_GLOBALS._player._canWalk = false;
break;
case 52:
R2_GLOBALS._sound1.play(98);
R2_GLOBALS.setFlag(52);
R2_GLOBALS._player.disableControl();
_sceneMode = 1116;
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
setAction(&_sequenceManager1, this, 1116, &R2_GLOBALS._player, NULL);
- _actor16.setAction(&_sequenceManager2, NULL, 1123, &_actor16, NULL);
+ _seeker.setAction(&_sequenceManager2, NULL, 1123, &_seeker, NULL);
} else {
setAction(&_sequenceManager1, this, 1124, &R2_GLOBALS._player, NULL);
- _actor16.setAction(&_sequenceManager2, NULL, 1117, &_actor16, NULL);
+ _seeker.setAction(&_sequenceManager2, NULL, 1117, &_seeker, NULL);
}
break;
case 53:
@@ -1184,13 +1188,13 @@ void Scene1100::signal() {
if (_field412 == 0) {
R2_GLOBALS.setFlag(55);
if (R2_GLOBALS.getFlag(55)) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(318, this);
else
_stripManager.start(323, this);
} else {
// This part is totally useless as flag 55 has been set right before the check
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(317, this);
else
_stripManager.start(322, this);
@@ -1200,10 +1204,10 @@ void Scene1100::signal() {
}
break;
case 54:
- if (_stripManager._field2E8 == 1) {
+ if (_stripManager._exitMode == 1) {
R2_GLOBALS._player.disableControl();
_sceneMode = 1125;
- setAction(&_sequenceManager1, this, 1125, &R2_GLOBALS._player, &_actor16, NULL);
+ setAction(&_sequenceManager1, this, 1125, &R2_GLOBALS._player, &_seeker, NULL);
} else
R2_GLOBALS._player.enableControl(CURSOR_TALK);
break;
@@ -1244,9 +1248,9 @@ void Scene1100::signal() {
break;
case 1116:
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
- _stripManager._lookupList[9] = 1;
- _stripManager._lookupList[10] = 1;
- _stripManager._lookupList[11] = 1;
+ R2_GLOBALS._stripManager_lookupList[9] = 1;
+ R2_GLOBALS._stripManager_lookupList[10] = 1;
+ R2_GLOBALS._stripManager_lookupList[11] = 1;
break;
case 1125: {
_sceneMode = 99;
@@ -1295,7 +1299,7 @@ void Scene1100::dispatch() {
}
void Scene1100::saveCharacter(int characterIndex) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._sound1.fadeOut2(NULL);
SceneExt::saveCharacter(characterIndex);
}
@@ -5973,7 +5977,8 @@ void Scene1337::subCF31D() {
if ((_arrunkObj1337[1]._arr2[i]._field34 == 0) && (!subC2687(_arrunkObj1337[1]._arr3[0]._field34))) {
subC340B(&_arrunkObj1337[1]._arr1[tmpVal], &_arrunkObj1337[1]._arr2[i]);
found = true;
- }
+ break;
+ }
}
}
@@ -5983,8 +5988,10 @@ void Scene1337::subCF31D() {
tmpVal = subC274D(1);
int tmpVal2 = subC331B(1);
- if ((tmpVal != -1) && ( tmpVal2 != -1))
+ if ((tmpVal != -1) && ( tmpVal2 != -1)) {
subC358E(&_arrunkObj1337[1]._arr1[tmpVal], tmpVal2);
+ found = true;
+ }
if (found)
return;
@@ -7008,7 +7015,7 @@ void Scene1500::signal() {
}
break;
case 24:
- R2_GLOBALS._sceneManager.changeScene(300);
+ R2_GLOBALS._sceneManager.changeScene(1550);
break;
default:
break;
@@ -7169,21 +7176,22 @@ void Scene1530::dispatch() {
}
/*--------------------------------------------------------------------------
- * Scene 1550 -
+ * Scene 1550 - Spaceport
*
*--------------------------------------------------------------------------*/
-Scene1550::UnkObj15501::UnkObj15501() {
- _fieldA4 = _fieldA6 = 0;
+
+Scene1550::Junk::Junk() {
+ _fieldA4 = _junkNumber = 0;
}
-void Scene1550::UnkObj15501::synchronize(Serializer &s) {
+void Scene1550::Junk::synchronize(Serializer &s) {
SceneActor::synchronize(s);
s.syncAsSint16LE(_fieldA4);
- s.syncAsSint16LE(_fieldA6);
+ s.syncAsSint16LE(_junkNumber);
}
-bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
+bool Scene1550::Junk::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
@@ -7236,36 +7244,36 @@ bool Scene1550::UnkObj15501::startAction(CursorType action, Event &event) {
}
}
-Scene1550::UnkObj15502::UnkObj15502() {
- _fieldA4 = 0;
+Scene1550::ShipComponent::ShipComponent() {
+ _componentId = 0;
}
-void Scene1550::UnkObj15502::synchronize(Serializer &s) {
+void Scene1550::ShipComponent::synchronize(Serializer &s) {
SceneActor::synchronize(s);
- s.syncAsSint16LE(_fieldA4);
+ s.syncAsSint16LE(_componentId);
}
-bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
+bool Scene1550::ShipComponent::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
switch (action) {
case CURSOR_USE:
- if (_fieldA4 == 8) {
+ if (_componentId == 8) {
scene->_field412 = 1;
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1576;
else
scene->_sceneMode = 1584;
- // strcpy(scene->_arrUnkObj15502[7]._actorName, 'hatch');
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[7], NULL);
+ // strcpy(scene->_shipComponents[7]._actorName, 'hatch');
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[7], NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case CURSOR_LOOK:
- if (_fieldA4 == 8)
+ if (_componentId == 8)
SceneItem::display(1550, 75, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
else if (_frame == 1)
SceneItem::display(1550, 70, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
@@ -7275,92 +7283,92 @@ bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
break;
case R2_FUEL_CELL:
scene->_field412 = 1;
- if (_fieldA4 == 6) {
+ if (_componentId == 6) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1574;
else
scene->_sceneMode = 1582;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[5], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[5], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GYROSCOPE:
scene->_field412 = 1;
- if (_fieldA4 == 3) {
+ if (_componentId == 3) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1571;
else
scene->_sceneMode = 1581;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[2], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[2], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_GUIDANCE_MODULE:
scene->_field412 = 1;
- if (_fieldA4 == 1) {
+ if (_componentId == 1) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1569;
else
scene->_sceneMode = 1579;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[0], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[0], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_THRUSTER_VALVE:
scene->_field412 = 1;
- if (_fieldA4 == 4) {
+ if (_componentId == 4) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1572;
- scene->_actor1.postInit();
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[3], &scene->_actor1, NULL);
+ scene->_landingStrut.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[3], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_RADAR_MECHANISM:
scene->_field412 = 1;
- if (_fieldA4 == 2) {
+ if (_componentId == 2) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1570;
else
scene->_sceneMode = 1580;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[1], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[1], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_IGNITOR:
scene->_field412 = 1;
- if (_fieldA4 == 5) {
+ if (_componentId == 5) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1573;
- scene->_actor1.postInit();
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[4], &scene->_actor1, NULL);
+ scene->_landingStrut.postInit();
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[4], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
break;
case R2_BATTERY:
scene->_field412 = 1;
- if (_fieldA4 == 7) {
+ if (_componentId == 7) {
R2_GLOBALS._player.disableControl();
- scene->_actor1.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
+ scene->_landingStrut.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1575;
else
scene->_sceneMode = 1583;
- scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_arrUnkObj15502[6], &scene->_actor1, NULL);
+ scene->setAction(&scene->_sequenceManager1, scene, scene->_sceneMode, &R2_GLOBALS._player, &scene->_shipComponents[6], &scene->_landingStrut, NULL);
return true;
}
return SceneActor::startAction(action, event);
@@ -7371,11 +7379,12 @@ bool Scene1550::UnkObj15502::startAction(CursorType action, Event &event) {
}
}
-void Scene1550::UnkObj15502::subA5CDF(int strip) {
- _fieldA4 = strip;
+void Scene1550::ShipComponent::setupShipComponent(int componentId) {
+ _componentId = componentId;
postInit();
- setup(1517, _fieldA4, 1);
- switch (_fieldA4 - 1) {
+ setup(1517, _componentId, 1);
+
+ switch (_componentId - 1) {
case 0:
if (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) == 0)
setFrame(5);
@@ -7510,19 +7519,16 @@ void Scene1550::UnkArea1550::process(Event &event) {
if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
if (cursor == _cursorNum) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
if (cursor != _cursorNum) {
_savedCursorNum = cursor;
- warning("TODO: _cursorState = ???");
R2_GLOBALS._events.setCursor(CURSOR_INVALID);
}
if (event.eventType == EVENT_BUTTON_DOWN) {
event.handled = true;
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
remove();
}
}
@@ -7570,26 +7576,30 @@ void Scene1550::UnkArea1550::proc13(int resNum, int lookLineNum, int talkLineNum
_areaActor.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
}
-bool Scene1550::Hotspot1::startAction(CursorType action, Event &event) {
+bool Scene1550::WorkingShip::startAction(CursorType action, Event &event) {
return SceneHotspot::startAction(action, event);
}
bool Scene1550::Hotspot3::startAction(CursorType action, Event &event) {
// Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
- assert ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS._player._characterIndex == 2));
+ assert ((R2_GLOBALS._player._characterIndex == R2_QUINN) || (R2_GLOBALS._player._characterIndex == R2_SEEKER));
// The original contains a debug message when CURSOR_TALK is used.
// This part is totally useless, we could remove it (and the entire function as well)
if (action == CURSOR_TALK)
- warning("Location: %d/%d - %d", R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex], R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2], k5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]);
+ warning("Location: %d/%d - %d",
+ R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x,
+ R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y,
+ scene1550AreaMap[(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y * 30)] +
+ R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x);
return SceneHotspot::startAction(action, event);
}
-bool Scene1550::Actor6::startAction(CursorType action, Event &event) {
+bool Scene1550::Wreckage::startAction(CursorType action, Event &event) {
return SceneActor::startAction(action, event);
}
-bool Scene1550::Actor7::startAction(CursorType action, Event &event) {
+bool Scene1550::Companion::startAction(CursorType action, Event &event) {
if (action != CURSOR_TALK)
return SceneActor::startAction(action, event);
@@ -7607,7 +7617,7 @@ bool Scene1550::Actor8::startAction(CursorType action, Event &event) {
R2_GLOBALS._player.disableControl();
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
scene->_field412 = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1552;
else
scene->_sceneMode = 1588;
@@ -7624,7 +7634,7 @@ bool Scene1550::Actor9::startAction(CursorType action, Event &event) {
scene->_sceneMode = 50;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start(518, scene);
else
scene->_stripManager.start(520, scene);
@@ -7645,7 +7655,7 @@ bool Scene1550::Actor10::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1555;
else
scene->_sceneMode = 1589;
@@ -7661,7 +7671,7 @@ bool Scene1550::Actor11::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
scene->_field412 = 1;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_sceneMode = 1586;
else
scene->_sceneMode = 1587;
@@ -7676,7 +7686,7 @@ bool Scene1550::Actor12::startAction(CursorType action, Event &event) {
Scene1550 *scene = (Scene1550 *)R2_GLOBALS._sceneManager._scene;
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 1585;
scene->setAction(&scene->_sequenceManager1, scene, 1585, &R2_GLOBALS._player, NULL);
@@ -7756,19 +7766,22 @@ void Scene1550::synchronize(Serializer &s) {
}
void Scene1550::postInit(SceneObjectList *OwnerList) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11))
+ // Exiting the intact spaceship
loadScene(1234);
else
+ // Normal scene entry
loadScene(1550);
+ SceneExt::postInit();
scalePalette(65, 65, 65);
setZoomPercents(30, 75, 170, 100);
_field417 = 1550;
_field419 = 0;
- SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1)
- R2_GLOBALS.setFlag(R2_ATTRACTOR_CABLE_HARNESS);
+ R2_GLOBALS.setFlag(16);
if ((R2_GLOBALS._player._characterScene[1] != 1550) && (R2_GLOBALS._player._characterScene[1] != 1580)) {
R2_GLOBALS._player._characterScene[1] = 1550;
@@ -7783,14 +7796,15 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.postInit();
R2_GLOBALS._player._effect = 6;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
R2_GLOBALS._player.setup(1500, 3, 1);
else
R2_GLOBALS._player.setup(1505, 3, 1);
R2_GLOBALS._player._moveDiff = Common::Point(5, 3);
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11))
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11))
R2_GLOBALS._player.setPosition(Common::Point(157, 135));
else
R2_GLOBALS._player.setPosition(Common::Point(160, 100));
@@ -7799,7 +7813,7 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
_field414 = 0;
- _actor7.changeZoom(-1);
+ _companion.changeZoom(-1);
R2_GLOBALS._player.changeZoom(-1);
switch (R2_GLOBALS._sceneManager._previousScene) {
@@ -7814,21 +7828,22 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._sound1.play(105);
break;
case 1580:
+ // Leaving intact ship
if (R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] == 1580) {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
_field412 = 1;
- _actor1.postInit();
- _arrUnkObj15502[7].subA5CDF(8);
- _arrUnkObj15502[7].hide();
- if (R2_GLOBALS._player._characterIndex == 1)
+ _landingStrut.postInit();
+ _shipComponents[7].setupShipComponent(8);
+ _shipComponents[7].hide();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_sceneMode = 1577;
else
_sceneMode = 1578;
- setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_actor1, &_arrUnkObj15502[7], NULL);
+ setAction(&_sequenceManager1, this, _sceneMode, &R2_GLOBALS._player, &_landingStrut, &_shipComponents[7], NULL);
R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1550;
} else {
R2_GLOBALS._player.enableControl();
@@ -7838,29 +7853,29 @@ void Scene1550::postInit(SceneObjectList *OwnerList) {
break;
}
- subA2B2F();
+ enterArea();
- _item1.setDetails(16, 1550, 10, -1, -1);
+ _shipHull.setDetails(16, 1550, 10, -1, -1);
_item2.setDetails(24, 1550, 10, -1, -1);
_item3.setDetails(Rect(0, 0, 320, 200), 1550, 0, 1, -1, 1, NULL);
if ((R2_GLOBALS._sceneManager._previousScene == 1500) && (R2_GLOBALS.getFlag(16))) {
_sceneMode = 70;
- if (!R2_GLOBALS._sceneObjects->contains(&_actor7))
- _actor7.postInit();
+ if (!R2_GLOBALS._sceneObjects->contains(&_companion))
+ _companion.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor7.setVisage(1505);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _companion.setVisage(1505);
else
- _actor7.setVisage(1500);
+ _companion.setVisage(1500);
- _actor7.changeZoom(77);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.changeZoom(77);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
assert(_field419 >= 1550);
R2_GLOBALS._walkRegions.enableRegion(k5A750[_field419 - 1550]);
- setAction(&_sequenceManager1, this, 1590, &_actor7, NULL);
+ setAction(&_sequenceManager1, this, 1590, &_companion, NULL);
} else if ((_sceneMode != 1577) && (_sceneMode != 1578))
R2_GLOBALS._player.enableControl();
}
@@ -7876,7 +7891,7 @@ void Scene1550::signal() {
case 7:
_field412 = 0;
R2_GLOBALS._v56AAB = 0;
- R2_GLOBALS._player.enableControl(CURSOR_ARROW);
+ R2_GLOBALS._player.enableControl(CURSOR_WALK);
break;
case 20:
// No break on purpose
@@ -7917,14 +7932,14 @@ void Scene1550::signal() {
break;
case 40: {
_sceneMode = 41;
- Common::Point pt(_arrUnkObj15501[0]._position.x, _arrUnkObj15501[0]._position.y + 20);
+ Common::Point pt(_junk[0]._position.x, _junk[0]._position.y + 20);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
}
break;
case 41:
_sceneMode = 42;
- if (R2_GLOBALS._player._characterIndex == 1) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
R2_GLOBALS._player.setup(1502, 8, 1);
} else {
R2_GLOBALS._player.changeZoom(R2_GLOBALS._player._percent + 14);
@@ -7932,37 +7947,42 @@ void Scene1550::signal() {
}
R2_GLOBALS._player.animate(ANIM_MODE_5, this);
break;
- case 42:
+
+ case 42: {
_sceneMode = 43;
- warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
- switch (_arrUnkObj15501[0]._frame - 1) {
- case 0:
- R2_INVENTORY.setObjectScene(26, R2_GLOBALS._player._characterIndex);
- break;
+ int junkRegionIndex = R2_GLOBALS._scene1550JunkLocations[_junk[0]._junkNumber + 3];
+ R2_GLOBALS._walkRegions.disableRegion(scene1550JunkRegions[junkRegionIndex]);
+
+ switch (_junk[0]._frame) {
case 1:
- R2_INVENTORY.setObjectScene(17, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_JOYSTICK, R2_GLOBALS._player._characterIndex);
break;
case 2:
- R2_INVENTORY.setObjectScene(22, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_FUEL_CELL, R2_GLOBALS._player._characterIndex);
break;
case 3:
- R2_INVENTORY.setObjectScene(25, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, R2_GLOBALS._player._characterIndex);
break;
case 4:
- R2_INVENTORY.setObjectScene(45, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, R2_GLOBALS._player._characterIndex);
break;
case 5:
- R2_INVENTORY.setObjectScene(28, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_BATTERY, R2_GLOBALS._player._characterIndex);
+ break;
+ case 6:
+ R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
break;
default:
break;
}
- _arrUnkObj15501[0].remove();
+
+ _junk[0].remove();
R2_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
+ }
case 43:
- warning("TODO: unknown use of arrUnkObj15501[0]._fieldA6");
- if (R2_GLOBALS._player._characterIndex == 1)
+ R2_GLOBALS._scene1550JunkLocations[_junk[0]._junkNumber + 2] = 0;
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
R2_GLOBALS._player.setVisage(1500);
else {
R2_GLOBALS._player.changeZoom(-1);
@@ -7976,29 +7996,29 @@ void Scene1550::signal() {
warning("STUB: sub_1D227()");
++_sceneMode;
setAction(&_sequenceManager1, this, 1591, &R2_GLOBALS._player, NULL);
- if (g_globals->_sceneObjects->contains(&_actor7))
+ if (g_globals->_sceneObjects->contains(&_companion))
signal();
else {
- _actor7.postInit();
- if (R2_GLOBALS._player._characterIndex == 1)
- _actor7.setVisage(1505);
+ _companion.postInit();
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ _companion.setVisage(1505);
else
- _actor7.setVisage(1500);
- _actor7.changeZoom(77);
- _actor7.setAction(&_sequenceManager2, this, 1590, &_actor7, NULL);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setVisage(1500);
+ _companion.changeZoom(77);
+ _companion.setAction(&_sequenceManager2, this, 1590, &_companion, NULL);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
break;
case 51:
++_sceneMode;
break;
case 52:
- _actor7.changeZoom(-1);
+ _companion.changeZoom(-1);
_sceneMode = 1592;
- if (R2_GLOBALS._player._characterIndex == 1)
- setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
+ setAction(&_sequenceManager1, this, 1592, &R2_GLOBALS._player, &_companion, &_junk[0], &_actor9, NULL);
else
- setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_actor7, &_arrUnkObj15501[0], &_actor9, NULL);
+ setAction(&_sequenceManager1, this, 1593, &R2_GLOBALS._player, &_companion, &_junk[0], &_actor9, NULL);
break;
case 61:
R2_GLOBALS._player.enableControl(CURSOR_USE);
@@ -8013,9 +8033,8 @@ void Scene1550::signal() {
}
break;
case 70:
- R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
- R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
- R2_GLOBALS._v565EC[0] = 1;
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER] = R2_GLOBALS._s1550PlayerArea[R2_QUINN];
+ //R2_GLOBALS._s1550PlayerAreas[0] = 1;
_sceneMode = 60;
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
_stripManager.start(500, this);
@@ -8026,13 +8045,13 @@ void Scene1550::signal() {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._v565AE >= 3) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
++R2_GLOBALS._v565AE;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(499 + R2_GLOBALS._v565AE, this);
else
_stripManager.start(502 + R2_GLOBALS._v565AE, this);
@@ -8042,13 +8061,13 @@ void Scene1550::signal() {
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
if (R2_GLOBALS._v565AE >= 4) {
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(572, this);
else
_stripManager.start(573, this);
} else {
++R2_GLOBALS._v565AE;
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
_stripManager.start(563 + R2_GLOBALS._v565AE, this);
else
_stripManager.start(567 + R2_GLOBALS._v565AE, this);
@@ -8112,7 +8131,7 @@ void Scene1550::signal() {
// No break on purpose
case 1579:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8120,7 +8139,7 @@ void Scene1550::signal() {
// No break on purpose
case 1580:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_RADAR_MECHANISM, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8128,19 +8147,19 @@ void Scene1550::signal() {
// No break on purpose
case 1581:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_GYROSCOPE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1572:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 0);
R2_GLOBALS._player.enableControl();
break;
case 1573:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_IGNITOR, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8148,7 +8167,7 @@ void Scene1550::signal() {
// No break on purpose
case 1582:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_FUEL_CELL, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8156,7 +8175,7 @@ void Scene1550::signal() {
// No break on purpose
case 1583:
_field412 = 0;
- _actor1.remove();
+ _landingStrut.remove();
R2_INVENTORY.setObjectScene(R2_BATTERY, 0);
R2_GLOBALS._player.enableControl();
break;
@@ -8170,7 +8189,7 @@ void Scene1550::signal() {
// No break on purpose
case 1578:
_sceneMode = 0;
- _actor1.remove();
+ _landingStrut.remove();
_field412 = 0;
R2_GLOBALS._player.fixPriority(-1);
R2_GLOBALS._player.enableControl();
@@ -8183,19 +8202,17 @@ void Scene1550::signal() {
// No break on purpose
case 1587:
R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, R2_GLOBALS._player._characterIndex);
- _actor1.remove();
+ _landingStrut.remove();
_field412 = 0;
R2_GLOBALS._player.enableControl();
break;
case 1592:
_actor9.remove();
R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1);
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_GLOBALS._v565EC[2] = R2_GLOBALS._v565EC[1];
- R2_GLOBALS._v565EC[4] = R2_GLOBALS._v565EC[3];
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER] = R2_GLOBALS._s1550PlayerArea[R2_QUINN];
} else {
- R2_GLOBALS._v565EC[1] = R2_GLOBALS._v565EC[2];
- R2_GLOBALS._v565EC[3] = R2_GLOBALS._v565EC[4];
+ R2_GLOBALS._s1550PlayerArea[R2_QUINN] = R2_GLOBALS._s1550PlayerArea[R2_SEEKER];
}
R2_GLOBALS._player.enableControl();
break;
@@ -8227,11 +8244,11 @@ void Scene1550::dispatch() {
Scene::dispatch();
// Arrays related to this scene are all hacky in the origina: they are based on the impossibility to use Miranda
- assert ((R2_GLOBALS._player._characterIndex == 1) || (R2_GLOBALS._player._characterIndex == 2));
+ assert ((R2_GLOBALS._player._characterIndex == R2_QUINN) || (R2_GLOBALS._player._characterIndex == R2_SEEKER));
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 15) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 16)) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 15) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 16)) {
R2_GLOBALS._player._shade = 0;
- // Original game contains a switch based on an uninitialised variable.
+ // Original game contains a switch based on an uninitialized variable.
// Until we understand what should really happen there, this code is unused on purpose
int missingVariable = 0;
switch (missingVariable) {
@@ -8263,12 +8280,13 @@ void Scene1550::dispatch() {
case 0:
// No break on purpose
case 5:
+ // Exiting the top of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 1;
_field412 = 1;
- --R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+ --R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y;
- subA2B2F();
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 108) * 172) / 100), 145));
if (R2_GLOBALS._player._position.x < 160) {
@@ -8286,12 +8304,13 @@ void Scene1550::dispatch() {
}
break;
case 1:
+ // Exiting the bottom of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 3;
_field412 = 1;
- ++R2_GLOBALS._v565EC[2 + R2_GLOBALS._player._characterIndex];
+ ++R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y;
- subA2B2F();
+ enterArea();
R2_GLOBALS._player.setPosition(Common::Point( 160 - (((((160 - R2_GLOBALS._player._position.x) * 100) / 172) * 108) / 100), 19));
if (R2_GLOBALS._player._position.x < 160) {
@@ -8309,14 +8328,15 @@ void Scene1550::dispatch() {
}
break;
case 2:
+ // Exiting the right of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 5;
_field412 = 1;
- ++R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
+ ++R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x;
- subA2B2F();
+ enterArea();
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
if (R2_GLOBALS._player._position.y >= 85) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
Common::Point pt(R2_GLOBALS._player._position.x + 30, R2_GLOBALS._player._position.y + 20);
@@ -8336,16 +8356,20 @@ void Scene1550::dispatch() {
}
break;
case 3:
+ // Exiting to the left of the screen
R2_GLOBALS._player.disableControl();
_sceneMode = 7;
_field412 = 1;
- --R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex];
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 24) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
+ --R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x;
+
+ enterArea();
+
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 24) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11)) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y / 2));
Common::Point pt(265, 29);
NpcMover *mover = new NpcMover();
R2_GLOBALS._player.addMover(mover, &pt, this);
- } else if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
+ } else if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11) && (R2_GLOBALS._player._position.y > 50) && (R2_GLOBALS._player._position.y < 135)) {
if (R2_GLOBALS._player._position.y >= 85) {
R2_GLOBALS._player.setPosition(Common::Point(320 - R2_GLOBALS._player._position.x, R2_GLOBALS._player._position.y + 10));
Common::Point pt(R2_GLOBALS._player._position.x - 30, R2_GLOBALS._player._position.y + 20);
@@ -8370,7 +8394,7 @@ void Scene1550::dispatch() {
}
void Scene1550::saveCharacter(int characterIndex) {
- if (R2_GLOBALS._player._characterIndex == 3)
+ if (R2_GLOBALS._player._characterIndex == R2_MIRANDA)
R2_GLOBALS._sound1.fadeOut2(NULL);
SceneExt::saveCharacter(characterIndex);
@@ -8560,7 +8584,7 @@ void Scene1550::SceneActor1550::subA4D14(int frameNumber, int strip) {
}
-void Scene1550::subA2B2F() {
+void Scene1550::enterArea() {
Rect tmpRect;
_field419 = 0;
_field415 = 0;
@@ -8568,19 +8592,19 @@ void Scene1550::subA2B2F() {
tmpRect = R2_GLOBALS._v5589E;
_actor14.remove();
- _actor17.remove();
- _actor15.remove();
- _actor19.remove();
+ _westWall.remove();
+ _northWall.remove();
+ _southWall.remove();
_actor16.remove();
- _actor18.remove();
+ _eastWall.remove();
for (int i = 0; i < 8; ++i)
- _arrUnkObj15501[i].remove();
+ _junk[i].remove();
- _actor6.remove();
+ _wreckage.remove();
for (int i = 0; i < 8; ++i)
- _arrUnkObj15502[i].remove();
+ _shipComponents[i].remove();
_actor8.remove();
_actor9.remove();
@@ -8589,18 +8613,19 @@ void Scene1550::subA2B2F() {
_actor11.remove();
if ((_sceneMode != 1577) && (_sceneMode != 1578))
- _actor1.remove();
+ _landingStrut.remove();
_actor2.remove();
- _actor7.remove();
+ _companion.remove();
_actor13.remove();
_actor5.remove();
_actor12.remove();
_actor4.remove();
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2]) {
+ // Set up of special walk regions for certain areas
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y) {
case 0:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 3:
R2_GLOBALS._walkRegions.load(1554);
_field419 = 1554;
@@ -8616,7 +8641,7 @@ void Scene1550::subA2B2F() {
case 3:
// No break on purpose
case 4:
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 23) || (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex])) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 23) || (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x)) {
if (!R2_GLOBALS.getFlag(16)) {
R2_GLOBALS._walkRegions.load(1559);
_field419 = 1559;
@@ -8624,7 +8649,7 @@ void Scene1550::subA2B2F() {
}
break;
case 7:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 10:
R2_GLOBALS._walkRegions.load(1555);
_field419 = 1555;
@@ -8638,7 +8663,7 @@ void Scene1550::subA2B2F() {
}
break;
case 11:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 24:
R2_GLOBALS._walkRegions.load(1558);
_field419 = 1558;
@@ -8652,7 +8677,7 @@ void Scene1550::subA2B2F() {
}
break;
case 16:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x) {
case 2:
R2_GLOBALS._walkRegions.load(1552);
_field419 = 1552;
@@ -8675,12 +8700,12 @@ void Scene1550::subA2B2F() {
int varA = 0;
if (!R2_GLOBALS.getFlag(16)) {
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] - 2) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y - 2) {
case 0:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 22) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 22) {
case 0:
varA = 1553;
- _actor15.subA4D14(6, 0);
+ _northWall.subA4D14(6, 0);
break;
case 1:
// No break on purpose
@@ -8693,7 +8718,7 @@ void Scene1550::subA2B2F() {
break;
case 5:
varA = 1553;
- _actor15.subA4D14(6, 0);
+ _northWall.subA4D14(6, 0);
break;
default:
break;
@@ -8702,14 +8727,14 @@ void Scene1550::subA2B2F() {
case 1:
// No break on purpose
case 2:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 21) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 21) {
case 0:
varA = 1550;
- _actor15.subA4D14(9, 0);
+ _northWall.subA4D14(9, 0);
break;
case 1:
varA = 1552;
- _actor15.subA4D14(10, 0);
+ _northWall.subA4D14(10, 0);
break;
case 2:
// No break on purpose
@@ -8722,25 +8747,25 @@ void Scene1550::subA2B2F() {
break;
case 6:
varA = 1552;
- _actor15.subA4D14(7, 0);
+ _northWall.subA4D14(7, 0);
break;
case 7:
varA = 1550;
- _actor15.subA4D14(8, 0);
+ _northWall.subA4D14(8, 0);
break;
default:
break;
}
break;
case 3:
- switch (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] - 21) {
+ switch (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x - 21) {
case 0:
varA = 1550;
- _actor15.subA4D14(4, 0);
+ _northWall.subA4D14(4, 0);
break;
case 1:
varA = 1550;
- _actor15.subA4D14(3, 0);
+ _northWall.subA4D14(3, 0);
break;
case 2:
// No break on purpose
@@ -8753,11 +8778,11 @@ void Scene1550::subA2B2F() {
break;
case 6:
varA = 1550;
- _actor15.subA4D14(2, 0);
+ _northWall.subA4D14(2, 0);
break;
case 7:
varA = 1550;
- _actor15.subA4D14(1, 0);
+ _northWall.subA4D14(1, 0);
break;
default:
break;
@@ -8766,21 +8791,22 @@ void Scene1550::subA2B2F() {
default:
break;
}
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] > 0) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] <= 29) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] >= 20) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] > 7)) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y > 0) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x <= 29) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x >= 20) && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y > 7)) {
R2_GLOBALS.setFlag(16);
R2_GLOBALS._sceneManager.changeScene(1500);
}
}
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == 9) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 11)) {
- if (R2_GLOBALS._sceneManager._sceneNumber != 1234) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == 9) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 11)) {
+ if (_screenNumber != 1234) {
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
loadScene(1234);
R2_GLOBALS._sceneManager._hasPalette = false;
_field414 = 0;
}
} else {
- if (R2_GLOBALS._sceneManager._sceneNumber == 1234) {
+ if (_screenNumber == 1234) {
R2_GLOBALS._sceneManager._fadeMode = FADEMODE_IMMEDIATE;
loadScene(1550);
R2_GLOBALS._sceneManager._hasPalette = false;
@@ -8828,71 +8854,75 @@ void Scene1550::subA2B2F() {
}
}
- switch (k5A4D6[(R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] * 30)] + R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex]) {
+ // Scene setup dependent on the type of cell specified in the scene map
+ switch (scene1550AreaMap[(R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y * 30) +
+ R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x]) {
case 0:
+ // Standard cell
if (_field419 == 0) {
R2_GLOBALS._walkRegions.load(1550);
_field419 = 1550;
}
break;
case 1:
+ // North end of the spaceport
if (_field419 == 0) {
R2_GLOBALS._walkRegions.load(1560);
_field419 = 1560;
}
_actor14.subA4D14(2, 1);
- _actor15.subA4D14(1, 3);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
break;
case 2:
R2_GLOBALS._walkRegions.load(1561);
_field419 = 1561;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(2, 2);
- _actor15.subA4D14(1, 3);
+ _westWall.subA4D14(2, 2);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
break;
case 3:
R2_GLOBALS._walkRegions.load(1562);
_field419 = 1562;
_actor14.subA4D14(2, 1);
- _actor15.subA4D14(1, 3);
+ _northWall.subA4D14(1, 3);
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(2, 6);
+ _eastWall.subA4D14(2, 6);
break;
case 4:
R2_GLOBALS._walkRegions.load(1563);
_field419 = 1563;
- _actor15.subA4D14(2, 3);
+ _northWall.subA4D14(2, 3);
break;
case 5:
R2_GLOBALS._walkRegions.load(1564);
_field419 = 1564;
- _actor19.subA4D14(2, 4);
+ _southWall.subA4D14(2, 4);
break;
case 6:
R2_GLOBALS._walkRegions.load(1565);
_field419 = 1565;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor15.subA4D14(3, 3);
+ _westWall.subA4D14(1, 2);
+ _northWall.subA4D14(3, 3);
break;
case 7:
R2_GLOBALS._walkRegions.load(1566);
_field419 = 1566;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor15.subA4D14(2, 4);
+ _westWall.subA4D14(1, 2);
+ _northWall.subA4D14(2, 4);
break;
case 8:
R2_GLOBALS._walkRegions.load(1567);
_field419 = 1567;
- _actor17.subA4D14(5, 2);
+ _westWall.subA4D14(5, 2);
break;
case 9:
R2_GLOBALS._walkRegions.load(1568);
_field419 = 1568;
- _actor17.subA4D14(4, 2);
+ _westWall.subA4D14(4, 2);
break;
case 10:
R2_GLOBALS._walkRegions.load(1569);
@@ -8903,56 +8933,57 @@ void Scene1550::subA2B2F() {
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
+ _westWall.subA4D14(1, 2);
break;
case 12:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(1, 5);
- _actor18.subA4D14(1, 6);
+ _eastWall.subA4D14(1, 6);
break;
case 13:
R2_GLOBALS._walkRegions.load(1572);
_field419 = 1572;
_actor14.subA4D14(1, 1);
- _actor17.subA4D14(1, 2);
- _actor19.subA4D14(1, 4);
+ _westWall.subA4D14(1, 2);
+ _southWall.subA4D14(1, 4);
break;
case 14:
R2_GLOBALS._walkRegions.load(1573);
_field419 = 1573;
- _actor19.subA4D14(1, 4);
+ _southWall.subA4D14(1, 4);
_actor16.subA4D14(1, 5);
- _actor18.subA4D14(1, 6);
+ _eastWall.subA4D14(1, 6);
break;
case 15:
+ // South wall
R2_GLOBALS._walkRegions.load(1574);
_field419 = 1574;
- _actor19.subA4D14(1, 4);
+ _southWall.subA4D14(1, 4);
break;
case 16:
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(2, 2);
+ _westWall.subA4D14(2, 2);
break;
case 17:
R2_GLOBALS._walkRegions.load(1570);
_field419 = 1570;
_actor14.subA4D14(2, 1);
- _actor17.subA4D14(3, 2);
+ _westWall.subA4D14(3, 2);
break;
case 18:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(2, 6);
+ _eastWall.subA4D14(2, 6);
break;
case 19:
R2_GLOBALS._walkRegions.load(1571);
_field419 = 1571;
_actor16.subA4D14(2, 5);
- _actor18.subA4D14(3, 6);
+ _eastWall.subA4D14(3, 6);
break;
default:
break;
@@ -8960,24 +8991,27 @@ void Scene1550::subA2B2F() {
int di = 0;
int tmpIdx = 0;
- // Original game was checking "i < 129" but it was clearly a bug as it's out of bounds
- for (int i = 0; i < 129 * 4; i += 4) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == k562CC[i]) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == k562CC[i + 1]) && (k562CC[i + 2] != 0)) {
- tmpIdx = k562CC[i + 3];
- _arrUnkObj15501[di].postInit();
- _arrUnkObj15501[di]._effect = 6;
- _arrUnkObj15501[di]._shade = 0;
- _arrUnkObj15501[di]._fieldA4 = tmpIdx;
- _arrUnkObj15501[di]._fieldA6 = i;
- _arrUnkObj15501[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
- if (k562CC[i + 2] == 41) {
- _arrUnkObj15501[di].changeZoom(-1);
- _arrUnkObj15501[di].setPosition(Common::Point(150, 70));
- _arrUnkObj15501[di].setup(1562, 1, 1);
- R2_GLOBALS._walkRegions.enableRegion(k5A78C);
- R2_GLOBALS._walkRegions.enableRegion(k5A78D);
- R2_GLOBALS._walkRegions.enableRegion(k5A790);
- R2_GLOBALS._walkRegions.enableRegion(k5A791);
+ for (int i = 0; i < 127 * 4; i += 4) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == R2_GLOBALS._scene1550JunkLocations[i]) &&
+ (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == R2_GLOBALS._scene1550JunkLocations[i + 1]) &&
+ (R2_GLOBALS._scene1550JunkLocations[i + 2] != 0)) {
+ tmpIdx = R2_GLOBALS._scene1550JunkLocations[i + 3];
+ _junk[di].postInit();
+ _junk[di]._effect = 6;
+ _junk[di]._shade = 0;
+ _junk[di]._fieldA4 = tmpIdx;
+ _junk[di]._junkNumber = i;
+ _junk[di].setDetails(1550, 62, -1, 63, 2, (SceneItem *) NULL);
+ if (R2_GLOBALS._scene1550JunkLocations[i + 2] == 41) {
+ _junk[di].changeZoom(-1);
+ _junk[di].setPosition(Common::Point(150, 70));
+ _junk[di].setup(1562, 1, 1);
+
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[2]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[3]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[6]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[7]);
+
if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1550) {
_actor9.postInit();
_actor9.setup(1562, 3, 1);
@@ -8986,35 +9020,36 @@ void Scene1550::subA2B2F() {
_actor9.setDetails(1550, 41, -1, 42, 2, (SceneItem *) NULL);
}
} else {
- if (k562CC[i + 2] > 40) {
- _arrUnkObj15501[di].changeZoom(100);
- _arrUnkObj15501[di].setup(1561, 1, k562CC[i + 2] - 40);
+ if (R2_GLOBALS._scene1550JunkLocations[i + 2] > 40) {
+ _junk[di].changeZoom(100);
+ _junk[di].setup(1561, 1, R2_GLOBALS._scene1550JunkLocations[i + 2] - 40);
} else {
- _arrUnkObj15501[di].changeZoom(-1);
- _arrUnkObj15501[di].setup(1552, ((k562CC[i + 2] - 1) / 5) + 1, ((k562CC[i + 2] - 1) % 5) + 1);
+ _junk[di].changeZoom(-1);
+ _junk[di].setup(1552, ((R2_GLOBALS._scene1550JunkLocations[i + 2] - 1) / 5) + 1, ((R2_GLOBALS._scene1550JunkLocations[i + 2] - 1) % 5) + 1);
}
- _arrUnkObj15501[di].setPosition(Common::Point(k5A72E[tmpIdx], k5A73F[tmpIdx]));
- if (k5A78A[tmpIdx] != 0)
- R2_GLOBALS._walkRegions.enableRegion(k5A78A[tmpIdx]);
+ _junk[di].setPosition(Common::Point(k5A72E[tmpIdx], k5A73F[tmpIdx]));
+ if (scene1550JunkRegions[tmpIdx] != 0)
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[tmpIdx]);
di++;
}
}
}
for (int i = 0; i < 15 * 3; i++) {
- if ((R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex] == k5A79B[i]) && (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == k5A79B[i + 1])) {
+ if ((R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].x == k5A79B[i])
+ && (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == k5A79B[i + 1])) {
tmpIdx = k5A79B[i + 2];
switch (tmpIdx - 1) {
case 0:
if (!R2_GLOBALS.getFlag(16)) {
- _actor1.postInit();
- if (R2_GLOBALS._v565EC[R2_GLOBALS._player._characterIndex + 2] == 3)
- _actor1.setup(1555, 2, 1);
+ _landingStrut.postInit();
+ if (R2_GLOBALS._s1550PlayerArea[R2_GLOBALS._player._characterIndex].y == 3)
+ _landingStrut.setup(1555, 2, 1);
else
- _actor1.setup(1555, 1, 1);
- _actor1.setPosition(Common::Point(150, 100));
- _actor1.fixPriority(92);
- _actor1.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
+ _landingStrut.setup(1555, 1, 1);
+ _landingStrut.setPosition(Common::Point(150, 100));
+ _landingStrut.fixPriority(92);
+ _landingStrut.setDetails(1550, 73, -1, -1, 2, (SceneItem *) NULL);
}
break;
case 1:
@@ -9053,20 +9088,20 @@ void Scene1550::subA2B2F() {
_actor4.setPosition(Common::Point(172, 48));
_actor4.fixPriority(169);
- R2_GLOBALS._walkRegions.enableRegion(k5A78A[15]);
+ R2_GLOBALS._walkRegions.enableRegion(scene1550JunkRegions[15]);
break;
case 2:
- _actor6.postInit();
- _actor6.setup(1550, 1, 1);
- _actor6.setPosition(Common::Point(259, 55));
- _actor6.fixPriority(133);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 1, 2);
- _actor1.setPosition(Common::Point(259, 133));
- _actor1.fixPriority(105);
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 1, 1);
+ _wreckage.setPosition(Common::Point(259, 55));
+ _wreckage.fixPriority(133);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 1, 2);
+ _landingStrut.setPosition(Common::Point(259, 133));
+ _landingStrut.fixPriority(105);
+ _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 1550) {
_actor10.postInit();
_actor10.setup(1550, 7, 2);
@@ -9076,16 +9111,16 @@ void Scene1550::subA2B2F() {
}
break;
case 3:
- _actor6.postInit();
- _actor6.setup(1550, 1, 4);
- _actor6.setPosition(Common::Point(76, 131));
- _actor6.fixPriority(10);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 1, 3);
- _actor1.setPosition(Common::Point(76, 64));
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 1, 4);
+ _wreckage.setPosition(Common::Point(76, 131));
+ _wreckage.fixPriority(10);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 1, 3);
+ _landingStrut.setPosition(Common::Point(76, 64));
+ _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1550) {
_actor11.postInit();
_actor11.setup(1504, 4, 1);
@@ -9104,48 +9139,48 @@ void Scene1550::subA2B2F() {
}
break;
case 4:
- _actor6.postInit();
- _actor6.setup(1550, 2, 4);
- _actor6.setPosition(Common::Point(243, 131));
- _actor6.fixPriority(10);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 2, 3);
- _actor1.setPosition(Common::Point(243, 64));
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 2, 4);
+ _wreckage.setPosition(Common::Point(243, 131));
+ _wreckage.fixPriority(10);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 2, 3);
+ _landingStrut.setPosition(Common::Point(243, 64));
+ _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
break;
case 5:
- _actor6.postInit();
- _actor6.setup(1550, 2, 1);
- _actor6.setPosition(Common::Point(60, 55));
- _actor6.fixPriority(133);
- _actor6.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 2, 2);
- _actor1.setPosition(Common::Point(60, 133));
- _actor1.fixPriority(106);
- _actor1.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 2, 1);
+ _wreckage.setPosition(Common::Point(60, 55));
+ _wreckage.fixPriority(133);
+ _wreckage.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 2, 2);
+ _landingStrut.setPosition(Common::Point(60, 133));
+ _landingStrut.fixPriority(106);
+ _landingStrut.setDetails(1550, 9, -1, -1, 2, (SceneItem *) NULL);
break;
case 6:
- _actor6.postInit();
- _actor6.setup(1550, 3, 1);
- _actor6.setPosition(Common::Point(281, 132));
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 3, 1);
+ _wreckage.setPosition(Common::Point(281, 132));
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
break;
case 7:
- _actor6.postInit();
- _actor6.setup(1550, 3, 2);
- _actor6.setPosition(Common::Point(57, 96));
- _actor6.fixPriority(70);
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 3, 3);
- _actor1.setPosition(Common::Point(145, 88));
- _actor1.fixPriority(55);
- _actor1.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 3, 2);
+ _wreckage.setPosition(Common::Point(57, 96));
+ _wreckage.fixPriority(70);
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 3, 3);
+ _landingStrut.setPosition(Common::Point(145, 88));
+ _landingStrut.fixPriority(55);
+ _landingStrut.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
_actor2.postInit();
_actor2.setup(1550, 3, 4);
@@ -9159,17 +9194,17 @@ void Scene1550::subA2B2F() {
_actor3.fixPriority(45);
break;
case 8:
- _actor6.postInit();
- _actor6.setup(1550, 4, 2);
- _actor6.setPosition(Common::Point(262, 96));
- _actor6.fixPriority(70);
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
-
- _actor1.postInit();
- _actor1.setup(1550, 4, 3);
- _actor1.setPosition(Common::Point(174, 88));
- _actor1.fixPriority(55);
- _actor1.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 4, 2);
+ _wreckage.setPosition(Common::Point(262, 96));
+ _wreckage.fixPriority(70);
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+
+ _landingStrut.postInit();
+ _landingStrut.setup(1550, 4, 3);
+ _landingStrut.setPosition(Common::Point(174, 88));
+ _landingStrut.fixPriority(55);
+ _landingStrut.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
_actor2.postInit();
_actor2.setup(1550, 4, 4);
@@ -9183,55 +9218,56 @@ void Scene1550::subA2B2F() {
_actor3.fixPriority(45);
break;
case 9:
- _actor6.postInit();
- _actor6.setup(1550, 4, 1);
- _actor6.setPosition(Common::Point(38, 132));
- _actor6.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
+ _wreckage.postInit();
+ _wreckage.setup(1550, 4, 1);
+ _wreckage.setPosition(Common::Point(38, 132));
+ _wreckage.setDetails(1550, 56, -1, -1, 2, (SceneItem *) NULL);
break;
case 11:
- _arrUnkObj15502[7].subA5CDF(8);
- _arrUnkObj15502[0].subA5CDF(1);
- _arrUnkObj15502[1].subA5CDF(2);
- _arrUnkObj15502[2].subA5CDF(3);
- _arrUnkObj15502[3].subA5CDF(4);
- _arrUnkObj15502[4].subA5CDF(5);
- _arrUnkObj15502[5].subA5CDF(6);
- _arrUnkObj15502[6].subA5CDF(7);
+ // Intact ship
+ _shipComponents[7].setupShipComponent(8);
+ _shipComponents[0].setupShipComponent(1);
+ _shipComponents[1].setupShipComponent(2);
+ _shipComponents[2].setupShipComponent(3);
+ _shipComponents[3].setupShipComponent(4);
+ _shipComponents[4].setupShipComponent(5);
+ _shipComponents[5].setupShipComponent(6);
+ _shipComponents[6].setupShipComponent(7);
default:
break;
}
}
}
- if ((R2_GLOBALS._v565EC[1] == R2_GLOBALS._v565EC[2]) && (R2_GLOBALS._v565EC[3] == R2_GLOBALS._v565EC[4])) {
- _actor7.postInit();
- _actor7._effect = 7;
- _actor7.changeZoom(-1);
+ if (R2_GLOBALS._s1550PlayerArea[R2_QUINN] == R2_GLOBALS._s1550PlayerArea[R2_SEEKER]) {
+ _companion.postInit();
+ _companion._effect = 7;
+ _companion.changeZoom(-1);
assert((_field419 >= 1550) && (_field419 <= 2008));
R2_GLOBALS._walkRegions.enableRegion(k5A750[_field419 - 1550]);
- _actor7.setPosition(Common::Point(k5A72E[k5A76D[_field419 - 1550]], k5A73F[k5A76D[_field419 - 1550]] + 8));
- if (R2_GLOBALS._player._characterIndex == 1) {
+ _companion.setPosition(Common::Point(k5A72E[k5A76D[_field419 - 1550]], k5A73F[k5A76D[_field419 - 1550]] + 8));
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
if (R2_GLOBALS._player._characterScene[2] == 1580) {
- _actor7.setup(1516, 3, 17);
- _actor7.setPosition(Common::Point(272, 94));
- _actor7.fixPriority(91);
- _actor7.changeZoom(100);
- _actor7.setDetails(1550, -1, -1, -1, 5, &_arrUnkObj15502[7]);
+ _companion.setup(1516, 3, 17);
+ _companion.setPosition(Common::Point(272, 94));
+ _companion.fixPriority(91);
+ _companion.changeZoom(100);
+ _companion.setDetails(1550, -1, -1, -1, 5, &_shipComponents[7]);
} else {
- _actor7.setup(1505, 6, 1);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setup(1505, 6, 1);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
} else {
if (R2_GLOBALS._player._characterScene[1] == 1580) {
- _actor7.setup(1516, 2, 14);
- _actor7.setPosition(Common::Point(276, 97));
- _actor7.fixPriority(91);
- _actor7.changeZoom(100);
- _actor7.setDetails(1550, -1, -1, -1, 5, &_arrUnkObj15502[7]);
+ _companion.setup(1516, 2, 14);
+ _companion.setPosition(Common::Point(276, 97));
+ _companion.fixPriority(91);
+ _companion.changeZoom(100);
+ _companion.setDetails(1550, -1, -1, -1, 5, &_shipComponents[7]);
} else {
- _actor7.setup(1500, 6, 1);
- _actor7.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
+ _companion.setup(1500, 6, 1);
+ _companion.setDetails(1550, -1, -1, -1, 2, (SceneItem *) NULL);
}
}
}
@@ -9636,7 +9672,7 @@ bool Scene1580::Hotspot1::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_JOYSTICK) {
- R2_INVENTORY.setObjectScene(26, 1580);
+ R2_INVENTORY.setObjectScene(R2_JOYSTICK, 1580);
R2_GLOBALS._sceneItems.remove(&scene->_item1);
scene->_actor2.postInit();
scene->_actor2.setup(1580, 1, 4);
@@ -9655,7 +9691,7 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_DIAGNOSTICS_DISPLAY) {
- R2_INVENTORY.setObjectScene(28, 1580);
+ R2_INVENTORY.setObjectScene(R2_DIAGNOSTICS_DISPLAY, 1580);
R2_GLOBALS._player.disableControl();
R2_GLOBALS._sceneItems.remove(&scene->_item2);
@@ -9664,7 +9700,7 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
scene->_actor3.setPosition(Common::Point(124, 108));
scene->_actor3.fixPriority(10);
- if (R2_INVENTORY.getObjectScene(26) == 1580)
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580)
scene->_actor3.setDetails(1550, 14, -1, -1, 5, &scene->_actor2);
else
scene->_actor3.setDetails(1550, 14, -1, -1, 2, (SceneItem *)NULL);
@@ -9684,15 +9720,15 @@ bool Scene1580::Hotspot2::startAction(CursorType action, Event &event) {
}
bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
- if ( (action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(28) == 1580)
- && (R2_INVENTORY.getObjectScene(17) == 0) && (R2_INVENTORY.getObjectScene(22) == 0)
- && (R2_INVENTORY.getObjectScene(25) == 0) && (R2_INVENTORY.getObjectScene(18) == 0)
- && (R2_INVENTORY.getObjectScene(23) == 0) && (R2_INVENTORY.getObjectScene(27) == 0)) {
+ if ( (action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580)
+ && (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) == 0) && (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) == 0) && (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 0) && (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 0)) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
scene->_sceneMode = 31;
R2_GLOBALS._player.disableControl();
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
scene->_stripManager.start(536, scene);
else
scene->_stripManager.start(537, scene);
@@ -9704,10 +9740,10 @@ bool Scene1580::Actor2::startAction(CursorType action, Event &event) {
}
bool Scene1580::Actor3::startAction(CursorType action, Event &event) {
- if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(51) == 1580)) {
+ if ((action == CURSOR_USE) && (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580)) {
Scene1580 *scene = (Scene1580 *)R2_GLOBALS._sceneManager._scene;
- R2_INVENTORY.setObjectScene(51, R2_GLOBALS._player._characterIndex);
+ R2_INVENTORY.setObjectScene(R2_BROKEN_DISPLAY, R2_GLOBALS._player._characterIndex);
scene->_item2.setDetails(Rect(69, 29, 177, 108), 1550, 82, -1, -1, 2, NULL);
scene->_actor1.remove();
remove();
@@ -9750,8 +9786,8 @@ bool Scene1580::Actor6::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_INVENTORY.setObjectScene(23, 1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_INVENTORY.setObjectScene(R2_THRUSTER_VALVE, 1);
remove();
return true;
}
@@ -9782,8 +9818,8 @@ bool Scene1580::Actor7::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_GLOBALS._player._characterIndex == 1) {
- R2_INVENTORY.setObjectScene(27, 1);
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ R2_INVENTORY.setObjectScene(R2_IGNITOR, 1);
remove();
return true;
}
@@ -9823,7 +9859,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_sceneMode = 0;
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(26) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) == 1580) {
_actor2.postInit();
_actor2.setup(1580, 1, 4);
_actor2.setPosition(Common::Point(159, 163));
@@ -9832,7 +9868,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_item1.setDetails(Rect(141, 148, 179, 167), 1550, 79, -1, -1, 1, NULL);
}
- if (R2_INVENTORY.getObjectScene(51) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_BROKEN_DISPLAY) == 1580) {
_actor3.postInit();
_actor3.setup(1580, 1, 1);
_actor3.setPosition(Common::Point(124, 108));
@@ -9843,7 +9879,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor1.setup(1580, 1, 3);
_actor1.setPosition(Common::Point(124, 96));
_actor1.fixPriority(20);
- } else if (R2_INVENTORY.getObjectScene(28) == 1580) {
+ } else if (R2_INVENTORY.getObjectScene(R2_DIAGNOSTICS_DISPLAY) == 1580) {
_actor3.postInit();
_actor3.setup(1580, 1, 1);
_actor3.setPosition(Common::Point(124, 108));
@@ -9861,7 +9897,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
}
_actor4.postInit();
- if (R2_INVENTORY.getObjectScene(58) == 0) {
+ if (R2_GLOBALS.getFlag(58) == 0) {
_actor4.setup(1580, 5, 1);
_actor4.setDetails(1550, 80, -1, -1, 1, (SceneItem *) NULL);
} else {
@@ -9876,8 +9912,8 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor5.setPosition(Common::Point(291, 147));
_actor5.fixPriority(100);
_actor5.setDetails(1550, 81, -1, -1, 1, (SceneItem *) NULL);
-
- if (R2_INVENTORY.getObjectScene(23) == 1580) {
+
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) == 1580) {
_actor6.postInit();
_actor6.setup(1580, 6, 2);
_actor6.setPosition(Common::Point(222, 108));
@@ -9885,7 +9921,7 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
_actor6.setDetails(1550, 32, -1, 34, 1, (SceneItem *) NULL);
}
- if (R2_INVENTORY.getObjectScene(27) == 1580) {
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) == 1580) {
_actor7.postInit();
_actor7.setup(1580, 6, 1);
_actor7.setPosition(Common::Point(195, 108));
@@ -9894,11 +9930,9 @@ void Scene1580::postInit(SceneObjectList *OwnerList) {
}
R2_GLOBALS._player.postInit();
- R2_GLOBALS._player._oldCharacterScene[R2_GLOBALS._player._characterIndex] = 1580;
R2_GLOBALS._player.hide();
setAction(&_sequenceManager, this, 1, &R2_GLOBALS._player, NULL);
_item3.setDetails(Rect(0, 0, 320, 200), 1550, 50, -1, -1, 1, NULL);
-
}
void Scene1580::signal() {
@@ -9910,49 +9944,49 @@ void Scene1580::signal() {
_actor1.setup(1580, 1, 2);
_actor1.setPosition(Common::Point(124, 94));
- if (R2_INVENTORY.getObjectScene(18) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_GYROSCOPE) != 0) {
_arrActor[0].postInit();
_arrActor[0].setup(1580, 2, 1);
_arrActor[0].setPosition(Common::Point(138, 56));
}
- if (R2_INVENTORY.getObjectScene(25) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_RADAR_MECHANISM) != 0) {
_arrActor[1].postInit();
_arrActor[1].setup(1580, 2, 2);
_arrActor[1].setPosition(Common::Point(140, 66));
}
- if (R2_INVENTORY.getObjectScene(27) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_IGNITOR) != 0) {
_arrActor[2].postInit();
_arrActor[2].setup(1580, 2, 3);
_arrActor[2].setPosition(Common::Point(142, 85));
}
- if (R2_INVENTORY.getObjectScene(23) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_THRUSTER_VALVE) != 0) {
_arrActor[3].postInit();
_arrActor[3].setup(1580, 2, 4);
_arrActor[3].setPosition(Common::Point(142, 92));
}
- if (R2_INVENTORY.getObjectScene(22) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_GUIDANCE_MODULE) != 0) {
_arrActor[4].postInit();
_arrActor[4].setup(1580, 2, 5);
_arrActor[4].setPosition(Common::Point(108, 54));
}
- if (R2_INVENTORY.getObjectScene(26) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_JOYSTICK) != 0) {
_arrActor[5].postInit();
_arrActor[5].setup(1580, 2, 6);
_arrActor[5].setPosition(Common::Point(110, 64));
}
- if (R2_INVENTORY.getObjectScene(45) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_BATTERY) != 0) {
_arrActor[6].postInit();
_arrActor[6].setup(1580, 2, 7);
_arrActor[6].setPosition(Common::Point(108, 80));
}
- if (R2_INVENTORY.getObjectScene(17) != 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FUEL_CELL) != 0) {
_arrActor[7].postInit();
_arrActor[7].setup(1580, 2, 8);
_arrActor[7].setPosition(Common::Point(111, 92));
@@ -10197,7 +10231,7 @@ void Scene1625::signal() {
_actor6.postInit();
warning("_actor6._actorName = \"arm\";");
- R2_INVENTORY.setObjectScene(40, 3);
+ R2_INVENTORY.setObjectScene(R2_SUPERCONDUCTOR_WIRE, 3);
_sceneMode = 14;
setAction(&_sequenceManager, this, 1625, &_actor1, &_actor6, NULL);
@@ -10644,7 +10678,7 @@ void Scene1700::signal() {
Common::Point pt(271, 90);
PlayerMover *mover = new PlayerMover();
_actor12.addMover(mover, &pt, NULL);
- if (R2_GLOBALS._player._characterIndex == 1)
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN)
setAction(&_sequenceManager, this, 1700, &R2_GLOBALS._player, &_actor8, NULL);
else
setAction(&_sequenceManager, this, 1701, &R2_GLOBALS._player, &_actor8, NULL);
@@ -12755,7 +12789,7 @@ void Scene1900::signal() {
R2_GLOBALS._sceneManager.changeScene(1925);
break;
case 1910:
- R2_INVENTORY.setObjectScene(22, 2535);
+ R2_INVENTORY.setObjectScene(R2_GUIDANCE_MODULE, 2535);
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
R2_GLOBALS._player._oldCharacterScene[1] = 1900;
R2_GLOBALS._player._oldCharacterScene[2] = 1900;
@@ -13505,7 +13539,6 @@ void Scene1950::Area1::remove() {
_areaActor.remove();
SceneArea::remove();
R2_GLOBALS._insetUp--;
- //
if (!R2_GLOBALS.getFlag(37))
R2_GLOBALS._sound2.play(278);
@@ -13525,7 +13558,7 @@ void Scene1950::Area1::remove() {
}
void Scene1950::Area1::process(Event &event) {
-// This is a copy of Scene1200::LaserPanel::process
+ // This is a copy of Scene1200::LaserPanel::process
if (_field20 != R2_GLOBALS._insetUp)
return;
@@ -13533,19 +13566,16 @@ void Scene1950::Area1::process(Event &event) {
if (_areaActor._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
if (cursor == _cursorNum) {
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
if (cursor != _cursorNum) {
_savedCursorNum = cursor;
- warning("TODO: _cursorState = ???");
R2_GLOBALS._events.setCursor(CURSOR_INVALID);
}
if (event.eventType == EVENT_BUTTON_DOWN) {
event.handled = true;
- warning("TODO: _cursorState = ???");
- R2_GLOBALS._events.setCursor(_savedCursorNum); //, _cursorState);
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
remove();
}
}
@@ -13606,14 +13636,14 @@ bool Scene1950::Actor2::startAction(CursorType action, Event &event) {
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(31, 0);
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 0);
scene->_sceneMode = 1958;
scene->setAction(&scene->_sequenceManager, scene, 1958, &R2_GLOBALS._player, &scene->_actor2, NULL);
return true;
}
bool Scene1950::Actor3::startAction(CursorType action, Event &event) {
- if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(35) != 1950))
+ if ((action != CURSOR_USE) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) != 1950))
return SceneActor::startAction(action, event);
Scene1950 *scene = (Scene1950 *)R2_GLOBALS._sceneManager._scene;
@@ -13882,7 +13912,7 @@ void Scene1950::Exit6::changeScene() {
R2_GLOBALS._player.disableControl(CURSOR_ARROW);
R2_GLOBALS._v566A5 = 5;
if (R2_GLOBALS._v566A4 == 2) {
- if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(34) == 2) && (R2_INVENTORY.getObjectScene(35) == 2)) {
+ if ((R2_GLOBALS.getFlag(36)) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 2) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)) {
scene->_sceneMode = 1961;
Common::Point pt(-20, 160);
NpcMover *mover = new NpcMover();
@@ -13890,7 +13920,7 @@ void Scene1950::Exit6::changeScene() {
} else {
if (!R2_GLOBALS.getFlag(36))
SceneItem::display(1950, 33, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
- if ((R2_INVENTORY.getObjectScene(34) == 1950) || (R2_INVENTORY.getObjectScene(35) == 1950))
+ if ((R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) || (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 1950))
SceneItem::display(1950, 34, 0, 280, 1, 160, 9, 1, 2, 20, 7, 7, -999);
scene->_sceneMode = 0;
Common::Point pt(30, 160);
@@ -14201,7 +14231,7 @@ void Scene1950::subBDC1E() {
switch (R2_GLOBALS._v566A4 - 1) {
case 0:
_exit7._enabled = true;
- if ((R2_INVENTORY.getObjectScene(31) == 0) && (R2_INVENTORY.getObjectScene(34) == 1950))
+ if ((R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) && (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950))
_exit8._enabled = true;
R2_GLOBALS._walkRegions.enableRegion(2);
R2_GLOBALS._walkRegions.enableRegion(3);
@@ -14719,7 +14749,7 @@ void Scene1950::subBE59B() {
_field416 = 1;
}
}
- if ((R2_GLOBALS._v566A4 == 1) && (R2_INVENTORY.getObjectScene(31) != 0)) {
+ if ((R2_GLOBALS._v566A4 == 1) && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) != 0)) {
_actor2.postInit();
_actor2.setVisage(1948);
_actor2.setStrip(3);
@@ -14755,7 +14785,7 @@ void Scene1950::subBE59B() {
_item2.setDetails(Rect(188, 124, 199, 133), 1950, 27, 28, -1, 2, NULL);
- if (R2_INVENTORY.getObjectScene(34) == 1950) {
+ if (R2_INVENTORY.getObjectScene(R2_SAPPHIRE_BLUE) == 1950) {
_actor5.postInit();
_actor5.setVisage(1970);
_actor5.setStrip(1);
@@ -14786,7 +14816,7 @@ void Scene1950::subBE59B() {
_actor3.setPosition(Common::Point(76, 94));
_actor3.fixPriority(25);
_actor3.setDetails(1950, 30, -1, -1, 2, (SceneItem *) NULL);
- if (R2_INVENTORY.getObjectScene(35) == 2)
+ if (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2)
_actor3.setFrame(2);
else
_actor3.setFrame(1);
@@ -14805,7 +14835,7 @@ void Scene1950::subBE59B() {
switch (R2_GLOBALS._v566A5) {
case 0:
_sceneMode = 1950;
- if (R2_INVENTORY.getObjectScene(31) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0) {
R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
} else {
@@ -15020,8 +15050,8 @@ void Scene1950::postInit(SceneObjectList *OwnerList) {
_exit8.setDest(Common::Point(268, 149));
R2_GLOBALS._player.postInit();
- if ( (R2_INVENTORY.getObjectScene(32) == 0) && (R2_INVENTORY.getObjectScene(33) == 0)
- && (R2_INVENTORY.getObjectScene(46) == 0) && (!R2_GLOBALS.getFlag(36)) )
+ if ( (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 0) && (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 0)
+ && (R2_INVENTORY.getObjectScene(R2_SOAKED_FACEMASK) == 0) && (!R2_GLOBALS.getFlag(36)) )
R2_GLOBALS._player.setVisage(22);
else
R2_GLOBALS._player.setVisage(20);
@@ -15124,7 +15154,7 @@ void Scene1950::signal() {
_exit8._enabled = true;
break;
case 1959:
- R2_INVENTORY.setObjectScene(46, 0);
+ R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 0);
R2_GLOBALS._v56AAB = 0;
R2_GLOBALS._player.enableControl(CURSOR_ARROW);
_exit8._enabled = true;
@@ -15155,7 +15185,7 @@ void Scene1950::signal() {
_actor5.setDetails(1950, 9, -1, -1, 2, (SceneItem *) NULL);
case 1967: {
_sceneMode = 0;
- R2_INVENTORY.setObjectScene(34, 2);
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 2);
_actor5.remove();
if (R2_GLOBALS.getFlag(36))
R2_GLOBALS._player.setVisage(20);
@@ -15170,7 +15200,7 @@ void Scene1950::signal() {
break;
case 1968:
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(35, 2);
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2);
_actor3.setFrame(2);
if (R2_GLOBALS.getFlag(36))
R2_GLOBALS._player.setVisage(20);
@@ -15190,7 +15220,7 @@ void Scene1950::process(Event &event) {
&& (R2_GLOBALS._player._uiEnabled)
&& (R2_GLOBALS._events.getCursor() == R2_LIGHT_BULB)
&& (R2_GLOBALS._player._bounds.contains(event.mousePos))
- && (R2_INVENTORY.getObjectScene(31) == 0)) {
+ && (R2_INVENTORY.getObjectScene(R2_SCRITH_KEY) == 0)) {
event.handled = true;
R2_GLOBALS._player.disableControl();
_exit7._enabled = false;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes1.h b/engines/tsage/ringworld2/ringworld2_scenes1.h
index 23ebb2c276..f984a6986a 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes1.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes1.h
@@ -75,15 +75,15 @@ public:
};
class Scene1100 : public SceneExt {
- class Actor16 : public SceneActor {
+ class Seeker : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor17 : public SceneActor {
+ class Trooper : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor18 : public SceneActor {
+ class Chief : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -118,9 +118,9 @@ public:
SceneActor _actor15;
BackgroundSceneObject _object1;
BackgroundSceneObject _object2;
- Actor16 _actor16;
- Actor17 _actor17;
- Actor18 _actor18;
+ Seeker _seeker;
+ Trooper _trooper;
+ Chief _chief;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
SequenceManager _sequenceManager3;
@@ -427,26 +427,26 @@ class Scene1550 : public SceneExt {
void subA4D14(int frameNumber, int strip);
};
- class UnkObj15501 : public SceneActor {
+ class Junk : public SceneActor {
public:
int _fieldA4;
- int _fieldA6;
+ int _junkNumber;
- UnkObj15501();
+ Junk();
void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
};
- class UnkObj15502 : public SceneActor {
+ class ShipComponent : public SceneActor {
public:
- int _fieldA4;
+ int _componentId;
- UnkObj15502();
+ ShipComponent();
void synchronize(Serializer &s);
virtual bool startAction(CursorType action, Event &event);
- void subA5CDF(int strip);
+ void setupShipComponent(int componentId);
};
class UnkObj15503 : public SceneActor {
@@ -472,7 +472,7 @@ class Scene1550 : public SceneExt {
virtual void proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum);
};
- class Hotspot1 : public NamedHotspot {
+ class WorkingShip : public NamedHotspot {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -482,12 +482,12 @@ class Scene1550 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor6 : public SceneActor {
+ class Wreckage : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
- class Actor7 : public SceneActor {
+ class Companion : public SceneActor {
public:
virtual bool startAction(CursorType action, Event &event);
};
@@ -522,7 +522,7 @@ class Scene1550 : public SceneExt {
virtual bool startAction(CursorType action, Event &event);
};
- class Actor14 : public SceneActor1550 {
+ class Wall : public SceneActor1550 {
// Nothing specific found in the original
// TODO: check if it's an useless class
};
@@ -530,30 +530,30 @@ class Scene1550 : public SceneExt {
public:
SpeakerQuinn _quinnSpeaker;
SpeakerSeeker _seekerSpeaker;
- Hotspot1 _item1;
- Hotspot1 _item2;
+ WorkingShip _shipHull;
+ WorkingShip _item2;
Hotspot3 _item3;
- SceneActor _actor1;
+ SceneActor _landingStrut;
SceneActor _actor2;
SceneActor _actor3;
SceneActor _actor4;
SceneActor _actor5;
- Actor6 _actor6;
- Actor7 _actor7;
+ Wreckage _wreckage;
+ Companion _companion;
Actor8 _actor8;
Actor9 _actor9;
Actor10 _actor10;
Actor11 _actor11;
Actor12 _actor12;
Actor13 _actor13;
- UnkObj15501 _arrUnkObj15501[8];
- Actor14 _actor14;
- Actor14 _actor15;
- Actor14 _actor16;
- Actor14 _actor17;
- Actor14 _actor18;
- Actor14 _actor19;
- UnkObj15502 _arrUnkObj15502[8];
+ Junk _junk[8];
+ Wall _actor14;
+ Wall _northWall; // Is also reused for landing strip
+ Wall _actor16;
+ Wall _westWall; // Is also reused for left hand space
+ Wall _eastWall;
+ Wall _southWall;
+ ShipComponent _shipComponents[8];
UnkArea1550 _unkArea1;
SequenceManager _sequenceManager1;
SequenceManager _sequenceManager2;
@@ -566,7 +566,7 @@ public:
Scene1550();
void synchronize(Serializer &s);
- void subA2B2F();
+ void enterArea();
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
diff --git a/engines/tsage/ringworld2/ringworld2_scenes2.cpp b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
index 9246c4b6a4..432f284890 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes2.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes2.cpp
@@ -769,6 +769,7 @@ Scene2000::Scene2000(): SceneExt() {
}
_exitingFlag = false;
+ _mazePlayerMode = 0;
}
void Scene2000::postInit(SceneObjectList *OwnerList) {
@@ -1116,7 +1117,7 @@ void Scene2350::postInit(SceneObjectList *OwnerList) {
_actor3.postInit();
_actor4.postInit();
- if (R2_INVENTORY.getObjectScene(20) == 2350) {
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2350) {
_actor3.hide();
_actor4.hide();
} else {
@@ -1176,12 +1177,12 @@ void Scene2350::signal() {
break;
case 21:
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(36, 1);
+ R2_INVENTORY.setObjectScene(R2_FLUTE, 1);
_sceneMode = 2354;
setAction(&_sequenceManager, this, 2354, &R2_GLOBALS._player, NULL);
break;
case 2354:
- R2_INVENTORY.setObjectScene(20, 2350);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2350);
g_globals->_sceneManager.changeScene(2900);
break;
case 2355:
@@ -1534,7 +1535,7 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(108, 160));
- if (R2_INVENTORY.getObjectScene(37) == 2430) {
+ if (R2_INVENTORY.getObjectScene(R2_GUNPOWDER) == 2430) {
_actor2.postInit();
_actor2.setup(2435, 1, 5);
_actor2.setPosition(Common::Point(205, 119));
@@ -1542,7 +1543,7 @@ void Scene2430::postInit(SceneObjectList *OwnerList) {
_actor2.setDetails(2430, 51, -1, 53, 1, (SceneItem *)NULL);
}
- if (R2_INVENTORY.getObjectScene(50) == 2435) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2435) {
_actor3.postInit();
_actor3.setup(2435, 1, 1);
_actor3.setPosition(Common::Point(31, 65));
@@ -1820,7 +1821,7 @@ void Scene2440::postInit(SceneObjectList *OwnerList) {
// Fix exit cursor, the original was using NW
_exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_SE, 2000);
_exit1.setDest(Common::Point(210, 160));
- if (R2_INVENTORY.getObjectScene(49) == 2440) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2440) {
_actor2.postInit();
_actor2.setup(2435, 1, 1);
_actor2.setPosition(Common::Point(94, 80));
@@ -1885,7 +1886,7 @@ void Scene2440::signal() {
break;
case 2440:
_actor2.remove();
- R2_INVENTORY.setObjectScene(49, 2);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_2, 2);
// No break on purpose
default:
R2_GLOBALS._player.enableControl();
@@ -2212,7 +2213,7 @@ bool Scene2455::Actor1::startAction(CursorType action, Event &event) {
Scene2455 *scene = (Scene2455 *)R2_GLOBALS._sceneManager._scene;
if (action == R2_GLASS_DOME) {
- if ((R2_INVENTORY.getObjectScene(49) == 2455) || (R2_INVENTORY.getObjectScene(50) == 2455)) {
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455) || (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455)) {
R2_GLOBALS._player.disableControl();
scene->_sceneMode = 2458;
scene->_actor2._lookLineNum = 9;
@@ -2232,7 +2233,7 @@ bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
switch (action) {
case R2_ALCOHOL_LAMP_2:
- if (R2_INVENTORY.getObjectScene(50) != 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) != 2455) {
R2_GLOBALS._player.disableControl();
scene->_actor1.postInit();
scene->_actor1.setup(2456, 3, 3);
@@ -2244,7 +2245,7 @@ bool Scene2455::Actor2::startAction(CursorType action, Event &event) {
}
break;
case R2_ALCOHOL_LAMP_3:
- if (R2_INVENTORY.getObjectScene(49) != 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) != 2455) {
R2_GLOBALS._player.disableControl();
scene->_actor1.postInit();
scene->_actor1.setup(2456, 3, 3);
@@ -2290,15 +2291,15 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1) {
- R2_INVENTORY.setObjectScene(29, 2);
- R2_INVENTORY.setObjectScene(50, 2);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_3, 2);
}
R2_GLOBALS._sound1.play(200);
_exit1.setDetails(Rect(0, 0, 320, 15), EXITCURSOR_N, 2425);
- if (R2_INVENTORY.getObjectScene(29) == 2455) {
- if ((R2_INVENTORY.getObjectScene(50) == 2455) || (R2_INVENTORY.getObjectScene(49) == 2455)) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) == 2455) || (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) == 2455)) {
_actor1.postInit();
_actor1.setup(2456, 3, 3);
_actor1.setPosition(Common::Point(162, 165));
@@ -2312,11 +2313,11 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
}
_actor2.postInit();
- if (R2_INVENTORY.getObjectScene(29) == 2455) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2455) {
_actor2.setup(2456, 3, 2);
_actor2.setDetails(2455, 9, 1, -1, 1, (SceneItem *)NULL);
} else {
- if ((R2_INVENTORY.getObjectScene(50) != 2455) && (R2_INVENTORY.getObjectScene(49) != 2455))
+ if ((R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_3) != 2455) && (R2_INVENTORY.getObjectScene(R2_ALCOHOL_LAMP_2) != 2455))
_actor2.setup(2455, 1, 1);
else
_actor2.setup(2456, 1, 1);
@@ -2324,7 +2325,7 @@ void Scene2455::postInit(SceneObjectList *OwnerList) {
}
_actor2.setPosition(Common::Point(162, 165));
_actor2.fixPriority(20);
- if (R2_INVENTORY.getObjectScene(29) != 2455)
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) != 2455)
_actor2.animate(ANIM_MODE_2, NULL);
R2_GLOBALS._player.postInit();
@@ -2356,23 +2357,23 @@ void Scene2455::signal() {
g_globals->_sceneManager.changeScene(2425);
break;
case 11:
- R2_INVENTORY.setObjectScene(49, 2455);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_2, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 12:
- R2_INVENTORY.setObjectScene(50, 2455);
+ R2_INVENTORY.setObjectScene(R2_ALCOHOL_LAMP_3, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 2458:
- R2_INVENTORY.setObjectScene(29, 2455);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2455);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
case 2459:
_actor3.remove();
- R2_INVENTORY.setObjectScene(31, 2);
+ R2_INVENTORY.setObjectScene(R2_SCRITH_KEY, 2);
R2_GLOBALS._player.enableControl(CURSOR_USE);
R2_GLOBALS._player._canWalk = false;
break;
@@ -2542,7 +2543,7 @@ void Scene2525::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(86, 155, 228, 168), EXITCURSOR_S, 2000);
- if (R2_INVENTORY.getObjectScene(29) == 2525) {
+ if (R2_INVENTORY.getObjectScene(R2_GLASS_DOME) == 2525) {
_actor3.postInit();
_actor3.setup(2435, 1, 2);
_actor3.setPosition(Common::Point(78, 155));
@@ -2615,7 +2616,7 @@ void Scene2525::signal() {
break;
case 2525:
_actor3.remove();
- R2_INVENTORY.setObjectScene(29, 2);
+ R2_INVENTORY.setObjectScene(R2_GLASS_DOME, 2);
R2_GLOBALS._player.enableControl();
break;
case 2526:
@@ -2698,7 +2699,7 @@ void Scene2530::postInit(SceneObjectList *OwnerList) {
_exit1.setDetails(Rect(68, 155, 147, 168), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(108, 160));
- if (R2_INVENTORY.getObjectScene(33) == 2530) {
+ if (R2_INVENTORY.getObjectScene(R2_PURE_GRAIN_ALCOHOL) == 2530) {
_actor2.postInit();
_actor2.setup(2435, 1, 3);
_actor2.setPosition(Common::Point(299, 80));
@@ -2766,7 +2767,7 @@ void Scene2530::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2530:
- R2_INVENTORY.setObjectScene(33, 2);
+ R2_INVENTORY.setObjectScene(R2_PURE_GRAIN_ALCOHOL, 2);
_actor2.remove();
break;
case 2531:
@@ -2798,7 +2799,7 @@ bool Scene2535::Actor3::startAction(CursorType action, Event &event) {
if (R2_GLOBALS._player._characterIndex == 1) {
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(20) == 2535) {
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) {
scene->_sceneMode = 2536;
scene->setAction(&scene->_sequenceManager, scene, 2536, &R2_GLOBALS._player, &scene->_actor3, NULL);
} else {
@@ -2846,12 +2847,12 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
SceneExt::postInit();
if (R2_GLOBALS._sceneManager._previousScene == -1) {
R2_GLOBALS.setFlag(73);
- R2_INVENTORY.setObjectScene(20, 2535);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 2535);
}
_exit1.setDetails(Rect(172, 155, 250, 167), EXITCURSOR_S, 2000);
_exit1.setDest(Common::Point(210, 160));
- if (R2_INVENTORY.getObjectScene(32) == 2535) {
+ if (R2_INVENTORY.getObjectScene(R2_TANNER_MASK) == 2535) {
_actor4.postInit();
_actor4.setup(2435, 1, 4);
_actor4.setPosition(Common::Point(47, 74));
@@ -2859,7 +2860,7 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
_actor4.setDetails(2535, 21, -1, -1, 1, (SceneItem *)NULL);
}
- if (R2_INVENTORY.getObjectScene(20) == 2535) {
+ if (R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 2535) {
_actor3.postInit();
_actor3.setup(2535, 3, 1);
_actor3.setPosition(Common::Point(203, 131));
@@ -2867,7 +2868,7 @@ void Scene2535::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._walkRegions.enableRegion(6);
}
- if ((R2_INVENTORY.getObjectScene(20) == 0) && (R2_GLOBALS.getFlag(73))) {
+ if ((R2_INVENTORY.getObjectScene(R2_REBREATHER_TANK) == 0) && (R2_GLOBALS.getFlag(73))) {
_actor3.postInit();
_actor3.setup(2536, 1, 2);
_actor3.setPosition(Common::Point(164, 133));
@@ -2933,12 +2934,12 @@ void Scene2535::signal() {
g_globals->_sceneManager.changeScene(2000);
break;
case 2535:
- R2_INVENTORY.setObjectScene(32, 2);
+ R2_INVENTORY.setObjectScene(R2_TANNER_MASK, 2);
_actor4.remove();
R2_GLOBALS._player.enableControl();
break;
case 2536:
- R2_INVENTORY.setObjectScene(20, 0);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 0);
R2_GLOBALS._walkRegions.disableRegion(6);
if (!R2_GLOBALS.getFlag(73)) {
_actor3.remove();
@@ -2958,7 +2959,7 @@ void Scene2535::signal() {
break;
case 2537:
_actor3.remove();
- R2_INVENTORY.setObjectScene(20, 1);
+ R2_INVENTORY.setObjectScene(R2_REBREATHER_TANK, 1);
R2_GLOBALS._player.enableControl();
break;
case 20:
@@ -3211,7 +3212,7 @@ void Scene2700::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(36) == 0)
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0)
R2_GLOBALS._sound1.changeSound(234);
if (R2_GLOBALS._sceneManager._previousScene == 2750) {
@@ -3452,7 +3453,7 @@ void Scene2700::signal() {
}
break;
case 11:
- R2_INVENTORY.setObjectScene(36, 0);
+ R2_INVENTORY.setObjectScene(R2_FLUTE, 0);
R2_GLOBALS._player.disableControl();
_field412 = 0;
_sceneMode = 2700;
@@ -3854,7 +3855,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
_rect2.set(130, 142, 210, 167);
_rect3.set(-1, 137, 290, 147);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._sound1.changeSound(235);
_actor2.postInit();
_actor2.setup(2751, 1, 1);
@@ -3929,7 +3930,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_quinnSpeaker);
_stripManager.addSpeaker(&_nejSpeaker);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
_actor1.postInit();
_actor1.setup(2752, 5, 1);
_actor1.animate(ANIM_MODE_NONE, NULL);
@@ -3943,7 +3944,7 @@ void Scene2750::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player.disableControl();
if (R2_GLOBALS._sceneManager._previousScene == 2700) {
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._player.setVisage(2752);
R2_GLOBALS._player.setStrip(6);
R2_GLOBALS._player.animate(ANIM_MODE_NONE, NULL);
@@ -4448,7 +4449,7 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
_stripManager.addSpeaker(&_nejSpeaker);
_stripManager.addSpeaker(&_guardSpeaker);
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._sound1.fadeSound(237);
if (R2_GLOBALS.getFlag(47)) {
_item2.setDetails(Rect(76, 45, 155, 90), 2800, 3, -1, -1, 2, NULL);
@@ -4469,7 +4470,7 @@ void Scene2800::postInit(SceneObjectList *OwnerList) {
R2_GLOBALS._player._moveDiff = Common::Point(2, 2);
R2_GLOBALS._player.disableControl();
- if (R2_INVENTORY.getObjectScene(36) == 0) {
+ if (R2_INVENTORY.getObjectScene(R2_FLUTE) == 0) {
R2_GLOBALS._player.setAction(&_sequenceManager, this, 2800, &R2_GLOBALS._player, NULL);
} else if (R2_GLOBALS.getFlag(47)) {
R2_GLOBALS._player.setVisage(3110);
diff --git a/engines/tsage/ringworld2/ringworld2_scenes3.cpp b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
index 6af2a0cad4..b2958a3d5e 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes3.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes3.cpp
@@ -378,7 +378,7 @@ bool Scene3150::Item5::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (R2_INVENTORY.getObjectScene(47) != 3150)
+ if (R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150)
return SceneHotspot::startAction(action, event);
R2_GLOBALS._player.disableControl();
@@ -386,7 +386,7 @@ bool Scene3150::Item5::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3154, &R2_GLOBALS._player, &scene->_actor3, NULL);
return true;
case R2_SUPERCONDUCTOR_WIRE:
- if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_GLOBALS.getFlag(75))) {
+ if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) && (R2_GLOBALS.getFlag(75))) {
R2_GLOBALS._player.disableControl();
scene->_actor3.postInit();
scene->_actor3._effect = 3;
@@ -417,7 +417,7 @@ bool Scene3150::Item6::startAction(CursorType action, Event &event) {
scene->setAction(&scene->_sequenceManager, scene, 3158, &R2_GLOBALS._player, &scene->_actor4, NULL);
return true;
case R2_FOOD_TRAY:
- if ((R2_INVENTORY.getObjectScene(47) != 3150) && (R2_INVENTORY.getObjectScene(40) == 3150) && (R2_GLOBALS.getFlag(75))) {
+ if ((R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) != 3150) && (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150) && (R2_GLOBALS.getFlag(75))) {
scene->_actor5.postInit();
scene->_actor5._effect = 6;
scene->_actor5._shade = 3;
@@ -535,7 +535,7 @@ void Scene3150::Exit2::changeScene() {
void Scene3150::postInit(SceneObjectList *OwnerList) {
loadScene(3150);
if (R2_GLOBALS._sceneManager._previousScene == -1) {
- R2_INVENTORY.setObjectScene(35, 2000);
+ R2_INVENTORY.setObjectScene(R2_ANCIENT_SCROLLS, 2000);
R2_GLOBALS._player._oldCharacterScene[1] = 3100;
R2_GLOBALS._player._oldCharacterScene[3] = 0;
R2_GLOBALS._player._characterIndex = R2_MIRANDA;
@@ -583,7 +583,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
_actor7.fixPriority(50);
_actor7.setDetails(3150, 17, -1, 19, 1, (SceneItem *)NULL);
- if (R2_INVENTORY.getObjectScene(41) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_PILLOW) == 3150) {
_actor4.postInit();
if (R2_GLOBALS.getFlag(75)) {
if (R2_GLOBALS.getFlag(76)) {
@@ -608,13 +608,13 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
}
}
- if (R2_INVENTORY.getObjectScene(47) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_LIGHT_BULB) == 3150) {
_actor3.postInit();
_actor3.setup(3152, 7, 1);
_actor3.setPosition(Common::Point(73, 83));
}
- if (R2_INVENTORY.getObjectScene(40) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_SUPERCONDUCTOR_WIRE) == 3150) {
_actor3.postInit();
_actor3.setup(3152, 7, 3);
_actor3.setPosition(Common::Point(70, 55));
@@ -623,7 +623,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
_actor3._shade = 5;
}
- if (R2_INVENTORY.getObjectScene(42) == 3150) {
+ if (R2_INVENTORY.getObjectScene(R2_FOOD_TRAY) == 3150) {
_actor5.postInit();
if (R2_GLOBALS.getFlag(77)) {
_actor5.setup(3152, 7, 8);
@@ -675,7 +675,7 @@ void Scene3150::postInit(SceneObjectList *OwnerList) {
break;
}
default:
- if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(35) == 2000) && (R2_GLOBALS._player._oldCharacterScene[1] == 3100)) {
+ if ((R2_GLOBALS._v56AA0 == 1) && (R2_INVENTORY.getObjectScene(R2_ANCIENT_SCROLLS) == 2000) && (R2_GLOBALS._player._oldCharacterScene[1] == 3100)) {
++R2_GLOBALS._v56AA0;
_sceneMode = 3156;
_actor1.postInit();
@@ -713,7 +713,7 @@ void Scene3150::signal() {
break;
case 3151:
_actor1.remove();
- R2_INVENTORY.setObjectScene(41, 3);
+ R2_INVENTORY.setObjectScene(R2_PILLOW, 3);
R2_GLOBALS._player.enableControl();
break;
case 3153:
@@ -726,37 +726,37 @@ void Scene3150::signal() {
break;
case 3154:
_actor3.remove();
- R2_INVENTORY.setObjectScene(47, 3);
+ R2_INVENTORY.setObjectScene(R2_LIGHT_BULB, 3);
R2_GLOBALS._player.enableControl();
break;
case 3155:
- R2_INVENTORY.setObjectScene(40, 3150);
+ R2_INVENTORY.setObjectScene(R2_SUPERCONDUCTOR_WIRE, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3156:
_actor5.setDetails(3150, 30, -1, -1, 2, (SceneItem *)NULL);
- R2_INVENTORY.setObjectScene(42, 3150);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3157:
_actor5.remove();
- R2_INVENTORY.setObjectScene(42, 3);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3);
R2_GLOBALS._player.enableControl();
break;
case 3158:
R2_GLOBALS.setFlag(75);
- R2_INVENTORY.setObjectScene(41, 3150);
+ R2_INVENTORY.setObjectScene(R2_PILLOW, 3150);
_actor4.fixPriority(110);
_actor4.setDetails(3150, 13, -1, -1, 2, (SceneItem *)NULL);
R2_GLOBALS._player.enableControl();
break;
case 3159:
R2_GLOBALS.setFlag(77);
- R2_INVENTORY.setObjectScene(42, 3150);
+ R2_INVENTORY.setObjectScene(R2_FOOD_TRAY, 3150);
R2_GLOBALS._player.enableControl();
break;
case 3160:
- R2_INVENTORY.setObjectScene(52, 3150);
+ R2_INVENTORY.setObjectScene(R2_TOOLBOX, 3150);
R2_GLOBALS.setFlag(80);
R2_GLOBALS._sceneManager.changeScene(1200);
break;
@@ -1407,7 +1407,7 @@ void Scene3260::postInit(SceneObjectList *OwnerList) {
_actor13.setPosition(Common::Point(40, 106));
_actor13.setDetails(3260, 18, 1, -1, 1, (SceneItem *)NULL);
- if (R2_INVENTORY.getObjectScene(52) == 3260) {
+ if (R2_INVENTORY.getObjectScene(R2_TOOLBOX) == 3260) {
_actor14.postInit();
_actor14.setup(3260, 7, 1);
_actor14.setPosition(Common::Point(202, 66));
@@ -1524,8 +1524,8 @@ void Scene3260::signal() {
R2_GLOBALS._events.setCursor(CURSOR_CROSSHAIRS);
SceneItem::display(3260, 15, 0, 280, 1, 160, 9, 1, 2, 20, 7, 154, -999);
R2_GLOBALS._player.disableControl();
- R2_INVENTORY.setObjectScene(52, 3);
- R2_INVENTORY.setObjectScene(43, 3);
+ R2_INVENTORY.setObjectScene(R2_TOOLBOX, 3);
+ R2_INVENTORY.setObjectScene(R2_LASER_HACKSAW, 3);
setAction(&_sequenceManager, this, 3273, &R2_GLOBALS._player, &_actor14, NULL);
break;
case 3273:
@@ -2771,7 +2771,7 @@ void Scene3400::signal() {
_actor2.setStrip(6);
_actor3.setStrip(3);
_actor4.setStrip(1);
- R2_INVENTORY.setObjectScene(34, 0);
+ R2_INVENTORY.setObjectScene(R2_SAPPHIRE_BLUE, 0);
_stripManager.start(3307, this);
if (R2_GLOBALS._player._characterIndex == 2) {
_sceneMode = 3400;
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.cpp b/engines/tsage/ringworld2/ringworld2_speakers.cpp
index cd2ff669ff..e7109829b0 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.cpp
+++ b/engines/tsage/ringworld2/ringworld2_speakers.cpp
@@ -204,13 +204,12 @@ void VisualSpeaker::setText(const Common::String &msg) {
_sceneText._textMode = _textMode;
_sceneText.setup(s);
- //_sceneText.clone();
-
_sceneText.setPosition(_textPos);
_sceneText.fixPriority(256);
// If subtitles are turned off, don't show the text
- if (!(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
+ if ((R2_GLOBALS._speechSubtitles & SPEECH_VOICE) &&
+ !(R2_GLOBALS._speechSubtitles & SPEECH_TEXT)) {
_sceneText.hide();
}
@@ -360,7 +359,7 @@ void SpeakerChief1100::proc15() {
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
if (!_object2) {
- _object2 = &scene->_actor18;
+ _object2 = &scene->_chief;
_object2->hide();
_object1.postInit();
_object1.setPosition(_object2->_position);
@@ -1180,6 +1179,7 @@ void SpeakerQuinn300::proc15() {
if (R2_GLOBALS._player._characterIndex == 3) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 300);
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_quinn;
}
@@ -1220,6 +1220,51 @@ void SpeakerQuinn300::proc15() {
}
}
+void SpeakerQuinn500::proc15() {
+ int v = _speakerMode;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == R2_QUINN) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 500);
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_seeker;
+ }
+
+ _object2->hide();
+
+ _object1.postInit();
+ _object1._effect = _object2->_effect;
+ _object1._shade = _object2->_shade;
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ switch (_object2->_visage) {
+ case 10:
+ _object1.setup(4021, (v == 1) ? 5 : 7, 1);
+ break;
+
+ case 1500:
+ _object1.setup(4021, (v == 1) ? 1 : 3, 1);
+ break;
+
+ default:
+ break;
+ }
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
void SpeakerQuinn1100::proc15() {
int v = _speakerMode;
@@ -1230,8 +1275,9 @@ void SpeakerQuinn1100::proc15() {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1100);
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor16;
+ _object2 = &scene->_seeker;
}
_object2->hide();
@@ -1275,6 +1321,7 @@ void SpeakerQuinn2435::proc15() {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -1301,6 +1348,7 @@ void SpeakerQuinn2450::proc15() {
if (R2_GLOBALS._player._characterIndex == 1) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -1948,9 +1996,9 @@ void SpeakerSeeker300::proc15() {
int v = _speakerMode;
if (!_object2) {
- if (R2_GLOBALS._player._characterIndex == 2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
_object2 = &R2_GLOBALS._player;
- } else {
+ } else {assert(R2_GLOBALS._sceneManager._sceneNumber == 300);
Scene300 *scene = (Scene300 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_seeker;
}
@@ -1980,6 +2028,43 @@ void SpeakerSeeker300::proc15() {
}
}
+void SpeakerSeeker500::proc15() {
+ int v = _speakerMode;
+
+ if (!_object2) {
+ if (R2_GLOBALS._player._characterIndex == R2_SEEKER) {
+ _object2 = &R2_GLOBALS._player;
+ } else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 500);
+ Scene500 *scene = (Scene500 *)R2_GLOBALS._sceneManager._scene;
+ _object2 = &scene->_seeker;
+ }
+
+ _object2->hide();
+ _object1.postInit();
+
+ _object1._effect = _object2->_effect;
+ _object1._shade = _object2->_shade;
+ _object1.setPosition(_object2->_position);
+
+ if (_object2->_mover)
+ _object2->addMover(NULL);
+ }
+
+ if (v == 0) {
+ _object1.animate(ANIM_MODE_2, NULL);
+ } else {
+ ((SceneItem *)_action)->_sceneRegionId = 0;
+
+ if (v == 1)
+ _object1.setup(4041, 3, 1);
+ else
+ _object1.setup(4041, 1, 1);
+
+ _object1.animate(ANIM_MODE_5, this);
+ }
+}
+
void SpeakerSeeker1100::proc15() {
int v = _speakerMode;
@@ -1990,8 +2075,9 @@ void SpeakerSeeker1100::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1100);
Scene1100 *scene = (Scene1100 *)R2_GLOBALS._sceneManager._scene;
- _object2 = &scene->_actor16;
+ _object2 = &scene->_seeker;
}
_object2->hide();
@@ -2046,6 +2132,7 @@ void SpeakerSeeker1900::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 1900);
Scene1900 *scene = (Scene1900 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -2076,6 +2163,7 @@ void SpeakerSeeker2435::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2435);
Scene2435 *scene = (Scene2435 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -2102,6 +2190,7 @@ void SpeakerSeeker2450::proc15() {
if (R2_GLOBALS._player._characterIndex == 2) {
_object2 = &R2_GLOBALS._player;
} else {
+ assert(R2_GLOBALS._sceneManager._sceneNumber == 2450);
Scene2450 *scene = (Scene2450 *)R2_GLOBALS._sceneManager._scene;
_object2 = &scene->_actor1;
}
@@ -2492,9 +2581,9 @@ void SpeakerSocko3200::proc15() {
// Classes related to SOLDIER
//----------------------------------------------------------------------------
-SpeakerSoldier::SpeakerSoldier(int colour) {
+SpeakerSoldier::SpeakerSoldier(int color) {
_speakerName = "SOLDIER";
- _color1 = colour;
+ _color1 = color;
_color2 = 0;
_speakerMode = 0;
_textWidth = 300;
@@ -2788,9 +2877,9 @@ void SpeakerTomko3245::proc15() {
// Classes related to WEBBSTER
//----------------------------------------------------------------------------
-SpeakerWebbster::SpeakerWebbster(int colour) {
+SpeakerWebbster::SpeakerWebbster(int color) {
_speakerName = "WEBBSTER";
- _color1 = colour;
+ _color1 = color;
_color2 = 0;
_speakerMode = 0;
_textWidth = 300;
diff --git a/engines/tsage/ringworld2/ringworld2_speakers.h b/engines/tsage/ringworld2/ringworld2_speakers.h
index 532e02576c..4dfb500f2d 100644
--- a/engines/tsage/ringworld2/ringworld2_speakers.h
+++ b/engines/tsage/ringworld2/ringworld2_speakers.h
@@ -282,6 +282,12 @@ public:
virtual void proc15();
};
+class SpeakerQuinn500 : public SpeakerQuinn {
+public:
+ virtual Common::String getClassName() { return "SpeakerQuinn500"; }
+ virtual void proc15();
+};
+
class SpeakerQuinn1100 : public SpeakerQuinn {
public:
virtual Common::String getClassName() { return "SpeakerQuinn1100"; }
@@ -420,6 +426,12 @@ public:
virtual void proc15();
};
+class SpeakerSeeker500 : public SpeakerSeeker {
+public:
+ virtual Common::String getClassName() { return "SpeakerSeeker500"; }
+ virtual void proc15();
+};
+
class SpeakerSeeker1100 : public SpeakerSeeker {
public:
virtual Common::String getClassName() { return "SpeakerSeeker1100"; }
@@ -504,7 +516,7 @@ public:
class SpeakerSoldier : public VisualSpeaker {
public:
- SpeakerSoldier(int colour);
+ SpeakerSoldier(int color);
virtual Common::String getClassName() { return "SpeakerSoldier"; }
};
@@ -579,7 +591,7 @@ public:
class SpeakerWebbster : public VisualSpeaker {
public:
- SpeakerWebbster(int colour);
+ SpeakerWebbster(int color);
virtual Common::String getClassName() { return "SpeakerWebbster"; }
};
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index a273ec2a0b..db38862365 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -244,7 +244,7 @@ char const *const USE_INTERCEPTOR = "Do you want to use your interceptor card?";
char const *const USE_DOUBLE_AGENT = "Do you want to use your double agent?";
char const *const NEED_INSTRUCTIONS = "Do you want instructions?";
char const *const WRONG_ANSWER_MSG = "Wrong respond value sent.";
-const byte k562CC[] = {
+const byte scene1550JunkLocationsDefault[] = {
20, 7, 41, 6,
3, 6, 42, 11,
10, 15, 43, 6,
@@ -374,7 +374,7 @@ const byte k562CC[] = {
28, 18, 21, 1
};
-const byte k5A4D6[] = {
+const byte scene1550AreaMap[] = {
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18,
17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
@@ -409,7 +409,7 @@ const byte k5A76D[] = {
3, 3, 3, 7, 3, 7, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3
};
-const byte k5A78A[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
+const byte scene1550JunkRegions[] = {0, 8, 15, 16, 12, 7, 18, 17, 13, 6, 19, 20, 14, 5, 11, 10, 9};
const byte k5A79B[] = {
23, 3, 1,
23, 4, 1,
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index e3daf73333..8c21147191 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -199,13 +199,13 @@ extern char const *const NEED_INSTRUCTIONS;
extern char const *const WRONG_ANSWER_MSG;
// Scene 1550 arrays of constants
-extern const byte k562CC[];
-extern const byte k5A4D6[];
+extern const byte scene1550JunkLocationsDefault[];
+extern const byte scene1550AreaMap[];
extern const byte k5A72E[];
extern const byte k5A73F[];
extern const byte k5A750[];
extern const byte k5A76D[];
-extern const byte k5A78A[];
+extern const byte scene1550JunkRegions[];
extern const byte k5A79B[];
extern const byte k5A7F6[];
diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp
index c0ebb804d2..09cc2fd56d 100644
--- a/engines/tsage/user_interface.cpp
+++ b/engines/tsage/user_interface.cpp
@@ -454,7 +454,7 @@ void UIElements::add(UIElement *obj) {
/**
* Handles updating the visual inventory in the user interface
*/
-void UIElements::updateInventory() {
+void UIElements::updateInventory(int objectNumber) {
switch (g_vm->getGameID()) {
case GType_BlueForce:
// Update the score
@@ -483,6 +483,17 @@ void UIElements::updateInventory() {
else if (_slotStart > (lastPage - 1))
_slotStart = 0;
+ // Handle changing the page, if necessary, to ensure an optionally supplied
+ // object number will be on-screen
+ if (objectNumber != 0) {
+ for (uint idx = 0; idx < _itemList.size(); ++idx) {
+ if (_itemList[idx] == objectNumber) {
+ _slotStart = idx / 4;
+ break;
+ }
+ }
+ }
+
// Handle refreshing slot graphics
UIInventorySlot *slotList[4] = { &_slot1, &_slot2, &_slot3, &_slot4 };
diff --git a/engines/tsage/user_interface.h b/engines/tsage/user_interface.h
index 0fbfc5a00f..d06dccd9a4 100644
--- a/engines/tsage/user_interface.h
+++ b/engines/tsage/user_interface.h
@@ -137,7 +137,7 @@ public:
virtual void process(Event &event);
void setup(const Common::Point &pt);
- void updateInventory();
+ void updateInventory(int objectNumber = 0);
void addScore(int amount);
void scrollInventory(bool isLeft);
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index 3059a69047..e073f27970 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -272,7 +272,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
// void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
Graphics::Surface *surface = new Graphics::Surface();
if (_deletableFont) { // We actually have a TTF
- surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+ surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), _gameRef->_renderer->getPixelFormat());
} else { // We are using a fallback, they can't do 32bpp
surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
}
@@ -285,7 +285,7 @@ BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width,
}
BaseSurface *retSurface = _gameRef->_renderer->createSurface();
- Graphics::Surface *convertedSurface = surface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+ Graphics::Surface *convertedSurface = surface->convertTo(_gameRef->_renderer->getPixelFormat());
retSurface->putSurface(*convertedSurface, true);
convertedSurface->free();
surface->free();
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index b16cf60752..e6d769c653 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -84,7 +84,6 @@ BaseRenderOSystem::~BaseRenderOSystem() {
delete _renderSurface;
_blankSurface->free();
delete _blankSurface;
- TransparentSurface::destroyLookup();
}
//////////////////////////////////////////////////////////////////////////
@@ -127,7 +126,7 @@ bool BaseRenderOSystem::initRenderer(int width, int height, bool windowed) {
_windowed = !ConfMan.getBool("fullscreen");
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
g_system->beginGFXTransaction();
g_system->initSize(_width, _height, &format);
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
@@ -613,8 +612,8 @@ bool BaseRenderOSystem::setViewport(int left, int top, int right, int bottom) {
// TODO: Hopefully this is the same logic that ScummVM uses.
rect.left = (int16)(left + _borderLeft);
rect.top = (int16)(top + _borderTop);
- rect.right = (int16)((right - left) * _ratioX);
- rect.bottom = (int16)((bottom - top) * _ratioY);
+ rect.setWidth((int16)((right - left) * _ratioX));
+ rect.setHeight((int16)((bottom - top) * _ratioY));
_renderRect = rect;
return STATUS_OK;
@@ -631,15 +630,13 @@ Rect32 BaseRenderOSystem::getViewPort() {
//////////////////////////////////////////////////////////////////////////
void BaseRenderOSystem::modTargetRect(Common::Rect *rect) {
- // FIXME: This is wrong in quite a few ways right now, and ends up
- // breaking the notebook in Dirty Split, so we disable the correction
- // for now, this will need fixing when a game with odd aspect-ratios
- // show up.
return;
- rect->left = (int16)MathUtil::round(rect->left * _ratioX + _borderLeft - _renderRect.left);
- rect->top = (int16)MathUtil::round(rect->top * _ratioY + _borderTop - _renderRect.top);
- rect->setWidth((int16)MathUtil::roundUp(rect->width() * _ratioX));
- rect->setHeight((int16)MathUtil::roundUp(rect->height() * _ratioY));
+ int newWidth = (int16)MathUtil::roundUp(rect->width() * _ratioX);
+ int newHeight = (int16)MathUtil::roundUp(rect->height() * _ratioY);
+ rect->left = (int16)MathUtil::round(rect->left * _ratioX + _borderLeft);
+ rect->top = (int16)MathUtil::round(rect->top * _ratioY + _borderTop);
+ rect->setWidth(newWidth);
+ rect->setHeight(newHeight);
}
//////////////////////////////////////////////////////////////////////////
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index d4c5905c4b..14767aa067 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -48,7 +48,7 @@ namespace Wintermute {
BaseSurfaceOSystem::BaseSurfaceOSystem(BaseGame *inGame) : BaseSurface(inGame) {
_surface = new Graphics::Surface();
_alphaMask = nullptr;
- _hasAlpha = true;
+ _alphaType = TransparentSurface::ALPHA_FULL;
_lockPixels = nullptr;
_lockPitch = 0;
_loaded = false;
@@ -71,22 +71,37 @@ BaseSurfaceOSystem::~BaseSurfaceOSystem() {
renderer->invalidateTicketsFromSurface(this);
}
-bool hasTransparency(Graphics::Surface *surf) {
+TransparentSurface::AlphaType hasTransparencyType(const Graphics::Surface *surf) {
if (surf->format.bytesPerPixel != 4) {
- warning("hasTransparency:: non 32 bpp surface passed as argument");
- return false;
+ warning("hasTransparencyType:: non 32 bpp surface passed as argument");
+ return TransparentSurface::ALPHA_OPAQUE;
}
uint8 r, g, b, a;
+ bool seenAlpha = false;
+ bool seenFullAlpha = false;
for (int i = 0; i < surf->h; i++) {
+ if (seenFullAlpha) {
+ break;
+ }
for (int j = 0; j < surf->w; j++) {
- uint32 pix = *(uint32 *)surf->getBasePtr(j, i);
+ uint32 pix = *(const uint32 *)surf->getBasePtr(j, i);
surf->format.colorToARGB(pix, a, r, g, b);
if (a != 255) {
- return true;
+ seenAlpha = true;
+ if (a != 0) {
+ seenFullAlpha = true;
+ break;
+ }
}
}
}
- return false;
+ if (seenFullAlpha) {
+ return TransparentSurface::ALPHA_FULL;
+ } else if (seenAlpha) {
+ return TransparentSurface::ALPHA_BINARY;
+ } else {
+ return TransparentSurface::ALPHA_OPAQUE;
+ }
}
//////////////////////////////////////////////////////////////////////////
@@ -128,39 +143,36 @@ bool BaseSurfaceOSystem::finishLoad() {
_width = image->getSurface()->w;
_height = image->getSurface()->h;
- bool isSaveGameGrayscale = scumm_strnicmp(_filename.c_str(), "savegame:", 9) == 0 && (_filename.c_str()[_filename.size() - 1] == 'g' || _filename.c_str()[_filename.size() - 1] == 'G');
+ bool isSaveGameGrayscale = _filename.matchString("savegame:*g", true);
if (isSaveGameGrayscale) {
warning("grayscaleConversion not yet implemented");
// FIBITMAP *newImg = FreeImage_ConvertToGreyscale(img); TODO
}
- // no alpha, set color key
- /* if (surface->format.bytesPerPixel != 4)
- SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf->format, ck_red, ck_green, ck_blue));*/
-
- // convert 32-bit BMPs to 24-bit or they appear totally transparent (does any app actually write alpha in BMP properly?)
- // Well, actually, we don't convert via 24-bit as the color-key application overwrites the Alpha-channel anyhow.
_surface->free();
delete _surface;
bool needsColorKey = false;
bool replaceAlpha = true;
- if (_filename.hasSuffix(".bmp") && image->getSurface()->format.bytesPerPixel == 4) {
- _surface = image->getSurface()->convertTo(g_system->getScreenFormat(), image->getPalette());
- needsColorKey = true;
- replaceAlpha = false;
- } else if (image->getSurface()->format.bytesPerPixel == 1 && image->getPalette()) {
+ if (image->getSurface()->format.bytesPerPixel == 1) {
+ if (!image->getPalette()) {
+ error("Missing palette while loading 8bit image %s", _filename.c_str());
+ }
_surface = image->getSurface()->convertTo(g_system->getScreenFormat(), image->getPalette());
needsColorKey = true;
- } else if (image->getSurface()->format.bytesPerPixel >= 3 && image->getSurface()->format != g_system->getScreenFormat()) {
- _surface = image->getSurface()->convertTo(g_system->getScreenFormat());
- if (image->getSurface()->format.bytesPerPixel == 3) {
- needsColorKey = true;
- }
} else {
- _surface = new Graphics::Surface();
- _surface->copyFrom(*image->getSurface());
- if (_surface->format.aBits() == 0) {
+ if (image->getSurface()->format != g_system->getScreenFormat()) {
+ _surface = image->getSurface()->convertTo(g_system->getScreenFormat());
+ } else {
+ _surface = new Graphics::Surface();
+ _surface->copyFrom(*image->getSurface());
+ }
+
+ if (_filename.hasSuffix(".bmp") && image->getSurface()->format.bytesPerPixel == 4) {
+ // 32 bpp BMPs have nothing useful in their alpha-channel -> color-key
+ needsColorKey = true;
+ replaceAlpha = false;
+ } else if (image->getSurface()->format.aBits() == 0) {
needsColorKey = true;
}
}
@@ -170,7 +182,7 @@ bool BaseSurfaceOSystem::finishLoad() {
trans.applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha);
}
- _hasAlpha = hasTransparency(_surface);
+ _alphaType = hasTransparencyType(_surface);
_valid = true;
_gameRef->addMem(_width * _height * 4);
@@ -409,8 +421,6 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
if (newRect) {
position.top = y;
position.left = x;
- position.right = x + newRect->width();
- position.bottom = y + newRect->height();
position.setWidth(newRect->width());
position.setHeight(newRect->height());
} else {
@@ -422,17 +432,11 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
// TODO: This actually requires us to have the SAME source-offsets every time,
// But no checking is in place for that yet.
- // TODO: Optimize by not doing alpha-blits if we lack or disable alpha
-
- bool hasAlpha = false;
-
- if (_hasAlpha && !transform._alphaDisable) {
- hasAlpha = true;
- }
-
- if (transform._alphaDisable) {
- warning("BaseSurfaceOSystem::drawSprite - AlphaDisable ignored");
+ // Optimize by not doing alpha-blits if we lack alpha
+ if (_alphaType == TransparentSurface::ALPHA_OPAQUE && !transform._alphaDisable) {
+ transform._alphaDisable = true;
}
+
renderer->drawSurface(this, _surface, &srcRect, &position, transform);
return STATUS_OK;
}
@@ -447,7 +451,11 @@ bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAl
_loaded = true;
_surface->free();
_surface->copyFrom(surface);
- _hasAlpha = hasAlpha;
+ if (hasAlpha) {
+ _alphaType = TransparentSurface::ALPHA_FULL;
+ } else {
+ _alphaType = TransparentSurface::ALPHA_OPAQUE;
+ }
BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
renderer->invalidateTicketsFromSurface(this);
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index da86833517..6cf19d00fb 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -30,6 +30,7 @@
#define WINTERMUTE_BASE_SURFACESDL_H
#include "graphics/surface.h"
+#include "engines/wintermute/graphics/transparent_surface.h"
#include "engines/wintermute/base/gfx/base_surface.h"
#include "common/list.h"
@@ -81,6 +82,7 @@ public:
return _height;
}
+ TransparentSurface::AlphaType getAlphaType() const { return _alphaType; }
private:
Graphics::Surface *_surface;
bool _loaded;
@@ -90,7 +92,7 @@ private:
uint32 getPixelAt(Graphics::Surface *surface, int x, int y);
uint32 _rotation;
- bool _hasAlpha;
+ TransparentSurface::AlphaType _alphaType;
void *_lockPixels;
int _lockPitch;
byte *_alphaMask;
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index 98739e0778..b1720c1b0b 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -28,6 +28,7 @@
#include "engines/wintermute/base/gfx/osystem/render_ticket.h"
+#include "engines/wintermute/base/gfx/osystem/base_surface_osystem.h"
#include "engines/wintermute/graphics/transform_tools.h"
#include "common/textconsole.h"
@@ -104,7 +105,13 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
clipRect.setWidth(getSurface()->w);
clipRect.setHeight(getSurface()->h);
- src._enableAlphaBlit = !_transform._alphaDisable;
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ } else {
+ src._alphaMode = _owner->getAlphaType();
+ }
+ }
src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
}
@@ -118,7 +125,13 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
clipRect->setHeight(getSurface()->h);
}
- src._enableAlphaBlit = !_transform._alphaDisable;
+ if (_owner) {
+ if (_transform._alphaDisable) {
+ src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
+ } else {
+ src._alphaMode = _owner->getAlphaType();
+ }
+ }
src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height());
if (doDelete) {
delete clipRect;
diff --git a/engines/wintermute/detection_tables.h b/engines/wintermute/detection_tables.h
index 702c0b28ba..63f5078c12 100644
--- a/engines/wintermute/detection_tables.h
+++ b/engines/wintermute/detection_tables.h
@@ -40,16 +40,20 @@ static const PlainGameDescriptor wintermuteGames[] = {
{"dreaming", "Des Reves Elastiques Avec Mille Insectes Nommes Georges"},
{"dirtysplit", "Dirty Split"},
{"dreamscape", "Dreamscape"},
+ {"escapemansion", "Escape from the Mansion"},
{"ghostsheet", "Ghost in the Sheet"},
{"hamlet", "Hamlet or the last game without MMORPS features, shaders and product placement"},
{"jamesperis", "James Peris: No License Nor Control"},
+ {"looky", "Looky"},
{"julia", "J.U.L.I.A."},
{"mirage", "Mirage"},
{"pigeons", "Pigeons in the Park"},
{"reversion1", "Reversion: The Escape"},
{"reversion2", "Reversion: The Meeting"},
{"rosemary", "Rosemary"},
+ {"shaban", "Shaban"},
{"shinestar", "The Shine of a Star"},
+ {"spacemadness", "Space Madness"},
{"thebox", "The Box"},
{"tib", "Fairy Tales About Toshechka and Boshechka"},
{"tradestory", "The Trader of Stories"},
@@ -284,6 +288,26 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Escape from the Mansion
+ {
+ "escapemansion",
+ "Beta 1",
+ AD_ENTRY1s("data.dcp", "d8e348b2312cc36a929cad75f12e0b3a", 21452380),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Escape from the Mansion
+ {
+ "escapemansion",
+ "Beta 2",
+ AD_ENTRY1s("data.dcp", "ded5fa6c5f2afdaf2cafb53e52cd3dd8", 21455763),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Ghosts in the Sheet
{
"ghostsheet",
@@ -379,6 +403,48 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_DEMO,
GUIO0()
},
+ // Looky Demo (English)
+ {
+ "looky",
+ "Demo",
+ {
+ {"english.dcp", 0, "1388e1dd320f4d553dea3b0316812f9d", 1358442},
+ {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Looky Demo (German)
+ {
+ "looky",
+ "Demo",
+ {
+ {"german.dcp", 0, "606c048426dfbe94442b59fd34a5c76e", 14339496},
+ {"data.dcp", 0, "7074bcd7bc7ad7eb04c271aafb964c32", 13815660},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+ // Looky (German)
+ {
+ "looky",
+ "",
+ {
+ {"german.dcp", 0, "bf4c2b8c26342342441a6d64934ab832", 107027865},
+ {"data.dcp", 0, "50de0beaa5ad621aa9f020df901d1e74", 1342214},
+ AD_LISTEND
+ },
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// Mirage
{
"mirage",
@@ -625,6 +691,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Shaban
+ {
+ "shaban",
+ "",
+ AD_ENTRY1s("data.dcp", "35f702ca9baabc5c620e0be230195c8a", 755388466),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// The Shine of a Star
{
"shinestar",
@@ -635,6 +711,16 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_UNSTABLE,
GUIO0()
},
+ // Space Madness
+ {
+ "spacemadness",
+ "1.0.2",
+ AD_ENTRY1s("data.dcp", "b9b83135dc7a9e1b4b5f50195dbeb630", 39546622),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
// The Box
{
"thebox",
diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp
index df6286e37a..cd200354f7 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -140,16 +140,9 @@ void TransparentSurface::copyPixelNearestNeighbor(float projX, float projY, int
}
#endif
-byte *TransparentSurface::_lookup = nullptr;
+TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
-void TransparentSurface::destroyLookup() {
- delete[] _lookup;
- _lookup = nullptr;
-}
-
-TransparentSurface::TransparentSurface() : Surface(), _enableAlphaBlit(true) {}
-
-TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _enableAlphaBlit(true) {
+TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _alphaMode(ALPHA_FULL) {
if (copyData) {
copyFrom(surf);
} else {
@@ -168,9 +161,9 @@ void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pit
byte *in, *out;
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
-#else
const int aIndex = 0;
+#else
+ const int aIndex = 3;
#endif
for (uint32 i = 0; i < height; i++) {
@@ -186,42 +179,60 @@ void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pit
}
}
-void TransparentSurface::generateLookup() {
- _lookup = new byte[256 * 256];
- for (int i = 0; i < 256; i++) {
- for (int j = 0; j < 256; j++) {
- _lookup[(i << 8) + j] = (i * j) >> 8;
+void doBlitBinary(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+ byte *in, *out;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ const int aIndex = 0;
+#else
+ const int aIndex = 3;
+#endif
+ const int aShift = 0;//img->format.aShift;
+
+ for (uint32 i = 0; i < height; i++) {
+ out = outo;
+ in = ino;
+ for (uint32 j = 0; j < width; j++) {
+ uint32 pix = *(uint32 *)in;
+ int a = (pix >> aShift) & 0xff;
+ in += inStep;
+
+ if (a == 0) { // Full transparency
+ out += 4;
+ } else { // Full opacity (Any value not exactly 0 is Opaque here)
+ *(uint32 *)out = pix;
+ out[aIndex] = 0xFF;
+ out += 4;
+ }
}
+ outo += pitch;
+ ino += inoStep;
}
}
-void TransparentSurface::doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+void doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
byte *in, *out;
- if (!_lookup) {
- generateLookup();
- }
-
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
- const int bIndex = 0;
- const int gIndex = 1;
- const int rIndex = 2;
-#else
const int aIndex = 0;
- const int bIndex = 3;
+ const int bIndex = 1;
const int gIndex = 2;
- const int rIndex = 1;
+ const int rIndex = 3;
+#else
+ const int aIndex = 3;
+ const int bIndex = 2;
+ const int gIndex = 1;
+ const int rIndex = 0;
#endif
- const int bShift = 0;//img->format.bShift;
- const int gShift = 8;//img->format.gShift;
- const int rShift = 16;//img->format.rShift;
- const int aShift = 24;//img->format.aShift;
+ const int bShift = 8;//img->format.bShift;
+ const int gShift = 16;//img->format.gShift;
+ const int rShift = 24;//img->format.rShift;
+ const int aShift = 0;//img->format.aShift;
- const int bShiftTarget = 0;//target.format.bShift;
- const int gShiftTarget = 8;//target.format.gShift;
- const int rShiftTarget = 16;//target.format.rShift;
+ const int bShiftTarget = 8;//target.format.bShift;
+ const int gShiftTarget = 16;//target.format.gShift;
+ const int rShiftTarget = 24;//target.format.rShift;
for (uint32 i = 0; i < height; i++) {
out = outo;
@@ -255,13 +266,9 @@ void TransparentSurface::doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32
default: // alpha blending
outa = 255;
-
- outb = _lookup[(((oPix >> bShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outg = _lookup[(((oPix >> gShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outr = _lookup[(((oPix >> rShiftTarget) & 0xff)) + ((255 - a) << 8)];
- outb += _lookup[b + (a << 8)];
- outg += _lookup[g + (a << 8)];
- outr += _lookup[r + (a << 8)];
+ outb = ((b * a) + ((oPix >> bShiftTarget) & 0xff) * (255-a)) >> 8;
+ outg = ((g * a) + ((oPix >> gShiftTarget) & 0xff) * (255-a)) >> 8;
+ outr = ((r * a) + ((oPix >> rShiftTarget) & 0xff) * (255-a)) >> 8;
out[aIndex] = outa;
out[bIndex] = outb;
@@ -292,14 +299,6 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
int cg = (color >> 8) & 0xff;
int cb = (color >> 0) & 0xff;
- // Compensate for transparency. Since we're coming
- // down to 255 alpha, we just compensate for the colors here
- if (ca != 255) {
- cr = cr * ca >> 8;
- cg = cg * ca >> 8;
- cb = cb * ca >> 8;
- }
-
// Create an encapsulating surface for the data
TransparentSurface srcImage(*this, false);
// TODO: Is the data really in the screen format?
@@ -309,7 +308,19 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
}
if (pPartRect) {
- srcImage.pixels = getBasePtr(pPartRect->left, pPartRect->top);
+
+ int xOffset = pPartRect->left;
+ int yOffset = pPartRect->top;
+
+ if (flipping & FLIP_V) {
+ yOffset = srcImage.h - pPartRect->bottom;
+ }
+
+ if (flipping & FLIP_H) {
+ xOffset = srcImage.w - pPartRect->right;
+ }
+
+ srcImage.pixels = getBasePtr(xOffset, yOffset);
srcImage.w = pPartRect->width();
srcImage.h = pPartRect->height();
@@ -379,29 +390,32 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
byte *in, *out;
#ifdef SCUMM_LITTLE_ENDIAN
- const int aIndex = 3;
- const int bIndex = 0;
- const int gIndex = 1;
- const int rIndex = 2;
-#else
const int aIndex = 0;
- const int bIndex = 3;
+ const int bIndex = 1;
const int gIndex = 2;
- const int rIndex = 1;
+ const int rIndex = 3;
+#else
+ const int aIndex = 3;
+ const int bIndex = 2;
+ const int gIndex = 1;
+ const int rIndex = 0;
#endif
- const int bShift = 0;//img->format.bShift;
- const int gShift = 8;//img->format.gShift;
- const int rShift = 16;//img->format.rShift;
- const int aShift = 24;//img->format.aShift;
- const int bShiftTarget = 0;//target.format.bShift;
- const int gShiftTarget = 8;//target.format.gShift;
- const int rShiftTarget = 16;//target.format.rShift;
+ const int bShift = 8;//img->format.bShift;
+ const int gShift = 16;//img->format.gShift;
+ const int rShift = 24;//img->format.rShift;
+ const int aShift = 0;//img->format.aShift;
+
+ const int bShiftTarget = 8;//target.format.bShift;
+ const int gShiftTarget = 16;//target.format.gShift;
+ const int rShiftTarget = 24;//target.format.rShift;
if (ca == 255 && cb == 255 && cg == 255 && cr == 255) {
- if (_enableAlphaBlit) {
+ if (_alphaMode == ALPHA_FULL) {
doBlitAlpha(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
- } else {
+ } else if (_alphaMode == ALPHA_BINARY) {
+ doBlitBinary(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+ } else if (_alphaMode == ALPHA_OPAQUE) {
doBlitOpaque(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
}
} else {
@@ -421,7 +435,6 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
if (ca != 255) {
a = a * ca >> 8;
}
-
switch (a) {
case 0: // Full transparency
out += 4;
@@ -451,27 +464,27 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
default: // alpha blending
outa = 255;
- outb = (o_pix >> bShiftTarget) & 0xff;
- outg = (o_pix >> gShiftTarget) & 0xff;
- outr = (o_pix >> rShiftTarget) & 0xff;
+ outb = ((o_pix >> bShiftTarget) & 0xff) * (255 - a);
+ outg = ((o_pix >> gShiftTarget) & 0xff) * (255 - a);
+ outr = ((o_pix >> rShiftTarget) & 0xff) * (255 - a);
if (cb == 0)
- outb = 0;
+ outb = outb >> 8;
else if (cb != 255)
- outb += ((b - outb) * a * cb) >> 16;
+ outb = ((outb<<8) + b * a * cb) >> 16;
else
- outb += ((b - outb) * a) >> 8;
+ outb = (outb + b * a) >> 8;
if (cg == 0)
- outg = 0;
+ outg = outg >> 8;
else if (cg != 255)
- outg += ((g - outg) * a * cg) >> 16;
+ outg = ((outg<<8) + g * a * cg) >> 16;
else
- outg += ((g - outg) * a) >> 8;
+ outg = (outg + g * a) >> 8;
if (cr == 0)
- outr = 0;
+ outr = outr >> 8;
else if (cr != 255)
- outr += ((r - outr) * a * cr) >> 16;
+ outr = ((outr<<8) + r * a * cr) >> 16;
else
- outr += ((r - outr) * a) >> 8;
+ outr = (outr + r * a) >> 8;
out[aIndex] = outa;
out[bIndex] = outb;
out[gIndex] = outg;
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
index 9d06f3e006..598aaa55d7 100644
--- a/engines/wintermute/graphics/transparent_surface.h
+++ b/engines/wintermute/graphics/transparent_surface.h
@@ -75,7 +75,13 @@ struct TransparentSurface : public Graphics::Surface {
FLIP_VH = FLIP_H | FLIP_V
};
- bool _enableAlphaBlit;
+ enum AlphaType {
+ ALPHA_OPAQUE = 0,
+ ALPHA_BINARY = 1,
+ ALPHA_FULL = 2
+ };
+
+ AlphaType _alphaMode;
/**
@brief renders the surface to another surface
@@ -114,11 +120,6 @@ struct TransparentSurface : public Graphics::Surface {
TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const;
TransparentSurface *rotoscale(const TransformStruct &transform) const;
- static byte *_lookup;
- static void destroyLookup();
-private:
- static void doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
- static void generateLookup();
};
/**
diff --git a/engines/wintermute/utils/string_util.cpp b/engines/wintermute/utils/string_util.cpp
index 23abb5d579..e8e078aba8 100644
--- a/engines/wintermute/utils/string_util.cpp
+++ b/engines/wintermute/utils/string_util.cpp
@@ -146,26 +146,21 @@ Utf8String StringUtil::wideToUtf8(const WideString &WideStr) {
return "";
}
-// Currently this only does Ansi->ISO 8859, and only for carets.
-char simpleAnsiToWide(const AnsiString &str, uint32 &offset) {
- byte c = str[offset];
-
- if (c == 146) {
- offset++;
- return 39; // Replace right-quote with apostrophe
- } else {
- offset++;
- return c;
- }
-}
-
//////////////////////////////////////////////////////////////////////////
WideString StringUtil::ansiToWide(const AnsiString &str) {
// TODO: This function gets called a lot, so warnings like these drown out the usefull information
Common::String converted = "";
uint32 index = 0;
while (index != str.size()) {
- converted += simpleAnsiToWide(str, index);
+ byte c = str[index];
+ if (c == 146) {
+ converted += (char)39; // Replace right-quote with apostrophe
+ } else if (c == 133) {
+ converted += Common::String("..."); // Replace ...-symbol with ...
+ } else {
+ converted += c;
+ }
+ index++;
}
// using default os locale!
diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp
index a878944661..0a6be4caf8 100644
--- a/engines/wintermute/wintermute.cpp
+++ b/engines/wintermute/wintermute.cpp
@@ -105,7 +105,7 @@ bool WintermuteEngine::hasFeature(EngineFeature f) const {
Common::Error WintermuteEngine::run() {
// Initialize graphics using following:
- Graphics::PixelFormat format(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
initGraphics(800, 600, true, &format);
if (g_system->getScreenFormat() != format) {
error("Wintermute currently REQUIRES 32bpp");
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index 5d6369c08f..8e1c5e91e1 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -73,6 +73,8 @@ struct DrawStep {
uint8 shadow, stroke, factor, radius, bevel; /**< Misc options... */
uint8 fillMode; /**< active fill mode */
+ uint8 shadowFillMode; /**< fill mode of the shadow used */
+
uint32 extraData; /**< Generic parameter for extra options (orientation/bevel) */
uint32 scale; /**< scale of all the coordinates in FIXED POINT with 16 bits mantissa */
@@ -103,7 +105,7 @@ VectorRenderer *createRenderer(int mode);
*/
class VectorRenderer {
public:
- VectorRenderer() : _activeSurface(NULL), _fillMode(kFillDisabled), _shadowOffset(0),
+ VectorRenderer() : _activeSurface(NULL), _fillMode(kFillDisabled), _shadowOffset(0), _shadowFillMode(kShadowExponential),
_disableShadows(false), _strokeWidth(1), _gradientFactor(1) {
}
@@ -126,6 +128,11 @@ public:
kTriangleRight
};
+ enum ShadowFillMode {
+ kShadowLinear = 0,
+ kShadowExponential = 1
+ };
+
/**
* Draws a line by considering the special cases for optimization.
*
@@ -292,6 +299,10 @@ public:
_fillMode = mode;
}
+ virtual void setShadowFillMode(ShadowFillMode mode) {
+ _shadowFillMode = mode;
+ }
+
/**
* Sets the stroke width. All shapes drawn with a stroke will
* have that width. Pass 0 to disable shape stroking.
@@ -466,7 +477,7 @@ public:
*/
virtual void drawString(const Graphics::Font *font, const Common::String &text,
const Common::Rect &area, Graphics::TextAlign alignH,
- GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool useEllipsis) = 0;
+ GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool useEllipsis, const Common::Rect &textDrawableArea) = 0;
/**
* Allows to temporarily enable/disable all shadows drawing.
@@ -485,6 +496,7 @@ protected:
Surface *_activeSurface; /**< Pointer to the surface currently being drawn */
FillMode _fillMode; /**< Defines in which way (if any) are filled the drawn shapes */
+ ShadowFillMode _shadowFillMode;
int _shadowOffset; /**< offset for drawn shadows */
int _bevel; /**< amount of fake bevel */
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index e4843ba78b..491a9d7f42 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -119,6 +119,38 @@ inline frac_t fp_sqroot(uint32 x) {
*(ptr4 + (y) + (px)) = color2; \
} while (0)
+#define BE_DRAWCIRCLE_BCOLOR_TR_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (y) - (px), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_TR_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (x) - (py), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_TL_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (x) - (py), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_TL_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (y) - (px), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_BL_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (y) + (px), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_BL_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (x) + (py), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_BR_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (x) + (py), color, a); \
+} while (0)
+
+#define BE_DRAWCIRCLE_BCOLOR_BR_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (y) + (px), color, a); \
+} while (0)
+
#define BE_DRAWCIRCLE_XCOLOR_TOP(ptr1,ptr2,x,y,px,py) do { \
*(ptr1 + (y) - (px)) = color1; \
*(ptr1 + (x) - (py)) = color2; \
@@ -222,6 +254,37 @@ inline frac_t fp_sqroot(uint32 x) {
this->blendPixelPtr(ptr4 + (y) + (px), color2, a); \
} while (0)
+#define WU_DRAWCIRCLE_BCOLOR_TR_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (y) - (px), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (x) - (py), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_TL_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (x) - (py), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_TL_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (y) - (px), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_BL_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (y) + (px), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_BL_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr - (x) + (py), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_BR_CW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (x) + (py), color, a); \
+} while (0)
+
+#define WU_DRAWCIRCLE_BCOLOR_BR_CCW(ptr,x,y,px,py,a) do { \
+ this->blendPixelPtr(ptr + (y) + (px), color, a); \
+} while (0)
// optimized Wu's algorithm
#define WU_ALGORITHM() do { \
@@ -287,12 +350,14 @@ VectorRenderer *createRenderer(int mode) {
return new VectorRendererSpec<uint32>(format);
else if (g_system->getOverlayFormat().bytesPerPixel == 2)
return new VectorRendererSpec<uint16>(format);
+ break;
#ifndef DISABLE_FANCY_THEMES
case GUI::ThemeEngine::kGfxAntialias:
if (g_system->getOverlayFormat().bytesPerPixel == 4)
return new VectorRendererAA<uint32>(format);
else if (g_system->getOverlayFormat().bytesPerPixel == 2)
return new VectorRendererAA<uint16>(format);
+ break;
#endif
default:
break;
@@ -646,24 +711,45 @@ darkenFill(PixelType *ptr, PixelType *end) {
template<typename PixelType>
void VectorRendererSpec<PixelType>::
drawString(const Graphics::Font *font, const Common::String &text, const Common::Rect &area,
- Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool ellipsis) {
+ Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool ellipsis, const Common::Rect &textDrawableArea) {
int offset = area.top;
if (font->getFontHeight() < area.height()) {
switch (alignV) {
- case GUI::ThemeEngine::kTextAlignVCenter:
- offset = area.top + ((area.height() - font->getFontHeight()) >> 1);
- break;
- case GUI::ThemeEngine::kTextAlignVBottom:
- offset = area.bottom - font->getFontHeight();
- break;
- default:
- break;
+ case GUI::ThemeEngine::kTextAlignVCenter:
+ offset = area.top + ((area.height() - font->getFontHeight()) >> 1);
+ break;
+ case GUI::ThemeEngine::kTextAlignVBottom:
+ offset = area.bottom - font->getFontHeight();
+ break;
+ default:
+ break;
}
}
- font->drawString(_activeSurface, text, area.left, offset, area.width() - deltax, _fgColor, alignH, deltax, ellipsis);
+ Common::Rect drawArea;
+ if (textDrawableArea.isEmpty()) {
+ // In case no special area to draw to is given we only draw in the
+ // area specified by the user.
+ drawArea = area;
+ // warning("there is no text drawable area. Please set this area for clipping");
+ } else {
+ // The area we can draw to is the intersection between the allowed
+ // drawing area (textDrawableArea) and the area where we try to draw
+ // the text (area).
+ drawArea = textDrawableArea.findIntersectingRect(area);
+ }
+
+ // Better safe than sorry. We intersect with the actual surface boundaries
+ // to avoid any ugly clipping in _activeSurface->getSubArea which messes
+ // up the calculation of the x and y coordinates where to draw the string.
+ drawArea = drawArea.findIntersectingRect(Common::Rect(0, 0, _activeSurface->w, _activeSurface->h));
+
+ if (!drawArea.isEmpty()) {
+ Surface textAreaSurface = _activeSurface->getSubArea(drawArea);
+ font->drawString(&textAreaSurface, text, area.left - drawArea.left, offset - drawArea.top, area.width() - deltax, _fgColor, alignH, deltax, ellipsis);
+ }
}
/** LINES **/
@@ -817,7 +903,8 @@ drawRoundedSquare(int x, int y, int r, int w, int h) {
if (Base::_fillMode != kFillDisabled && Base::_shadowOffset
&& x + w + Base::_shadowOffset + 1 < Base::_activeSurface->w
- && y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h) {
+ && y + h + Base::_shadowOffset + 1 < Base::_activeSurface->h
+ && h > (Base::_shadowOffset + 1) * 2) {
drawRoundedSquareShadow(x, y, r, w, h, Base::_shadowOffset);
}
@@ -848,13 +935,14 @@ drawTab(int x, int y, int r, int w, int h) {
// FIXME: This is broken for the AA renderer.
// See the rounded rect alg for how to fix it. (The border should
// be drawn before the interior, both inside drawTabAlg.)
- drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode);
+ drawTabShadow(x, y, w - 2, h, r);
+ drawTabAlg(x, y, w - 2, h, r, _bgColor, Base::_fillMode);
if (Base::_strokeWidth)
drawTabAlg(x, y, w, h, r, _fgColor, kFillDisabled, (Base::_dynamicData >> 16), (Base::_dynamicData & 0xFFFF));
break;
case kFillForeground:
- drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode);
+ drawTabAlg(x, y, w, h, r, _fgColor, Base::_fillMode);
break;
}
}
@@ -1035,6 +1123,67 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer:
}
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+drawTabShadow(int x1, int y1, int w, int h, int r) {
+ int offset = 3;
+ int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
+
+ // "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
+ uint8 expFactor = 3;
+ uint16 alpha = (_activeSurface->format.bytesPerPixel > 2) ? 4 : 8;
+
+ int xstart = x1;
+ int ystart = y1;
+ int width = w;
+ int height = h + offset + 1;
+
+ for (int i = offset; i >= 0; i--) {
+ int f, ddF_x, ddF_y;
+ int x, y, px, py;
+
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(xstart + r, ystart + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(xstart + width - r, ystart + r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(xstart, ystart);
+
+ int short_h = height - (2 * r) + 2;
+ PixelType color = _format.RGBToColor(0, 0, 0);
+
+ BE_RESET();
+
+ // HACK: As we are drawing circles exploting 8-axis symmetry,
+ // there are 4 pixels on each circle which are drawn twice.
+ // this is ok on filled circles, but when blending on surfaces,
+ // we cannot let it blend twice. awful.
+ uint32 hb = 0;
+
+ while (x++ < y) {
+ BE_ALGORITHM();
+
+ if (((1 << x) & hb) == 0) {
+ blendFill(ptr_tl - y - px, ptr_tr + y - px, color, (uint8)alpha);
+ hb |= (1 << x);
+ }
+
+ if (((1 << y) & hb) == 0) {
+ blendFill(ptr_tl - x - py, ptr_tr + x - py, color, (uint8)alpha);
+ hb |= (1 << y);
+ }
+ }
+
+ ptr_fill += pitch * r;
+ while (short_h--) {
+ blendFill(ptr_fill, ptr_fill + width + 1, color, (uint8)alpha);
+ ptr_fill += pitch;
+ }
+
+ // Move shadow one pixel upward each iteration
+ xstart += 1;
+ // Multiply with expfactor
+ alpha = (alpha * (expFactor << 8)) >> 9;
+ }
+}
+
/** BEVELED TABS FOR CLASSIC THEME **/
template<typename PixelType>
void VectorRendererSpec<PixelType>::
@@ -1468,118 +1617,160 @@ drawTriangleFast(int x1, int y1, int size, bool inverted, PixelType color, Vecto
/** ROUNDED SQUARE ALGORITHM **/
template<typename PixelType>
void VectorRendererSpec<PixelType>::
-drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m, uint8 alpha_t, uint8 alpha_r, uint8 alpha_b, uint8 alpha_l) {
int f, ddF_x, ddF_y;
int x, y, px, py;
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
+ int sw = 0, sp = 0, hp = h * pitch;
- // TODO: Split this up into border, bevel and interior functions
-
- if (fill_m != kFillDisabled) {
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
-
- int real_radius = r;
- int short_h = h - (2 * r) + 2;
- int long_h = h;
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- BE_RESET();
+ int real_radius = r;
+ int short_h = h - (2 * r) + 2;
- PixelType color1 = color;
- if (fill_m == kFillBackground)
- color1 = _bgColor;
+ PixelType color1 = color;
+ PixelType color2 = color;
- if (fill_m == kFillGradient) {
- PixelType color2, color3, color4;
- precalcGradient(long_h);
+ while (sw++ < Base::_strokeWidth) {
+ blendFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color1, alpha_t); // top
+ blendFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color2, alpha_b); // bottom
+ sp += pitch;
- while (x++ < y) {
- BE_ALGORITHM();
+ BE_RESET();
+ r--;
+
+ int alphaStep_tr = ((alpha_t - alpha_r)/(y+1));
+ int alphaStep_br = ((alpha_r - alpha_b)/(y+1));
+ int alphaStep_bl = ((alpha_b - alpha_l)/(y+1));
+ int alphaStep_tl = ((alpha_l - alpha_t)/(y+1));
+
+ // Avoid blending the last pixels twice, since we have an alpha
+ while (x++ < (y - 2)) {
+ BE_ALGORITHM();
- color1 = calcGradient(real_radius - x, long_h);
- color2 = calcGradient(real_radius - y, long_h);
- color3 = calcGradient(long_h - r + x, long_h);
- color4 = calcGradient(long_h - r + y, long_h);
+ BE_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, x, y, px, py, (uint8)(alpha_r + (alphaStep_tr * x)));
+ BE_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, x, y, px, py, (uint8)(alpha_b + (alphaStep_br * x)));
+ BE_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, x, y, px, py, (uint8)(alpha_l + (alphaStep_bl * x)));
+ BE_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, x, y, px, py, (uint8)(alpha_t + (alphaStep_tl * x)));
+
+ BE_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, x, y, px, py, (uint8)(alpha_t - (alphaStep_tr * x)));
+ BE_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, x, y, px, py, (uint8)(alpha_r - (alphaStep_br * x)));
+ BE_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, x, y, px, py, (uint8)(alpha_b - (alphaStep_bl * x)));
+ BE_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, x, y, px, py, (uint8)(alpha_l - (alphaStep_tl * x)));
+
+ if (Base::_strokeWidth > 1) {
+ BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py);
+ BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py);
+ }
+ }
+ }
- gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y);
- gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x);
+ ptr_fill += pitch * real_radius;
+ while (short_h--) {
+ blendFill(ptr_fill, ptr_fill + Base::_strokeWidth, color1, alpha_l); // left
+ blendFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color2, alpha_r); // right
+ ptr_fill += pitch;
+ }
+}
- gradientFill(ptr_bl - x + py, w - 2 * r + 2 * x, x1 + r - x - y, long_h - r + y);
- gradientFill(ptr_bl - y + px, w - 2 * r + 2 * y, x1 + r - y - x, long_h - r + x);
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ int f, ddF_x, ddF_y;
+ int x, y, px, py;
+ int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
- BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
- }
- } else {
- while (x++ < y) {
- BE_ALGORITHM();
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color1);
- colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1);
+ int real_radius = r;
+ int short_h = h - (2 * r) + 2;
+ int long_h = h;
- colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color1);
- colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color1);
+ BE_RESET();
- // do not remove - messes up the drawing at lower resolutions
- BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
- }
- }
+ PixelType color1 = color;
- ptr_fill += pitch * r;
- while (short_h--) {
- if (fill_m == kFillGradient) {
- gradientFill(ptr_fill, w + 1, x1, real_radius++);
- } else {
- colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color1);
- }
- ptr_fill += pitch;
- }
- }
+ if (fill_m == kFillGradient) {
+ PixelType color2, color3, color4;
+ precalcGradient(long_h);
+ while (x++ < y) {
+ BE_ALGORITHM();
- if (Base::_strokeWidth) {
- int sw = 0, sp = 0, hp = h * pitch;
+ color1 = calcGradient(real_radius - x, long_h);
+ color2 = calcGradient(real_radius - y, long_h);
+ color3 = calcGradient(long_h - r + x, long_h);
+ color4 = calcGradient(long_h - r + y, long_h);
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
+ gradientFill(ptr_tl - x - py, w - 2 * r + 2 * x, x1 + r - x - y, real_radius - y);
+ gradientFill(ptr_tl - y - px, w - 2 * r + 2 * y, x1 + r - y - x, real_radius - x);
- int real_radius = r;
- int short_h = h - (2 * r) + 2;
+ gradientFill(ptr_bl - x + py, w - 2 * r + 2 * x, x1 + r - x - y, long_h - r + y);
+ gradientFill(ptr_bl - y + px, w - 2 * r + 2 * y, x1 + r - y - x, long_h - r + x);
- // TODO: A gradient effect on the bevel
- PixelType color1, color2;
- color1 = Base::_bevel ? _bevelColor : color;
- color2 = color;
+ BE_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ }
+ } else {
+ while (x++ < y) {
+ BE_ALGORITHM();
- while (sw++ < Base::_strokeWidth) {
- colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color1);
- colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color2);
- sp += pitch;
+ colorFill<PixelType>(ptr_tl - x - py, ptr_tr + x - py, color1);
+ colorFill<PixelType>(ptr_tl - y - px, ptr_tr + y - px, color1);
- BE_RESET();
- r--;
+ colorFill<PixelType>(ptr_bl - x + py, ptr_br + x + py, color1);
+ colorFill<PixelType>(ptr_bl - y + px, ptr_br + y + px, color1);
- while (x++ < y) {
- BE_ALGORITHM();
- BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ // do not remove - messes up the drawing at lower resolutions
+ BE_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py);
+ }
+ }
- if (Base::_strokeWidth > 1) {
- BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x - 1, y, px, py);
- BE_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px - pitch, py);
- }
- }
+ ptr_fill += pitch * r;
+ while (short_h--) {
+ if (fill_m == kFillGradient) {
+ gradientFill(ptr_fill, w + 1, x1, real_radius++);
+ } else {
+ colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color1);
}
+ ptr_fill += pitch;
+ }
+}
- ptr_fill += pitch * real_radius;
- while (short_h--) {
- colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color1);
- colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color2);
- ptr_fill += pitch;
+template<typename PixelType>
+void VectorRendererSpec<PixelType>::
+drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ const uint8 borderAlpha_t = 0;
+ const uint8 borderAlpha_r = 127;
+ const uint8 borderAlpha_b = 255;
+ const uint8 borderAlpha_l = 63;
+
+ const uint8 bevelAlpha_t = 255;
+ const uint8 bevelAlpha_r = 31;
+ const uint8 bevelAlpha_b = 0;
+ const uint8 bevelAlpha_l = 127;
+
+ // If only border is visible
+ if ((!(w <= 0 || h <= 0)) && (fill_m != Base::kFillDisabled)) {
+ if (fill_m == Base::kFillBackground)
+ drawInteriorRoundedSquareAlg(x1, y1, r, w, h, _bgColor, fill_m);
+ else
+ drawInteriorRoundedSquareAlg(x1, y1, r, w, h, color, fill_m);
+ }
+
+ if (Base::_strokeWidth) {
+ if (r != 0 && _bevel > 0) {
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, borderAlpha_t, borderAlpha_r, borderAlpha_b, borderAlpha_l);
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, _bevelColor, fill_m, bevelAlpha_t, bevelAlpha_r, bevelAlpha_b, bevelAlpha_l);
+ } else {
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, 255, 255, 255, 255);
}
}
}
@@ -1638,85 +1829,112 @@ drawCircleAlg(int x1, int y1, int r, PixelType color, VectorRenderer::FillMode f
********************************************************************/
template<typename PixelType>
void VectorRendererSpec<PixelType>::
-drawSquareShadow(int x, int y, int w, int h, int blur) {
- PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x + w - 1, y + blur);
+drawSquareShadow(int x, int y, int w, int h, int offset) {
+ PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x + w - 1, y + offset);
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
int i, j;
- i = h - blur;
+ i = h - offset;
while (i--) {
- j = blur;
+ j = offset;
while (j--)
- blendPixelPtr(ptr + j, 0, ((blur - j) << 8) / blur);
+ blendPixelPtr(ptr + j, 0, ((offset - j) << 8) / offset);
ptr += pitch;
}
- ptr = (PixelType *)_activeSurface->getBasePtr(x + blur, y + h - 1);
+ ptr = (PixelType *)_activeSurface->getBasePtr(x + offset, y + h - 1);
- while (i++ < blur) {
- j = w - blur;
+ while (i++ < offset) {
+ j = w - offset;
while (j--)
- blendPixelPtr(ptr + j, 0, ((blur - i) << 8) / blur);
+ blendPixelPtr(ptr + j, 0, ((offset - i) << 8) / offset);
ptr += pitch;
}
ptr = (PixelType *)_activeSurface->getBasePtr(x + w, y + h);
i = 0;
- while (i++ < blur) {
- j = blur - 1;
+ while (i++ < offset) {
+ j = offset - 1;
while (j--)
- blendPixelPtr(ptr + j, 0, (((blur - j) * (blur - i)) << 8) / (blur * blur));
+ blendPixelPtr(ptr + j, 0, (((offset - j) * (offset - i)) << 8) / (offset * offset));
ptr += pitch;
}
}
template<typename PixelType>
void VectorRendererSpec<PixelType>::
-drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) {
- int f, ddF_x, ddF_y;
- int x, y, px, py;
+drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int offset) {
int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel;
- int alpha = 102;
- x1 += blur;
- y1 += blur;
+ // "Harder" shadows when having lower BPP, since we will have artifacts (greenish tint on the modern theme)
+ uint8 expFactor = 3;
+ uint16 alpha = (_activeSurface->format.bytesPerPixel > 2) ? 4 : 8;
+
+ // These constants ensure a border of 2px on the left and of each rounded square
+ int xstart = (x1 > 2) ? x1 - 2 : x1;
+ int ystart = y1;
+ int width = w + offset + 2;
+ int height = h + offset + 1;
+
+ for (int i = offset; i >= 0; i--) {
+ int f, ddF_x, ddF_y;
+ int x, y, px, py;
+
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(xstart + r, ystart + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(xstart + width - r, ystart + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(xstart + r, ystart + height - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(xstart + width - r, ystart + height - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(xstart, ystart);
+
+ int short_h = height - (2 * r) + 2;
+ PixelType color = _format.RGBToColor(0, 0, 0);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - blur, y1 + r);
-
- int short_h = h - (2 * r) + 1;
+ BE_RESET();
- BE_RESET();
+ // HACK: As we are drawing circles exploting 8-axis symmetry,
+ // there are 4 pixels on each circle which are drawn twice.
+ // this is ok on filled circles, but when blending on surfaces,
+ // we cannot let it blend twice. awful.
+ uint32 hb = 0;
+
+ while (x++ < y) {
+ BE_ALGORITHM();
- // HACK: As we are drawing circles exploting 8-axis symmetry,
- // there are 4 pixels on each circle which are drawn twice.
- // this is ok on filled circles, but when blending on surfaces,
- // we cannot let it blend twice. awful.
- uint32 hb = 0;
- while (x++ < y) {
- BE_ALGORITHM();
+ if (((1 << x) & hb) == 0) {
+ blendFill(ptr_tl - y - px, ptr_tr + y - px, color, (uint8)alpha);
+
+ // Will create a dark line of pixles if left out
+ if (hb > 0) {
+ blendFill(ptr_bl - y + px, ptr_br + y + px, color, (uint8)alpha);
+ }
+ hb |= (1 << x);
+ }
- if (((1 << x) & hb) == 0) {
- blendFill(ptr_tr - px - r, ptr_tr + y - px, 0, alpha);
- blendFill(ptr_bl - y + px, ptr_br + y + px, 0, alpha);
- hb |= (1 << x);
+ if (((1 << y) & hb) == 0) {
+ blendFill(ptr_tl - x - py, ptr_tr + x - py, color, (uint8)alpha);
+ blendFill(ptr_bl - x + py, ptr_br + x + py, color, (uint8)alpha);
+ hb |= (1 << y);
+ }
}
-
- if (((1 << y) & hb) == 0) {
- blendFill(ptr_tr - r - py, ptr_tr + x - py, 0, alpha);
- blendFill(ptr_bl - x + py, ptr_br + x + py, 0, alpha);
- hb |= (1 << y);
+
+ ptr_fill += pitch * r;
+ while (short_h--) {
+ blendFill(ptr_fill, ptr_fill + width + 1, color, (uint8)alpha);
+ ptr_fill += pitch;
}
- }
- while (short_h--) {
- blendFill(ptr_fill - r, ptr_fill + blur, 0, alpha);
- ptr_fill += pitch;
+ // Make shadow smaller each iteration, and move it one pixel inward
+ xstart += 1;
+ ystart += 1;
+ width -= 2;
+ height -= 2;
+
+ if (_shadowFillMode == kShadowExponential)
+ // Multiply with expfactor
+ alpha = (alpha * (expFactor << 8)) >> 9;
}
}
@@ -1909,7 +2127,7 @@ drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer:
/** ROUNDED SQUARES **/
template<typename PixelType>
void VectorRendererAA<PixelType>::
-drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m, uint8 alpha_t, uint8 alpha_r, uint8 alpha_b, uint8 alpha_l) {
int x, y;
const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel;
int px, py;
@@ -1918,65 +2136,89 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto
frac_t T = 0, oldT;
uint8 a1, a2;
- // TODO: Split this up into border, bevel and interior functions
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- if (Base::_strokeWidth) {
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
-
- int sw = 0, sp = 0;
- int short_h = h - 2 * r;
- int hp = h * pitch;
-
- int strokeWidth = Base::_strokeWidth;
- // If we're going to fill the inside, draw a slightly thicker border
- // so we can blend the inside on top of it.
- if (fill_m != Base::kFillDisabled) strokeWidth++;
-
- // TODO: A gradient effect on the bevel
- PixelType color1, color2;
- color1 = Base::_bevel ? Base::_bevelColor : color;
- color2 = color;
+ int sw = 0, sp = 0;
+ int short_h = h - 2 * r;
+ int hp = h * pitch;
+ int strokeWidth = Base::_strokeWidth;
- while (sw++ < strokeWidth) {
- colorFill<PixelType>(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color1);
- colorFill<PixelType>(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color2);
- sp += pitch;
+ while (sw++ < strokeWidth) {
+ this->blendFill(ptr_fill + hp - sp + r, ptr_fill + w + hp + 1 - sp - r, color, alpha_b); // bottom
+ this->blendFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color, alpha_t); // top
- x = r - (sw - 1);
- y = 0;
- T = 0;
- px = pitch * x;
- py = 0;
+ sp += pitch;
- while (x > y++) {
- WU_ALGORITHM();
+ x = r - (sw - 1);
+ y = 0;
+ T = 0;
+ px = pitch * x;
+ py = 0;
- // sw == 1: outside, sw = _strokeWidth: inside
- // We always draw the outer edge AAed, but the inner edge
- // only when the inside isn't filled
- if (sw != strokeWidth || fill_m != Base::kFillDisabled)
- a2 = 255;
+ int alphaStep_tr = ((alpha_t - alpha_r)/(x+1));
+ int alphaStep_br = ((alpha_r - alpha_b)/(x+1));
+ int alphaStep_bl = ((alpha_b - alpha_l)/(x+1));
+ int alphaStep_tl = ((alpha_l - alpha_t)/(x+1));
- // inner arc
- WU_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, (x - 1), y, (px - pitch), py, a2);
+ while (x > y++) {
+ WU_ALGORITHM();
- if (sw == 1) // outer arc
- WU_DRAWCIRCLE_BCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
+ // sw == 1: outside, sw = _strokeWidth: inside
+ // We always draw the outer edge AAed, but the inner edge
+ // only when the inside isn't filled
+ if (sw != strokeWidth || fill_m != Base::kFillDisabled)
+ a2 = 255;
+
+ // inner arc
+ WU_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_t - (alphaStep_tr * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_r - (alphaStep_br * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_b - (alphaStep_bl * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_l - (alphaStep_tl * y)) << 8) * a2) >> 16));
+
+ WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_r + (alphaStep_tr * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_b + (alphaStep_br * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_l + (alphaStep_bl * y)) << 8) * a2) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, (x - 1), y, (px - pitch), py, (uint8)((uint32)(((alpha_t + (alphaStep_tl * y)) << 8) * a2) >> 16));
+
+ // outer arc
+ if (sw == 1) {
+ WU_DRAWCIRCLE_BCOLOR_TR_CW(ptr_tr, x, y, px, py, (uint8)((uint32)(((alpha_t - (alphaStep_tr * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BR_CW(ptr_br, x, y, px, py, (uint8)((uint32)(((alpha_r - (alphaStep_br * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BL_CW(ptr_bl, x, y, px, py, (uint8)((uint32)(((alpha_b - (alphaStep_bl * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_TL_CW(ptr_tl, x, y, px, py, (uint8)((uint32)(((alpha_l - (alphaStep_tl * y)) << 8) * a1) >> 16));
+
+ WU_DRAWCIRCLE_BCOLOR_TR_CCW(ptr_tr, x, y, px, py, (uint8)((uint32)(((alpha_r + (alphaStep_tr * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BR_CCW(ptr_br, x, y, px, py, (uint8)((uint32)(((alpha_b + (alphaStep_br * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_BL_CCW(ptr_bl, x, y, px, py, (uint8)((uint32)(((alpha_l + (alphaStep_bl * y)) << 8) * a1) >> 16));
+ WU_DRAWCIRCLE_BCOLOR_TL_CCW(ptr_tl, x, y, px, py, (uint8)((uint32)(((alpha_t + (alphaStep_tl * y)) << 8) * a1) >> 16));
+ }
}
- }
ptr_fill += pitch * r;
- while (short_h-- >= 0) {
- colorFill<PixelType>(ptr_fill, ptr_fill + Base::_strokeWidth, color1);
- colorFill<PixelType>(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color2);
+
+ while (short_h-- >= -2) {
+ this->blendFill(ptr_fill, ptr_fill + Base::_strokeWidth, color, alpha_l); // left
+ this->blendFill(ptr_fill + w - Base::_strokeWidth + 1, ptr_fill + w + 1, color, alpha_r); // right
ptr_fill += pitch;
}
}
+}
+
+template<typename PixelType>
+void VectorRendererAA<PixelType>::
+drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ int x, y;
+ const int pitch = Base::_activeSurface->pitch / Base::_activeSurface->format.bytesPerPixel;
+ int px, py;
+
+ uint32 rsq = r*r;
+ frac_t T = 0, oldT;
+ uint8 a1, a2;
r -= Base::_strokeWidth;
x1 += Base::_strokeWidth;
@@ -1985,93 +2227,116 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto
h -= 2*Base::_strokeWidth;
rsq = r*r;
- if (w <= 0 || h <= 0)
- return; // Only border is visible
+ PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
+ PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
+ PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
+ PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
+ PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
- if (fill_m != Base::kFillDisabled) {
- if (fill_m == Base::kFillBackground)
- color = Base::_bgColor;
+ int short_h = h - 2 * r;
+ x = r;
+ y = 0;
+ T = 0;
+ px = pitch * x;
+ py = 0;
- PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
- PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
- PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r);
- PixelType *ptr_br = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + h - r);
- PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
+ if (fill_m == Base::kFillGradient) {
- int short_h = h - 2 * r;
- x = r;
- y = 0;
- T = 0;
- px = pitch * x;
- py = 0;
+ Base::precalcGradient(h);
- if (fill_m == Base::kFillGradient) {
+ PixelType color1, color2, color3, color4;
+ while (x > y++) {
+ WU_ALGORITHM();
- Base::precalcGradient(h);
+ color1 = Base::calcGradient(r - x, h);
+ color2 = Base::calcGradient(r - y, h);
+ color3 = Base::calcGradient(h - r + x, h);
+ color4 = Base::calcGradient(h - r + y, h);
- PixelType color1, color2, color3, color4;
- while (x > y++) {
- WU_ALGORITHM();
+ Base::gradientFill(ptr_tl - x - py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, r - y);
- color1 = Base::calcGradient(r - x, h);
- color2 = Base::calcGradient(r - y, h);
- color3 = Base::calcGradient(h - r + x, h);
- color4 = Base::calcGradient(h - r + y, h);
+ // Only fill each horizontal line once (or we destroy
+ // the gradient effect at the edges)
+ if (T < oldT || y == 1)
+ Base::gradientFill(ptr_tl - y - px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, r - x);
- Base::gradientFill(ptr_tl - x - py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, r - y);
+ Base::gradientFill(ptr_bl - x + py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, h - r + y);
- // Only fill each horizontal line once (or we destroy
- // the gradient effect at the edges)
- if (T < oldT || y == 1)
- Base::gradientFill(ptr_tl - y - px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, r - x);
+ // Only fill each horizontal line once (or we destroy
+ // the gradient effect at the edges)
+ if (T < oldT || y == 1)
+ Base::gradientFill(ptr_bl - y + px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, h - r + x);
- Base::gradientFill(ptr_bl - x + py + 1, w - 2 * r + 2 * x - 1, x1 + r - x - y + 1, h - r + y);
+ // This shape is used for dialog backgrounds.
+ // If we're drawing on top of an empty overlay background,
+ // and the overlay supports alpha, we have to do AA by
+ // setting the dest alpha channel, instead of blending with
+ // dest color channels.
+ if (!g_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha))
+ WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelPtr);
+ else
+ WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelDestAlphaPtr);
+ }
- // Only fill each horizontal line once (or we destroy
- // the gradient effect at the edges)
- if (T < oldT || y == 1)
- Base::gradientFill(ptr_bl - y + px + 1, w - 2 * r + 2 * y - 1, x1 + r - y - x + 1, h - r + x);
-
- // This shape is used for dialog backgrounds.
- // If we're drawing on top of an empty overlay background,
- // and the overlay supports alpha, we have to do AA by
- // setting the dest alpha channel, instead of blending with
- // dest color channels.
- if (!g_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha))
- WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelPtr);
- else
- WU_DRAWCIRCLE_XCOLOR(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1, blendPixelDestAlphaPtr);
- }
+ ptr_fill += pitch * r;
+ while (short_h-- >= 0) {
+ Base::gradientFill(ptr_fill, w + 1, x1, r++);
+ ptr_fill += pitch;
+ }
- ptr_fill += pitch * r;
- while (short_h-- >= 0) {
- Base::gradientFill(ptr_fill, w + 1, x1, r++);
- ptr_fill += pitch;
- }
+ } else {
- } else {
+ while (x > 1 + y++) {
+ WU_ALGORITHM();
- while (x > 1 + y++) {
- WU_ALGORITHM();
+ colorFill<PixelType>(ptr_tl - x - py + 1, ptr_tr + x - py, color);
+ if (T < oldT || y == 1)
+ colorFill<PixelType>(ptr_tl - y - px + 1, ptr_tr + y - px, color);
- colorFill<PixelType>(ptr_tl - x - py + 1, ptr_tr + x - py, color);
- if (T < oldT || y == 1)
- colorFill<PixelType>(ptr_tl - y - px + 1, ptr_tr + y - px, color);
+ colorFill<PixelType>(ptr_bl - x + py + 1, ptr_br + x + py, color);
+ if (T < oldT || y == 1)
+ colorFill<PixelType>(ptr_bl - y + px + 1, ptr_br + y + px, color);
- colorFill<PixelType>(ptr_bl - x + py + 1, ptr_br + x + py, color);
- if (T < oldT || y == 1)
- colorFill<PixelType>(ptr_bl - y + px + 1, ptr_br + y + px, color);
+ WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
+ }
- WU_DRAWCIRCLE(ptr_tr, ptr_tl, ptr_bl, ptr_br, x, y, px, py, a1);
- }
+ ptr_fill += pitch * r;
+ while (short_h-- >= 0) {
+ colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
+ ptr_fill += pitch;
+ }
+ }
+}
- ptr_fill += pitch * r;
- while (short_h-- >= 0) {
- colorFill<PixelType>(ptr_fill, ptr_fill + w + 1, color);
- ptr_fill += pitch;
- }
+template<typename PixelType>
+void VectorRendererAA<PixelType>::
+drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m) {
+ const uint8 borderAlpha_t = 0;
+ const uint8 borderAlpha_r = 127;
+ const uint8 borderAlpha_b = 255;
+ const uint8 borderAlpha_l = 63;
+
+ const uint8 bevelAlpha_t = 255;
+ const uint8 bevelAlpha_r = 31;
+ const uint8 bevelAlpha_b = 0;
+ const uint8 bevelAlpha_l = 127;
+
+ if (Base::_strokeWidth) {
+ if (r != 0 && Base::_bevel > 0) {
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, borderAlpha_t, borderAlpha_r, borderAlpha_b, borderAlpha_l);
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, Base::_bevelColor, fill_m, bevelAlpha_t, bevelAlpha_r, bevelAlpha_b, bevelAlpha_l);
+ } else {
+ drawBorderRoundedSquareAlg(x1, y1, r, w, h, color, fill_m, 255, 255, 255, 255);
}
}
+
+ // If only border is visible
+ if ((!(w <= 0 || h <= 0)) && (fill_m != Base::kFillDisabled)) {
+ if (fill_m == Base::kFillBackground)
+ drawInteriorRoundedSquareAlg(x1, y1, r, w, h, Base::_bgColor, fill_m);
+ else
+ drawInteriorRoundedSquareAlg(x1, y1, r, w, h, color, fill_m);
+ }
}
/** CIRCLES **/
diff --git a/graphics/VectorRendererSpec.h b/graphics/VectorRendererSpec.h
index 4ed80cb55f..c035ca0e19 100644
--- a/graphics/VectorRendererSpec.h
+++ b/graphics/VectorRendererSpec.h
@@ -61,7 +61,7 @@ public:
}
void drawString(const Graphics::Font *font, const Common::String &text,
const Common::Rect &area, Graphics::TextAlign alignH,
- GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis);
+ GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis, const Common::Rect &textDrawableArea = Common::Rect(0, 0, 0, 0));
void setFgColor(uint8 r, uint8 g, uint8 b) { _fgColor = _format.RGBToColor(r, g, b); }
void setBgColor(uint8 r, uint8 g, uint8 b) { _bgColor = _format.RGBToColor(r, g, b); }
@@ -158,6 +158,12 @@ protected:
virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h,
PixelType color, FillMode fill_m);
+ virtual void drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h,
+ PixelType color, FillMode fill_m, uint8 alpha_t, uint8 alpha_r, uint8 alpha_b, uint8 alpha_l);
+
+ virtual void drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h,
+ PixelType color, FillMode fill_m);
+
virtual void drawSquareAlg(int x, int y, int w, int h,
PixelType color, FillMode fill_m);
@@ -174,6 +180,8 @@ protected:
PixelType color, VectorRenderer::FillMode fill_m,
int baseLeft = 0, int baseRight = 0);
+ virtual void drawTabShadow(int x, int y, int w, int h, int r);
+
virtual void drawBevelTabAlg(int x, int y, int w, int h,
int bevel, PixelType topColor, PixelType bottomColor,
int baseLeft = 0, int baseRight = 0);
@@ -186,10 +194,10 @@ protected:
* There functions may be overloaded in inheriting classes to improve performance
* in the slowest platforms where pixel alpha blending just doesn't cut it.
*
- * @param blur Intensity/size of the shadow.
+ * @param offset Intensity/size of the shadow.
*/
- virtual void drawSquareShadow(int x, int y, int w, int h, int blur);
- virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur);
+ virtual void drawSquareShadow(int x, int y, int w, int h, int offset);
+ virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset);
/**
* Calculates the color gradient on a given point.
@@ -292,10 +300,12 @@ protected:
*/
virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
- virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur) {
- Base::drawRoundedSquareShadow(x, y, r, w, h, blur);
-// VectorRenderer::applyConvolutionMatrix(VectorRenderer::kConvolutionHardBlur,
-// Common::Rect(x, y, x + w + blur * 2, y + h + blur * 2));
+ virtual void drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m, uint8 alpha_t, uint8 alpha_l, uint8 alpha_r, uint8 alpha_b);
+
+ virtual void drawInteriorRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
+
+ virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int offset) {
+ Base::drawRoundedSquareShadow(x, y, r, w, h, offset);
}
virtual void drawTabAlg(int x, int y, int w, int h, int r,
diff --git a/graphics/font.cpp b/graphics/font.cpp
index 3b00cd8568..a852274b06 100644
--- a/graphics/font.cpp
+++ b/graphics/font.cpp
@@ -128,7 +128,7 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in
w = getCharWidth(cur);
if (x+w > rightX)
break;
- if (x >= leftX)
+ if (x+w >= leftX)
drawChar(dst, str[i], x, y, color);
x += w;
}
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 561c0244a2..688654d208 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -122,15 +122,16 @@ protected:
class ThemeItemTextData : public ThemeItem {
public:
- ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::String &text,
- Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV,
+ ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::Rect &textDrawableArea,
+ const Common::String &text, Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV,
bool ellipsis, bool restoreBg, int deltaX) :
ThemeItem(engine, area), _data(data), _color(color), _text(text), _alignH(alignH), _alignV(alignV),
- _ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX) {}
+ _ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX), _textDrawableArea(textDrawableArea) {}
void drawSelf(bool draw, bool restore);
protected:
+ Common::Rect _textDrawableArea;
const TextDrawData *_data;
const TextColorData *_color;
Common::String _text;
@@ -246,7 +247,7 @@ void ThemeItemTextData::drawSelf(bool draw, bool restore) {
if (draw) {
_engine->renderer()->setFgColor(_color->r, _color->g, _color->b);
- _engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis);
+ _engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis, _textDrawableArea);
}
_engine->addDirtyRect(_area);
@@ -521,6 +522,12 @@ void ThemeEngine::setGraphicsMode(GraphicsMode mode) {
delete _vectorRenderer;
_vectorRenderer = Graphics::createRenderer(mode);
_vectorRenderer->setSurface(&_screen);
+
+ // Since we reinitialized our screen surfaces we know nothing has been
+ // drawn so far. Sometimes we still end up with dirty screen bits in the
+ // list. Clearing it avoids invalid overlay writes when the backend
+ // resizes the overlay.
+ _dirtyScreen.clear();
}
void WidgetDrawData::calcBackgroundOffset() {
@@ -836,7 +843,7 @@ void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic,
}
void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
- bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) {
+ bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax, const Common::Rect &drawableTextArea) {
if (_texts[type] == 0)
return;
@@ -844,7 +851,7 @@ void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect
Common::Rect area = r;
area.clip(_screen.w, _screen.h);
- ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, text, alignH, alignV, ellipsis, restoreBg, deltax);
+ ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, drawableTextArea, text, alignH, alignV, ellipsis, restoreBg, deltax);
if (_buffering) {
_screenQueue.push_back(q);
@@ -1115,7 +1122,7 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co
}
}
-void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color, bool restore) {
+void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color, bool restore, const Common::Rect &drawableTextArea) {
if (!ready())
return;
@@ -1185,7 +1192,7 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid
break;
}
- queueDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax);
+ queueDDText(textId, colorId, r, str, restore, useEllipsis, align, kTextAlignVCenter, deltax, drawableTextArea);
}
void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state, FontColor color) {
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index c0e47a19e6..4dffb13e71 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -29,6 +29,7 @@
#include "common/hashmap.h"
#include "common/list.h"
#include "common/str.h"
+#include "common/rect.h"
#include "graphics/surface.h"
#include "graphics/font.h"
@@ -39,10 +40,6 @@
class OSystem;
-namespace Common {
-struct Rect;
-}
-
namespace Graphics {
struct DrawStep;
class VectorRenderer;
@@ -376,7 +373,7 @@ public:
void drawDialogBackground(const Common::Rect &r, DialogBackground type, WidgetStateInfo state = kStateEnabled);
- void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true);
+ void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled, FontColor color = kFontColorNormal);
@@ -588,7 +585,7 @@ protected:
*/
void queueDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool restore = false);
void queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
- bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0);
+ bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
void queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha);
/**
diff --git a/gui/about.cpp b/gui/about.cpp
index 20145886c6..3bb1934e28 100644
--- a/gui/about.cpp
+++ b/gui/about.cpp
@@ -180,9 +180,10 @@ void AboutDialog::close() {
}
void AboutDialog::drawDialog() {
-// g_gui.theme()->setDrawArea(Common::Rect(_x, _y, _x+_w, _y+_h));
Dialog::drawDialog();
+ setTextDrawableArea(Common::Rect(_x, _y, _x + _w, _y + _h));
+
// Draw text
// TODO: Add a "fade" effect for the top/bottom text lines
// TODO: Maybe prerender all of the text into another surface,
@@ -239,8 +240,8 @@ void AboutDialog::drawDialog() {
while (*str && *str == ' ')
str++;
- if (*str && y > _y && y + g_gui.theme()->getFontHeight() < _y + _h)
- g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false);
+ if (*str)
+ g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false, ThemeEngine::kFontStyleBold, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
y += _lineHeight;
}
}
diff --git a/gui/credits.h b/gui/credits.h
index 70f79ac9a5..3a4d7769f6 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -170,6 +170,15 @@ static const char *credits[] = {
"C0""Eugene Sandulenko",
"C0""David Turner",
"",
+"C1""Mortevielle",
+"A0""Arnaud Boutonne",
+"C0""Arnaud Boutonn\351",
+"C0""Paul Gilbert",
+"",
+"C1""Neverhood",
+"C0""Benjamin Haisch",
+"C0""Filippos Karapetis",
+"",
"C1""Parallaction",
"C0""peres",
"",
diff --git a/gui/object.cpp b/gui/object.cpp
index 73c4f74d6c..189a286ead 100644
--- a/gui/object.cpp
+++ b/gui/object.cpp
@@ -29,7 +29,7 @@
namespace GUI {
GuiObject::GuiObject(const Common::String &name)
- : _x(-1000), _y(-1000), _w(0), _h(0), _name(name), _firstWidget(0) {
+ : _x(-1000), _y(-1000), _w(0), _h(0), _name(name), _firstWidget(0), _textDrawableArea(Common::Rect(0, 0, 0, 0)) {
reflowLayout();
}
diff --git a/gui/object.h b/gui/object.h
index bce3cd7846..dac3341b5a 100644
--- a/gui/object.h
+++ b/gui/object.h
@@ -24,6 +24,7 @@
#include "common/scummsys.h"
#include "common/str.h"
+#include "common/rect.h"
namespace GUI {
@@ -59,6 +60,8 @@ class Widget;
class GuiObject : public CommandReceiver {
friend class Widget;
protected:
+ Common::Rect _textDrawableArea;
+
int16 _x, _y;
uint16 _w, _h;
const Common::String _name;
@@ -66,10 +69,12 @@ protected:
Widget *_firstWidget;
public:
- GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(0) { }
+ GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(0), _textDrawableArea(Common::Rect(0, 0, 0, 0)) { }
GuiObject(const Common::String &name);
~GuiObject();
+ virtual void setTextDrawableArea(const Common::Rect &r) { _textDrawableArea = r; }
+
virtual int16 getAbsX() const { return _x; }
virtual int16 getAbsY() const { return _y; }
virtual int16 getChildX() const { return getAbsX(); }
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 1b6ae3ec27..352cc86852 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -1,142 +1,142 @@
"<?xml version = '1.0'?>"
-"<render_info> "
-"<palette> "
+"<render_info>"
+"<palette>"
"<color name='black' "
"rgb='0,0,0' "
-"/> "
+"/>"
"<color name='lightgrey' "
"rgb='104,104,104' "
-"/> "
+"/>"
"<color name='darkgrey' "
"rgb='64,64,64' "
-"/> "
+"/>"
"<color name='green' "
"rgb='32,160,32' "
-"/> "
+"/>"
"<color name='green2' "
"rgb='0,255,0' "
-"/> "
-"</palette> "
-"<fonts> "
+"/>"
+"</palette>"
+"<fonts>"
"<font id='text_default' "
"file='helvb12.bdf' "
-"/> "
+"/>"
"<font resolution='y<400' "
"id='text_default' "
"file='clR6x12.bdf' "
-"/> "
+"/>"
"<font id='text_button' "
"file='helvb12.bdf' "
-"/> "
+"/>"
"<font resolution='y<400' "
"id='text_button' "
"file='clR6x12.bdf' "
-"/> "
+"/>"
"<font id='text_normal' "
"file='helvb12.bdf' "
-"/> "
+"/>"
"<font resolution='y<400' "
"id='text_normal' "
"file='clR6x12.bdf' "
-"/> "
+"/>"
"<font id='tooltip_normal' "
"file='fixed5x8.bdf' "
-"/> "
+"/>"
"<text_color id='color_normal' "
"color='green' "
-"/> "
+"/>"
"<text_color id='color_normal_inverted' "
"color='black' "
-"/> "
+"/>"
"<text_color id='color_normal_hover' "
"color='green2' "
-"/> "
+"/>"
"<text_color id='color_normal_disabled' "
"color='lightgrey' "
-"/> "
+"/>"
"<text_color id='color_alternative' "
"color='lightgrey' "
-"/> "
+"/>"
"<text_color id='color_alternative_inverted' "
"color='255,255,255' "
-"/> "
+"/>"
"<text_color id='color_alternative_hover' "
"color='176,176,176' "
-"/> "
+"/>"
"<text_color id='color_alternative_disabled' "
"color='darkgrey' "
-"/> "
+"/>"
"<text_color id='color_button' "
"color='green' "
-"/> "
+"/>"
"<text_color id='color_button_hover' "
"color='green2' "
-"/> "
+"/>"
"<text_color id='color_button_disabled' "
"color='lightgrey' "
-"/> "
-"</fonts> "
-"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/> "
-"<drawdata id='text_selection' cache='false'> "
+"/>"
+"</fonts>"
+"<defaults fill='foreground' fg_color='darkgrey' bg_color='black' shadow='0' bevel_color='lightgrey'/>"
+"<drawdata id='text_selection' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='text_selection_focus' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='text_selection_focus' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='mainmenu_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='mainmenu_bg' cache='false'>"
"<drawstep func='fill' "
"fill='foreground' "
"fg_color='black' "
-"/> "
-"</drawdata> "
-"<drawdata id='special_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='special_bg' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='tooltip_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='tooltip_bg' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='foreground' "
"fg_color='black' "
-"/> "
-"</drawdata> "
-"<drawdata id='separator' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='separator' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"height='2' "
"ypos='center' "
"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_base' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_base' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_handle_hover' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_handle_hover' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green2' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_handle_idle' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_handle_idle' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_idle' cache='false' resolution='y>399'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_button_idle' cache='false' resolution='y>399'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -146,13 +146,13 @@
"ypos='center' "
"padding='0,0,3,0' "
"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_idle' cache='false' resolution='y<400'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_button_idle' cache='false' resolution='y<400'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -162,13 +162,13 @@
"ypos='center' "
"padding='0,0,2,0' "
"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_hover' cache='false' resolution='y>399'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_button_hover' cache='false' resolution='y>399'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -178,13 +178,13 @@
"ypos='center' "
"padding='0,0,3,0' "
"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='scrollbar_button_hover' cache='false' resolution='y<400'> "
+"/>"
+"</drawdata>"
+"<drawdata id='scrollbar_button_hover' cache='false' resolution='y<400'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -194,69 +194,69 @@
"ypos='center' "
"padding='0,0,2,0' "
"orientation='top' "
-"/> "
-"</drawdata> "
-"<drawdata id='tab_active' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='tab_active' cache='false'>"
"<text font='text_default' "
"text_color='color_normal_hover' "
"vertical_align='center' "
"horizontal_align='center' "
-"/> "
+"/>"
"<drawstep func='tab' "
"bevel='2' "
"radius='0' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='tab_inactive' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='tab_inactive' cache='false'>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='center' "
"horizontal_align='center' "
-"/> "
+"/>"
"<drawstep func='tab' "
"bevel='2' "
"radius='0' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='tab_background' cache='false'> "
-"</drawdata> "
-"<drawdata id='widget_slider' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='tab_background' cache='false'>"
+"</drawdata>"
+"<drawdata id='widget_slider' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='slider_disabled' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_disabled' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='slider_full' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_full' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='slider_hover' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='slider_hover' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green2' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_small' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_small' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_idle' cache='false' resolution='y>399'> "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_idle' cache='false' resolution='y>399'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -266,7 +266,7 @@
"ypos='10' "
"padding='0,0,7,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -276,18 +276,18 @@
"ypos='4' "
"padding='0,0,7,0' "
"orientation='top' "
-"/> "
+"/>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_idle' cache='false' resolution='y<400'> "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_idle' cache='false' resolution='y<400'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -297,7 +297,7 @@
"ypos='9' "
"padding='0,0,3,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -307,18 +307,18 @@
"ypos='4' "
"padding='0,0,3,0' "
"orientation='top' "
-"/> "
+"/>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_disabled' cache='false' resolution='y>399'> "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_disabled' cache='false' resolution='y>399'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -328,7 +328,7 @@
"ypos='10' "
"padding='0,0,7,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -338,18 +338,18 @@
"ypos='4' "
"padding='0,0,7,0' "
"orientation='top' "
-"/> "
+"/>"
"<text font='text_default' "
"text_color='color_normal_disabled' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_disabled' cache='false' resolution='y<400'> "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_disabled' cache='false' resolution='y<400'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -359,7 +359,7 @@
"ypos='9' "
"padding='0,0,3,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -369,18 +369,18 @@
"ypos='4' "
"padding='0,0,3,0' "
"orientation='top' "
-"/> "
+"/>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_hover' cache='false' resolution='y>399'> "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_hover' cache='false' resolution='y>399'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -390,7 +390,7 @@
"ypos='10' "
"padding='0,0,7,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -400,18 +400,18 @@
"ypos='4' "
"padding='0,0,7,0' "
"orientation='top' "
-"/> "
+"/>"
"<text font='text_default' "
"text_color='color_normal_hover' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='popup_hover' cache='false' resolution='y<400'> "
+"/>"
+"</drawdata>"
+"<drawdata id='popup_hover' cache='false' resolution='y<400'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -421,7 +421,7 @@
"ypos='9' "
"padding='0,0,3,0' "
"orientation='bottom' "
-"/> "
+"/>"
"<drawstep func='triangle' "
"fg_color='green' "
"fill='foreground' "
@@ -431,123 +431,123 @@
"ypos='4' "
"padding='0,0,3,0' "
"orientation='top' "
-"/> "
+"/>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_textedit' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_textedit' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='plain_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='plain_bg' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='caret' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='caret' cache='false'>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='lightgrey' "
-"/> "
-"</drawdata> "
-"<drawdata id='default_bg' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='default_bg' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='button_pressed' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='button_pressed' cache='false'>"
"<text font='text_button' "
"text_color='color_alternative_inverted' "
"vertical_align='center' "
"horizontal_align='center' "
-"/> "
+"/>"
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='button_idle' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='button_idle' cache='false'>"
"<text font='text_button' "
"text_color='color_button' "
"vertical_align='center' "
"horizontal_align='center' "
-"/> "
+"/>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='button_hover' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='button_hover' cache='false'>"
"<text font='text_button' "
"text_color='color_button_hover' "
"vertical_align='center' "
"horizontal_align='center' "
-"/> "
+"/>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='button_disabled' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='button_disabled' cache='false'>"
"<text font='text_button' "
"text_color='color_button_disabled' "
"vertical_align='center' "
"horizontal_align='center' "
-"/> "
+"/>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='checkbox_disabled' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='checkbox_disabled' cache='false'>"
"<text font='text_default' "
"text_color='color_normal_disabled' "
"vertical_align='top' "
"horizontal_align='left' "
-"/> "
+"/>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='checkbox_selected' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='checkbox_selected' cache='false'>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='top' "
"horizontal_align='left' "
-"/> "
+"/>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
+"/>"
"<drawstep func='cross' "
"fill='foreground' "
"stroke='2' "
"fg_color='green' "
-"/> "
-"</drawdata> "
-"<drawdata id='checkbox_default' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='checkbox_default' cache='false'>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='top' "
"horizontal_align='left' "
-"/> "
+"/>"
"<drawstep func='bevelsq' "
"bevel='2' "
"fill='none' "
-"/> "
-"</drawdata> "
-"<drawdata id='radiobutton_default' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='radiobutton_default' cache='false'>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
+"/>"
"<drawstep func='circle' "
"width='7' "
"height='7' "
@@ -556,14 +556,14 @@
"bg_color='darkgrey' "
"xpos='0' "
"ypos='0' "
-"/> "
-"</drawdata> "
-"<drawdata id='radiobutton_selected' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='radiobutton_selected' cache='false'>"
"<text font='text_default' "
"text_color='color_normal' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
+"/>"
"<drawstep func='circle' "
"width='7' "
"height='7' "
@@ -572,7 +572,7 @@
"fill='none' "
"xpos='0' "
"ypos='0' "
-"/> "
+"/>"
"<drawstep func='circle' "
"width='7' "
"height='7' "
@@ -581,14 +581,14 @@
"fill='foreground' "
"xpos='2' "
"ypos='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='radiobutton_disabled' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='radiobutton_disabled' cache='false'>"
"<text font='text_default' "
"text_color='color_normal_disabled' "
"vertical_align='center' "
"horizontal_align='left' "
-"/> "
+"/>"
"<drawstep func='circle' "
"width='7' "
"height='7' "
@@ -597,2510 +597,2510 @@
"fill='background' "
"xpos='0' "
"ypos='0' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_default' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_default' cache='false'>"
"<drawstep func='bevelsq' "
"bevel='2' "
-"/> "
-"</drawdata> "
-"<drawdata id='widget_small' cache='false'> "
+"/>"
+"</drawdata>"
+"<drawdata id='widget_small' cache='false'>"
"<drawstep func='square' "
"stroke='0' "
-"/> "
-"</drawdata> "
-"</render_info> "
-"<layout_info resolution='y>399'> "
-"<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='ShowLauncherLogo' value='0'/> "
-"<def var='ShowGlobalMenuLogo' value='0'/> "
-"<def var='ShowSearchPic' value='0'/> "
-"<def var='ShowChooserPics' value='0'/> "
-"<def var='ShowChooserPageDisplay' value='1'/> "
-"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/> "
-"<def var='RecorderDialog.ExtInfo.Visible' value='1'/> "
-"<def var='OnScreenDialog.ShowPics' value='0'/> "
-"<def var='KeyMapper.Spacing' value='10'/> "
-"<def var='KeyMapper.LabelWidth' value='100'/> "
-"<def var='KeyMapper.ButtonWidth' value='80'/> "
-"<def var='Tooltip.MaxWidth' value='200'/> "
+"/>"
+"</drawdata>"
+"</render_info>"
+"<layout_info resolution='y>399'>"
+"<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='ShowLauncherLogo' value='0'/>"
+"<def var='ShowGlobalMenuLogo' value='0'/>"
+"<def var='ShowSearchPic' value='0'/>"
+"<def var='ShowChooserPics' value='0'/>"
+"<def var='ShowChooserPageDisplay' value='1'/>"
+"<def var='SaveLoadChooser.ExtInfo.Visible' value='1'/>"
+"<def var='RecorderDialog.ExtInfo.Visible' value='1'/>"
+"<def var='OnScreenDialog.ShowPics' value='0'/>"
+"<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='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='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,19' "
-"/> "
+"/>"
"<widget name='Checkbox' "
"size='-1,14' "
-"/> "
+"/>"
"<widget name='Radiobutton' "
"size='-1,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ListWidget' "
"padding='5,0,8,0' "
-"/> "
+"/>"
"<widget name='PopUpWidget' "
"padding='7,5,0,0' "
-"/> "
+"/>"
"<widget name='EditTextWidget' "
"padding='5,5,0,0' "
-"/> "
+"/>"
"<widget name='Console' "
"padding='7,5,5,5' "
-"/> "
+"/>"
"<widget name='Scrollbar' "
"size='15,0' "
-"/> "
+"/>"
"<widget name='TabWidget.Tab' "
"size='75,27' "
"padding='0,0,8,0' "
-"/> "
+"/>"
"<widget name='TabWidget.Body' "
"padding='0,0,0,0' "
-"/> "
+"/>"
"<widget name='TabWidget.NavButton' "
"size='15,18' "
"padding='0,3,4,0' "
-"/> "
+"/>"
"<widget name='EditRecordLabel' "
"size='60,25' "
-"/> "
+"/>"
"<widget name='EditRecord' "
"size='240,25' "
-"/> "
-"</globals> "
-"<dialog name='Launcher' overlays='screen'> "
-"<layout type='vertical' center='true' padding='16,16,8,8'> "
+"/>"
+"</globals>"
+"<dialog name='Launcher' overlays='screen'>"
+"<layout type='vertical' center='true' padding='16,16,8,8'>"
"<widget name='Version' "
"height='Globals.Line.Height' "
"textalign='center' "
-"/> "
-"<layout type='horizontal' spacing='5' padding='10,0,0,0'> "
+"/>"
+"<layout type='horizontal' spacing='5' padding='10,0,0,0'>"
"<widget name='SearchDesc' "
"width='60' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='Search' "
"width='150' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SearchClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"<space /> "
-"</layout> "
-"<widget name='GameList'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"<space />"
+"</layout>"
+"<widget name='GameList'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='LoadGameButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='AddGameButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='EditGameButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='RemoveGameButton' "
"height='20' "
-"/> "
-"</layout> "
-"<space size='4'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<space size='4'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='QuitButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='AboutButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='OptionsButton' "
"height='20' "
-"/> "
+"/>"
"<widget name='StartButton' "
"height='20' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='Browser' overlays='Dialog.Launcher.GameList' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='Headline' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Path' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List'/> "
-"<layout type='vertical' padding='0,0,16,0'> "
+"/>"
+"<widget name='List'/>"
+"<layout type='vertical' padding='0,0,16,0'>"
"<widget name='Hidden' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Up' "
"type='Button' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Choose' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,16'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions' overlays='Dialog.Launcher.GameList' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='16,16,16,16'>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</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>"
+"</layout>"
+"</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'>"
"<widget name='grModePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='grModePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='grRenderPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='grRenderPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='grAspectCheckbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='grFullscreenCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='auMidiPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auMidiPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='auOPLPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auOPLPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='auSampleRatePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auSampleRatePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
-"/> "
+"/>"
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
-"/> "
+"/>"
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='vcMusicText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcMusicSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcMusicLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='vcSfxText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSfxSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSfxLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSpeechSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSpeechLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"</layout> "
-"<layout type='vertical' padding='24,0,24,0' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"<layout type='vertical' padding='24,0,24,0' center='true'>"
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</layout> "
-"</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>"
+"</layout>"
+"</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'>"
"<widget name='auPrefGmPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auPrefGmPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='mcFontButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='mcFontPath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='mcFontClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcMixedCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='mcMidiGainText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='mcMidiGainSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='mcMidiGainLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcFluidSynthSettings' "
"width='200' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='auPrefMt32PopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auPrefMt32Popup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcMt32Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='mcGSCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='SaveButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='SavePath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SavePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='ThemeButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ThemePath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ThemePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='ExtraButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ExtraPath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ExtraPathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='PluginsButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='PluginsPath' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</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>"
+"</layout>"
+"</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'>"
"<widget name='ThemeButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='CurTheme' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='RendererPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='RendererPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='AutosavePeriodPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='AutosavePeriodPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='GuiLanguagePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='GuiLanguagePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='KeysButton' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Action' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List'/> "
+"/>"
+"<widget name='List'/>"
"<widget name='Mapping' "
"height='Globals.Line.Height' "
-"/> "
-"<space size='Globals.Line.Height'/> "
-"<layout type='horizontal'> "
+"/>"
+"<space size='Globals.Line.Height'/>"
+"<layout type='horizontal'>"
"<widget name='Map' "
"type='Button' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<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='16,16,16,4'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<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='16,16,16,4'>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Graphics' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Graphics' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Audio' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Audio' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_MIDI' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_MIDI' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_MT32' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_MT32' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Volume' /> "
-"</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'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Volume' />"
+"</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'>"
"<widget name='Id' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Domain' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='Name' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Desc' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LangPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LangPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='PlatformPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='PlatformPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='Savepath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='SavepathText' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SavePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='Extrapath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ExtrapathText' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ExtraPathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='Gamepath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='GamepathText' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='16,16,16,16'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'>"
+"<layout type='vertical' padding='16,16,16,16'>"
"<widget name='customOption1Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption2Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption3Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption4Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption5Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption6Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption7Checkbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalMenu' overlays='screen_center'> "
-"<layout type='vertical' padding='16,16,16,16' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalMenu' overlays='screen_center'>"
+"<layout type='vertical' padding='16,16,16,16' center='true'>"
"<widget name='Title' "
"width='210' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Version' "
"width='210' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Resume' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"<space size='10'/> "
+"/>"
+"<space size='10'/>"
"<widget name='Load' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Save' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"<space size='10'/> "
+"/>"
+"<space size='10'/>"
"<widget name='Options' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Help' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='About' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"<space size='10'/> "
+"/>"
+"<space size='10'/>"
"<widget name='RTL' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Quit' "
"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'> "
-"<layout type='vertical' padding='0,0,0,0' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"</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'>"
"<widget name='vcMusicText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcMusicSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcMusicLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='vcSfxText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSfxSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSfxLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSpeechSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSpeechLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"</layout> "
-"<layout type='vertical' padding='24,24,24,24' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"<layout type='vertical' padding='24,24,24,24' center='true'>"
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
"width='80' "
-"/> "
-"</layout> "
-"</layout> "
-"<space size='8' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"</layout>"
+"<space size='8' />"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
"width='100' "
-"/> "
+"/>"
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
"width='100' "
-"/> "
+"/>"
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
"width='100' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<space size='60'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10'> "
+"/>"
+"</layout>"
+"<space size='60'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10'>"
"<widget name='Keys' "
"type='Button' "
-"/> "
-"<space size='Globals.Button.Width' /> "
+"/>"
+"<space size='Globals.Button.Width' />"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='16,16,16,16'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='16,16,16,16'>"
+"<space/>"
"<widget name='ResetSettings' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='VoiceCountText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='VoiceCountSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='VoiceCountLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LevelText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LevelSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='LevelLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='SpeedText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='SpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='SpeedLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='DepthText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='DepthSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='DepthLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='WaveFormTypeText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='WaveFormType' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='RoomSizeText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='RoomSizeSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='RoomSizeLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='DampingText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='DampingSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='DampingLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='WidthText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='WidthSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='WidthLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LevelText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LevelSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='LevelLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='8'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='InterpolationText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Interpolation' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,32' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='SaveLoadChooser' overlays='screen' inset='8' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,32' center='true'>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Title' "
"height='Globals.Line.Height' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='PageDisplay' "
"width='200' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,16' spacing='16'> "
-"<widget name='List' /> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,16' spacing='16'>"
+"<widget name='List' />"
"<widget name='Thumbnail' "
"width='180' "
"height='200' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='ListSwitch' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GridSwitch' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Delete' "
"type='Button' "
-"/> "
-"<space size='32'/> "
+"/>"
+"<space size='32'/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Choose' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='SavenameDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='SavenameDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='DescriptionText' "
"width='320' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Description' "
"height='19' "
-"/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,16,0'>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
-"<space size='96'/> "
+"/>"
+"<space size='96'/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,32' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='RecorderDialog' 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'> "
-"<widget name='List' /> "
-"<layout type='vertical' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,16' spacing='16'>"
+"<widget name='List' />"
+"<layout type='vertical' padding='0,0,0,0'>"
"<widget name='Thumbnail' "
"width='180' "
"height='170' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='NextScreenShotButton' "
"width='25' "
"height='25' "
-"/> "
+"/>"
"<widget name='currentScreenshot' "
"width='125' "
"height='25' "
"textalign='center' "
-"/> "
+"/>"
"<widget name='PreviousScreenShotButton' "
"width='25' "
"height='25' "
-"/> "
-"</layout> "
-"<widget name='Author' height='Globals.Line.Height' /> "
-"<widget name='Notes' height='Globals.Line.Height' /> "
-"</layout> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<widget name='Author' height='Globals.Line.Height' />"
+"<widget name='Notes' height='Globals.Line.Height' />"
+"</layout>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Delete' "
"type='Button' "
-"/> "
-"<space size='16'/> "
+"/>"
+"<space size='16'/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
-"<space size='16'/> "
+"/>"
+"<space size='16'/>"
"<widget name='Edit' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Record' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Playback' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='OnScreenDialog' overlays='screen_center'> "
-"<layout type='horizontal' spacing='5' padding='5,3,5,3' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='OnScreenDialog' overlays='screen_center'>"
+"<layout type='horizontal' spacing='5' padding='5,3,5,3' center='true'>"
"<widget name='StopButton' "
"width='32' "
"height='32' "
-"/> "
+"/>"
"<widget name='EditButton' "
"width='32' "
"height='32' "
-"/> "
+"/>"
"<widget name='SwitchModeButton' "
"width='32' "
"height='32' "
-"/> "
+"/>"
"<widget name='FastReplayButton' "
"width='32' "
"height='32' "
-"/> "
+"/>"
"<widget name='TimeLabel' "
"width='50' "
"height='30' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='EditRecordDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='EditRecordDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Title' "
"width='320' "
"height='Globals.Line.Height' "
-"/> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='AuthorLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='AuthorEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='NameLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='NameEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='NotesLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='NotesEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='OK' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='ScummHelp' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='ScummHelp' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Title' "
"width='320' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='HelpText' "
"height='200' "
-"/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,16,0'>"
"<widget name='Prev' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Next' "
"type='Button' "
-"/> "
-"<space size='32'/> "
+"/>"
+"<space size='32'/>"
"<widget name='Close' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Description1' "
"width='320' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Description2' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Standard' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Practice' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Expert' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,32,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='MassAdd' overlays='screen_center' shading='dim'>"
+"<layout type='vertical' padding='8,8,32,8' center='true'>"
"<widget name='DirProgressText' "
"width='480' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GameProgressText' "
"width='480' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GameList' "
"width='480' "
"height='250' "
-"/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
+"/>"
+"<layout type='horizontal' padding='8,8,8,8'>"
"<widget name='Ok' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='KeyMapper' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,32,8' spacing='10' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='KeyMapper' overlays='screen_center' shading='dim'>"
+"<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='400' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='KeymapArea' "
"width='600' "
"height='280' "
-"/> "
+"/>"
"<widget name='Close' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='Predictive' overlays='screen_center'> "
-"<layout type='vertical' padding='5,5,5,5' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='Predictive' overlays='screen_center'>"
+"<layout type='vertical' padding='5,5,5,5' center='true'>"
"<widget name='Headline' "
"height='Globals.Line.Height' "
"width='210' "
"textalign='center' "
-"/> "
-"<layout type='horizontal' padding='5,5,5,5'> "
+"/>"
+"<layout type='horizontal' padding='5,5,5,5'>"
"<widget name='Word' "
"width='190' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Delete' "
"width='20' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<space size='5' /> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<space size='5' />"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button1' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button2' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button3' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button4' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button5' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button6' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button7' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button8' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button9' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Pre' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Button0' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Next' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"<space size='5' /> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<space size='5' />"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Add' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"<space size='22'/> "
+"/>"
+"<space size='22'/>"
"<widget name='Cancel' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='OK' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"</layout_info> "
-"<layout_info resolution='y<400'> "
-"<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='ShowLauncherLogo' value='0'/> "
-"<def var='ShowGlobalMenuLogo' value='0'/> "
-"<def var='ShowSearchPic' value='0'/> "
-"<def var='ShowChooserPics' value='0'/> "
-"<def var='ShowChooserPageDisplay' value='0'/> "
-"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/> "
-"<def var='RecorderDialog.ExtInfo.Visible' value='0'/> "
-"<def var='OnScreenDialog.ShowPics' 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'/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"</layout_info>"
+"<layout_info resolution='y<400'>"
+"<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='ShowLauncherLogo' value='0'/>"
+"<def var='ShowGlobalMenuLogo' value='0'/>"
+"<def var='ShowSearchPic' value='0'/>"
+"<def var='ShowChooserPics' value='0'/>"
+"<def var='ShowChooserPageDisplay' value='0'/>"
+"<def var='SaveLoadChooser.ExtInfo.Visible' value='0'/>"
+"<def var='RecorderDialog.ExtInfo.Visible' value='0'/>"
+"<def var='OnScreenDialog.ShowPics' 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' /> "
+"<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='18,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='PopUp' "
"size='-1,15' "
-"/> "
+"/>"
"<widget name='Checkbox' "
"size='-1,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Radiobutton' "
"size='-1,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ListWidget' "
"padding='5,0,0,0' "
-"/> "
+"/>"
"<widget name='PopUpWidget' "
"padding='7,5,0,0' "
-"/> "
+"/>"
"<widget name='EditTextWidget' "
"padding='5,5,0,0' "
-"/> "
+"/>"
"<widget name='Console' "
"padding='7,5,5,5' "
-"/> "
+"/>"
"<widget name='Scrollbar' "
"size='9,0' "
-"/> "
+"/>"
"<widget name='TabWidget.Tab' "
"size='45,16' "
"padding='0,0,2,0' "
-"/> "
+"/>"
"<widget name='TabWidget.Body' "
"padding='0,0,0,-8' "
-"/> "
+"/>"
"<widget name='TabWidget.NavButton' "
"size='32,18' "
"padding='0,0,1,0' "
-"/> "
+"/>"
"<widget name='EditRecordLabel' "
"size='60,Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='EditRecord' "
"size='120,15' "
-"/> "
-"</globals> "
-"<dialog name='Launcher' overlays='screen'> "
-"<layout type='vertical' center='true' padding='6,6,2,2'> "
+"/>"
+"</globals>"
+"<dialog name='Launcher' overlays='screen'>"
+"<layout type='vertical' center='true' padding='6,6,2,2'>"
"<widget name='Version' "
"height='Globals.Line.Height' "
"textalign='center' "
-"/> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,0'>"
"<widget name='SearchDesc' "
"width='50' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='Search' "
"width='150' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SearchClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"<space /> "
-"</layout> "
-"<widget name='GameList'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"<space />"
+"</layout>"
+"<widget name='GameList'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='LoadGameButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='AddGameButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='EditGameButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='RemoveGameButton' "
"height='12' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='8'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='8'>"
"<widget name='QuitButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='AboutButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='OptionsButton' "
"height='12' "
-"/> "
+"/>"
"<widget name='StartButton' "
"height='12' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='Browser' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,0,4'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='Browser' overlays='screen' inset='8' shading='dim'>"
+"<layout type='vertical' padding='8,8,0,4'>"
"<widget name='Headline' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Path' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List'/> "
-"<layout type='vertical' padding='0,0,8,0'> "
+"/>"
+"<widget name='List'/>"
+"<layout type='vertical' padding='0,0,8,0'>"
"<widget name='Hidden' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Up' "
"type='Button' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Choose' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions' overlays='screen' inset='16' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='8,8,8,8'>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</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>"
+"</layout>"
+"</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'>"
"<widget name='grModePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='grModePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='grRenderPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='grRenderPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='grAspectCheckbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='grFullscreenCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='auMidiPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auMidiPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='auOPLPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auOPLPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='auSampleRatePopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auSampleRatePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='3' center='true'>"
"<widget name='subToggleDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
-"/> "
+"/>"
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
-"/> "
+"/>"
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='vcMusicText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcMusicSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcMusicLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcSfxText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSfxSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSfxLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSpeechSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSpeechLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
-"<space size='110' /> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
+"<space size='110' />"
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='16,16,16,16' spacing='6'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='16,16,16,16' spacing='6'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='auPrefGmPopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auPrefGmPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'>"
"<widget name='mcFontButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='mcFontPath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='mcFontClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<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' spacing='6' center='true'>"
"<widget name='mcMidiGainText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='mcMidiGainSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='mcMidiGainLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcFluidSynthSettings' "
"width='150' "
"height='Globals.Button.Height' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='auPrefMt32PopupDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='auPrefMt32Popup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='mcMt32Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='mcGSCheckbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='SaveButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='SavePath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SavePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='ThemeButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ThemePath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ThemePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='ExtraButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ExtraPath' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ExtraPathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16'>"
"<widget name='PluginsButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='PluginsPath' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</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>"
+"</layout>"
+"</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'>"
"<widget name='ThemeButton' "
"type='Button' "
-"/> "
+"/>"
"<widget name='CurTheme' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='RendererPopupDesc' "
"width='80' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='RendererPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='AutosavePeriodPopupDesc' "
"width='80' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='AutosavePeriodPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='GuiLanguagePopupDesc' "
"width='80' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='GuiLanguagePopup' "
"type='PopUp' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='KeysButton' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Action' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List'/> "
+"/>"
+"<widget name='List'/>"
"<widget name='Mapping' "
"height='Globals.Line.Height' "
-"/> "
-"<space size='Globals.Line.Height'/> "
-"<layout type='horizontal'> "
+"/>"
+"<space size='Globals.Line.Height'/>"
+"<layout type='horizontal'>"
"<widget name='Map' "
"type='Button' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<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='8,8,8,8'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<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='8,8,8,8'>"
+"<space/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Graphics' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Graphics' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Graphics' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Audio' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Audio' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_MIDI' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_MIDI' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_MIDI' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_MT32' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_MT32' /> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_MT32' />"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Volume' overlays='Dialog.GlobalOptions.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<import layout='Dialog.GlobalOptions_Volume' /> "
-"</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'> "
+"/>"
+"<import layout='Dialog.GlobalOptions_Volume' />"
+"</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'>"
"<widget name='Id' "
"width='35' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='Domain' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='Name' "
"width='35' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='Desc' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<space size='8'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<space size='8'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='LangPopupDesc' "
"width='60' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='LangPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='PlatformPopupDesc' "
"width='60' "
"height='Globals.Line.Height' "
"textalign='right' "
-"/> "
+"/>"
"<widget name='PlatformPopup' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</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>"
+"</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'>"
"<widget name='Savepath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='SavepathText' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='SavePathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'>"
"<widget name='Extrapath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='ExtrapathText' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='ExtraPathClearButton' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='16' center='true'>"
"<widget name='Gamepath' "
"type='Button' "
-"/> "
+"/>"
"<widget name='GamepathText' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='GameOptions_Engine' overlays='Dialog.GameOptions.TabWidget' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='customOption1Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption2Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption3Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption4Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption5Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption6Checkbox' "
"type='Checkbox' "
-"/> "
+"/>"
"<widget name='customOption7Checkbox' "
"type='Checkbox' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='GlobalMenu' overlays='screen_center'> "
-"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='GlobalMenu' overlays='screen_center'>"
+"<layout type='vertical' padding='2,2,4,6' center='true' spacing='6'>"
"<widget name='Title' "
"width='160' "
"height='4' "
-"/> "
+"/>"
"<widget name='Version' "
"width='160' "
"height='4' "
-"/> "
-"<space size='1'/> "
+"/>"
+"<space size='1'/>"
"<widget name='Load' "
"width='120' "
"height='12' "
-"/> "
+"/>"
"<widget name='Save' "
"width='120' "
"height='12' "
-"/> "
-"<space size='1'/> "
+"/>"
+"<space size='1'/>"
"<widget name='Options' "
"width='120' "
"height='12' "
-"/> "
+"/>"
"<widget name='Help' "
"width='120' "
"height='12' "
-"/> "
+"/>"
"<widget name='About' "
"width='120' "
"height='12' "
-"/> "
-"<space size='1'/> "
+"/>"
+"<space size='1'/>"
"<widget name='Resume' "
"width='120' "
"height='12' "
-"/> "
+"/>"
"<widget name='RTL' "
"width='120' "
"height='12' "
-"/> "
+"/>"
"<widget name='Quit' "
"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' spacing='6' center='true'> "
+"/>"
+"</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'>"
"<widget name='vcMusicText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcMusicSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcMusicLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcSfxText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSfxSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSfxLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='vcSpeechText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='vcSpeechSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='vcSpeechLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
-"<space size='110' /> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
+"<space size='110' />"
"<widget name='vcMuteCheckbox' "
"type='Checkbox' "
"width='80' "
-"/> "
-"</layout> "
-"<layout type='vertical' padding='0,0,0,0' spacing='1' center='true'> "
+"/>"
+"</layout>"
+"<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'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='subToggleSpeechOnly' "
"type='Radiobutton' "
"width='90' "
-"/> "
+"/>"
"<widget name='subToggleSubOnly' "
"type='Radiobutton' "
"width='90' "
-"/> "
+"/>"
"<widget name='subToggleSubBoth' "
"type='Radiobutton' "
"width='90' "
-"/> "
-"</layout> "
-"</layout> "
-"<space size='2' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"<space size='2' />"
+"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
"<widget name='subSubtitleSpeedDesc' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='subSubtitleSpeedLabel' "
"type='SmallLabel' "
-"/> "
-"</layout> "
-"<space size='16'/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='4'> "
+"/>"
+"</layout>"
+"<space size='16'/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='4'>"
"<widget name='Keys' "
"type='Button' "
-"/> "
-"<space size='Globals.Button.Width' /> "
+"/>"
+"<space size='Globals.Button.Width' />"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'> "
-"<layout type='vertical' padding='0,0,0,0'> "
-"<widget name='TabWidget'/> "
-"<layout type='horizontal' padding='8,8,8,8'> "
-"<space/> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings' overlays='GlobalOptions' shading='dim'>"
+"<layout type='vertical' padding='0,0,0,0'>"
+"<widget name='TabWidget'/>"
+"<layout type='horizontal' padding='8,8,8,8'>"
+"<space/>"
"<widget name='ResetSettings' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Chorus' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='VoiceCountText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='VoiceCountSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='VoiceCountLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LevelText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LevelSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='LevelLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='SpeedText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='SpeedSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='SpeedLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='DepthText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='DepthSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='DepthLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='WaveFormTypeText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='WaveFormType' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Reverb' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
"<widget name='EnableTabCheckbox' "
"type='Checkbox' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='RoomSizeText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='RoomSizeSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='RoomSizeLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='DampingText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='DampingSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='DampingLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='WidthText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='WidthSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='WidthLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='LevelText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='LevelSlider' "
"type='Slider' "
-"/> "
+"/>"
"<widget name='LevelLabel' "
"width='32' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='6'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='FluidSynthSettings_Misc' overlays='Dialog.FluidSynthSettings.TabWidget'>"
+"<layout type='vertical' padding='8,8,8,8' spacing='6'>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
"<widget name='InterpolationText' "
"type='OptionsLabel' "
-"/> "
+"/>"
"<widget name='Interpolation' "
"type='PopUp' "
-"/> "
-"</layout> "
-"</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'/> "
-"<widget name='List' /> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"/>"
+"</layout>"
+"</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'/>"
+"<widget name='List' />"
+"<layout type='horizontal' padding='0,0,16,0'>"
"<widget name='ListSwitch' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GridSwitch' "
"height='Globals.Line.Height' "
"width='Globals.Line.Height' "
-"/> "
-"<space/> "
+"/>"
+"<space/>"
"<widget name='Delete' "
"type='Button' "
-"/> "
-"<space size='16'/> "
+"/>"
+"<space size='16'/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Choose' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='SavenameDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='SavenameDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='DescriptionText' "
"width='180' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Description' "
"height='19' "
-"/> "
-"<layout type='horizontal' padding='0,0,16,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,16,0'>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Ok' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,4' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='RecorderDialog' overlays='screen' inset='8' shading='dim'>"
+"<layout type='vertical' padding='8,8,8,4' center='true'>"
"<widget name='Title' "
"height='Globals.Line.Height' "
-"/> "
-"<widget name='List' /> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='2'> "
+"/>"
+"<widget name='List' />"
+"<layout type='horizontal' padding='0,0,0,0' spacing='2'>"
"<widget name='Edit' "
"type='Button' "
-"/> "
-"<space /> "
+"/>"
+"<space />"
"<widget name='Record' "
"type='Button' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='2'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='0,0,0,0' spacing='2'>"
"<widget name='Delete' "
"type='Button' "
-"/> "
-"<space /> "
+"/>"
+"<space />"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Playback' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='OnScreenDialog' overlays='screen_center'> "
-"<layout type='horizontal' spacing='5' padding='3,2,3,2' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='OnScreenDialog' overlays='screen_center'>"
+"<layout type='horizontal' spacing='5' padding='3,2,3,2' center='true'>"
"<widget name='StopButton' "
"width='16' "
"height='16' "
-"/> "
+"/>"
"<widget name='EditButton' "
"width='16' "
"height='16' "
-"/> "
+"/>"
"<widget name='SwitchModeButton' "
"width='16' "
"height='16' "
-"/> "
+"/>"
"<widget name='FastReplayButton' "
"width='16' "
"height='16' "
-"/> "
+"/>"
"<widget name='TimeLabel' "
"width='50' "
"height='16' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='EditRecordDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='EditRecordDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Title' "
"height='Globals.Line.Height' "
-"/> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='AuthorLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='AuthorEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='NameLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='NameEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,10'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,10'>"
"<widget name='NotesLabel' "
"type='EditRecordLabel' "
-"/> "
+"/>"
"<widget name='NotesEdit' "
"type='EditRecord' "
-"/> "
-"</layout> "
-"<layout type='horizontal' spacing='5' padding='0,0,0,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' spacing='5' padding='0,0,0,0'>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
+"/>"
"<widget name='OK' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='ScummHelp' overlays='screen'> "
-"<layout type='vertical' padding='8,8,8,8'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='ScummHelp' overlays='screen'>"
+"<layout type='vertical' padding='8,8,8,8'>"
"<widget name='Title' "
"width='180' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='HelpText' "
"height='140' "
-"/> "
-"<layout type='horizontal' padding='0,0,0,0'> "
+"/>"
+"<layout type='horizontal' padding='0,0,0,0'>"
"<widget name='Prev' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Next' "
"type='Button' "
-"/> "
-"<space size='32'/> "
+"/>"
+"<space size='32'/>"
"<widget name='Close' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'> "
-"<layout type='vertical' padding='8,8,8,8' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='LoomTownsDifficultyDialog' overlays='screen_center'>"
+"<layout type='vertical' padding='8,8,8,8' center='true'>"
"<widget name='Description1' "
"width='280' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Description2' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='Standard' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Practice' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Expert' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='MassAdd' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='4,4,16,4' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='MassAdd' overlays='screen_center' shading='dim'>"
+"<layout type='vertical' padding='4,4,16,4' center='true'>"
"<widget name='DirProgressText' "
"width='280' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GameProgressText' "
"width='280' "
"height='Globals.Line.Height' "
-"/> "
+"/>"
"<widget name='GameList' "
"width='280' "
"height='100' "
-"/> "
-"<layout type='horizontal' padding='4,4,4,4'> "
+"/>"
+"<layout type='horizontal' padding='4,4,4,4'>"
"<widget name='Ok' "
"type='Button' "
-"/> "
+"/>"
"<widget name='Cancel' "
"type='Button' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"<dialog name='KeyMapper' overlays='screen_center' shading='dim'> "
-"<layout type='vertical' padding='8,8,8,8' spacing='10' center='true'> "
-"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"<dialog name='KeyMapper' overlays='screen_center' shading='dim'>"
+"<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='150' "
"height='Globals.Line.Height' "
-"/> "
-"</layout> "
+"/>"
+"</layout>"
"<widget name='KeymapArea' "
"width='300' "
"height='120' "
-"/> "
+"/>"
"<widget name='Close' "
"type='Button' "
-"/> "
-"</layout> "
-"</dialog> "
-"<dialog name='Predictive' overlays='screen_center'> "
-"<layout type='vertical' padding='1,1,1,1' center='true'> "
+"/>"
+"</layout>"
+"</dialog>"
+"<dialog name='Predictive' overlays='screen_center'>"
+"<layout type='vertical' padding='1,1,1,1' center='true'>"
"<widget name='Headline' "
"height='Globals.Line.Height' "
"width='150' "
"textalign='center' "
-"/> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Word' "
"width='120' "
"height='Globals.Button.Height' "
-"/> "
+"/>"
"<widget name='Delete' "
"width='20' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button1' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button2' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button3' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button4' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button5' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button6' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,3'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,3'>"
"<widget name='Button7' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button8' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button9' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<layout type='horizontal' padding='3,3,3,0'> "
+"/>"
+"</layout>"
+"<layout type='horizontal' padding='3,3,3,0'>"
"<widget name='Pre' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Button0' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Next' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"<space size='3' /> "
-"<layout type='horizontal' padding='3,3,0,3'> "
+"/>"
+"</layout>"
+"<space size='3' />"
+"<layout type='horizontal' padding='3,3,0,3'>"
"<widget name='Add' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='Cancel' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
+"/>"
"<widget name='OK' "
"width='Globals.Predictive.Button.Width' "
"height='Globals.Predictive.Button.Height' "
-"/> "
-"</layout> "
-"</layout> "
-"</dialog> "
-"</layout_info> "
+"/>"
+"</layout>"
+"</layout>"
+"</dialog>"
+"</layout_info>"
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 4154c6c33a..1085aa64a4 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 0f10003e94..e40e8b1e26 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx
index 1b3bcea0d6..3a1ec5a5f0 100644
--- a/gui/themes/scummmodern/scummmodern_gfx.stx
+++ b/gui/themes/scummmodern/scummmodern_gfx.stx
@@ -38,6 +38,14 @@
rgb = '203, 126, 107'
/>
+ <color name = 'brightredborder'
+ rgb = '238, 213, 207'
+ />
+
+ <color name = 'darkredborder'
+ rgb = '30, 7, 1'
+ />
+
<!-- Disabled button/slider -->
<color name = 'darkeneddarkred'
rgb = '120, 28, 0'
@@ -73,7 +81,7 @@
rgb = '255, 255, 255'
/>
<color name = 'shadowcolor'
- rgb = '63, 60, 17'
+ rgb = '105, 101, 86'
/>
<color name = 'darkgray'
rgb = '176, 168, 144'
@@ -170,6 +178,10 @@
color = '128, 128, 128'
/>
+ <text_color id = 'color_button_hover'
+ color = 'white'
+ />
+
<text_color id = 'color_alternative_inverted'
color = 'white'
/>
@@ -186,10 +198,6 @@
color = 'white'
/>
- <text_color id = 'color_button_hover'
- color = '255, 214, 84'
- />
-
<text_color id = 'color_button_disabled'
color = '192, 192, 192'
/>
@@ -232,7 +240,7 @@
stroke = '0'
gradient_start = 'darkorange'
gradient_end = 'brightorange'
- shadow = '3'
+ shadow = '7'
gradient_factor = '3'
/>
</drawdata>
@@ -466,7 +474,7 @@
fg_color = 'lightgray2'
fill = 'background'
bg_color = 'xtrabrightred'
- shadow = '2'
+ shadow = '1'
/>
<drawstep func = 'triangle'
@@ -505,7 +513,7 @@
fg_color = 'lightgray2'
fill = 'background'
bg_color = 'xtrabrightred'
- shadow = '2'
+ shadow = '1'
/>
<drawstep func = 'triangle'
@@ -663,7 +671,7 @@
fg_color = 'lightgray2'
fill = 'background'
bg_color = 'xtrabrightred'
- shadow = '2'
+ shadow = '1'
/>
<drawstep func = 'triangle'
@@ -716,7 +724,7 @@
gradient_start = 'blandyellow'
gradient_end = 'xtrabrightred'
fill = 'gradient'
- shadow = '3'
+ shadow = '7'
/>
</drawdata>
@@ -737,7 +745,7 @@
gradient_start = 'blandyellow'
gradient_end = 'xtrabrightred'
gradient_factor = '4'
- shadow = '3'
+ shadow = '7'
/>
</drawdata>
@@ -783,18 +791,18 @@
stroke = '1'
fill = 'gradient'
shadow = '0'
- fg_color = 'shadowcolor'
+ fg_color = 'darkredborder'
gradient_start = 'brightred'
gradient_end = 'darkred'
bevel = '1'
- bevel_color = '237, 169, 72'
+ bevel_color = 'brightredborder'
/>
</drawdata>
<!-- Hovered button -->
<drawdata id = 'button_hover' cache = 'false'>
<text font = 'text_button'
- text_color = 'color_button_hover'
+ text_color = 'color_button'
vertical_align = 'center'
horizontal_align = 'center'
/>
@@ -803,11 +811,11 @@
stroke = '1'
fill = 'gradient'
shadow = '0'
- fg_color = 'shadowcolor'
+ fg_color = 'darkredborder'
gradient_start = 'brightpink'
gradient_end = 'darkpink'
bevel = '1'
- bevel_color = 'xtrabrightred'
+ bevel_color = 'brightredborder'
/>
</drawdata>
@@ -915,7 +923,7 @@
gradient_factor = '6'
fill = 'gradient'
bg_color = 'xtrabrightred'
- shadow = '3'
+ shadow = '7'
/>
</drawdata>
diff --git a/gui/themes/scummtheme.py b/gui/themes/scummtheme.py
index 4c55fd79de..524e91468e 100755
--- a/gui/themes/scummtheme.py
+++ b/gui/themes/scummtheme.py
@@ -37,9 +37,13 @@ def parseSTX(theme_file, def_file):
comm = re.compile("<!--(.*?)-->", re.DOTALL)
head = re.compile("<\?(.*?)\?>")
+ strlitcount = 0
output = ""
for line in theme_file:
- output += line.rstrip("\r\n\t ").lstrip() + " \n"
+ output += line.rstrip("\r\n\t ").lstrip()
+ if not output.endswith('>'):
+ output += ' '
+ output += "\n"
output = re.sub(comm, "", output)
output = re.sub(head, "", output)
@@ -48,7 +52,9 @@ def parseSTX(theme_file, def_file):
for line in output.splitlines():
if line and not line.isspace():
+ strlitcount += len(line)
def_file.write("\"" + line + "\"\n")
+ return strlitcount
def buildDefTheme(themeName):
def_file = open("default.inc", "w")
@@ -57,16 +63,23 @@ def buildDefTheme(themeName):
print ("Cannot open default theme dir.")
def_file.write(""" "<?xml version = '1.0'?>"\n""")
+ strlitcount = 24
for filename in os.listdir(themeName):
filename = os.path.join(themeName, filename)
if os.path.isfile(filename) and filename.endswith(".stx"):
theme_file = open(filename, "r")
- parseSTX(theme_file, def_file)
+ strlitcount += parseSTX(theme_file, def_file)
theme_file.close()
def_file.close()
+ if strlitcount > 65535:
+ print("WARNING: default.inc string literal is of length %d which exceeds the" % strlitcount)
+ print(" maximum length of 65536 that C++ compilers are required to support.")
+ print(" It is likely that bugs will occur dependent on compiler behaviour.")
+ print(" To avoid this, reduce the size of the theme.")
+
def printUsage():
print ("===============================")
print ("ScummVM Theme Generation Script")
diff --git a/gui/widgets/editable.cpp b/gui/widgets/editable.cpp
index 6fae9346b2..667850d6cc 100644
--- a/gui/widgets/editable.cpp
+++ b/gui/widgets/editable.cpp
@@ -277,7 +277,7 @@ void EditableWidget::drawCaret(bool erase) {
int chrWidth = g_gui.getCharWidth(_editString[_caretPos], _font);
const uint last = (_caretPos > 0) ? _editString[_caretPos - 1] : 0;
x += g_gui.getKerningOffset(last, _editString[_caretPos], _font);
- g_gui.theme()->drawText(Common::Rect(x, y, x + chrWidth, y + editRect.height() - 2), chr, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font);
+ g_gui.theme()->drawText(Common::Rect(x, y, x + chrWidth, y + editRect.height() - 2), chr, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
}
}
diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp
index 3677f02e47..52527effd8 100644
--- a/gui/widgets/edittext.cpp
+++ b/gui/widgets/edittext.cpp
@@ -93,11 +93,15 @@ void EditTextWidget::drawWidget() {
// Draw the text
adjustOffset();
- g_gui.theme()->drawText(Common::Rect(_x+2+ _leftPadding,_y+2, _x+_leftPadding+getEditRect().width()+2, _y+_h-2), _editString, _state, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, -_editScrollOffset, false, _font);
+
+ const Common::Rect &r = Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 8, _y + _h);
+ setTextDrawableArea(r);
+
+ g_gui.theme()->drawText(Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 2, _y + _h), _editString, _state, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, -_editScrollOffset, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
}
Common::Rect EditTextWidget::getEditRect() const {
- Common::Rect r(2 + _leftPadding, 2, _w - 2 - _leftPadding - _rightPadding, _h-1);
+ Common::Rect r(2 + _leftPadding, 2, _w - 2 - _leftPadding - _rightPadding, _h - 1);
return r;
}
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index beb68fc969..aee2d88988 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -80,6 +80,13 @@ namespace Video {
#define ID_DUCK MKTAG('D','U','C','K')
#define ID_MPG2 MKTAG('m','p','g','2')
+// Stream Types
+enum {
+ kStreamTypePaletteChange = MKTAG16('p', 'c'),
+ kStreamTypeRawVideo = MKTAG16('d', 'b'),
+ kStreamTypeAudio = MKTAG16('w', 'b')
+};
+
AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _frameRateOverride(0), _soundType(soundType) {
initCommon();
@@ -106,6 +113,12 @@ void AVIDecoder::initCommon() {
memset(&_header, 0, sizeof(_header));
}
+bool AVIDecoder::isSeekable() const {
+ // Only videos with an index can seek
+ // Anyone else who wants to seek is crazy.
+ return isVideoLoaded() && !_indexEntries.empty();
+}
+
bool AVIDecoder::parseNextChunk() {
uint32 tag = _fileStream->readUint32BE();
uint32 size = _fileStream->readUint32LE();
@@ -150,10 +163,10 @@ bool AVIDecoder::parseNextChunk() {
OldIndex indexEntry;
indexEntry.id = _fileStream->readUint32BE();
indexEntry.flags = _fileStream->readUint32LE();
- indexEntry.offset = _fileStream->readUint32LE();
+ indexEntry.offset = _fileStream->readUint32LE() + _movieListStart - 4; // Adjust to absolute
indexEntry.size = _fileStream->readUint32LE();
_indexEntries.push_back(indexEntry);
- debug(0, "Index %d == Tag \'%s\', Offset = %d, Size = %d", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size);
+ debug(0, "Index %d == Tag \'%s\', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags);
}
break;
default:
@@ -187,7 +200,7 @@ void AVIDecoder::handleList(uint32 listSize) {
_decodedHeader = true;
break;
case ID_INFO: // Metadata
- case ID_PRMI: // Unknown (ZEngine)
+ case ID_PRMI: // Unknown metadata, should be safe to ignore
// Ignore metadata
_fileStream->skip(listSize);
return;
@@ -254,21 +267,22 @@ void AVIDecoder::handleStreamHeader(uint32 size) {
if (sHeader.streamHandler == 0)
sHeader.streamHandler = bmInfo.compression;
- AVIVideoTrack *track = new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo);
+ byte *initialPalette = 0;
if (bmInfo.bitCount == 8) {
- byte *palette = const_cast<byte *>(track->getPalette());
+ initialPalette = new byte[256 * 3];
+ memset(initialPalette, 0, 256 * 3);
+
+ byte *palette = initialPalette;
for (uint32 i = 0; i < bmInfo.clrUsed; i++) {
palette[i * 3 + 2] = _fileStream->readByte();
palette[i * 3 + 1] = _fileStream->readByte();
palette[i * 3] = _fileStream->readByte();
_fileStream->readByte();
}
-
- track->markPaletteDirty();
}
- addTrack(track);
+ addTrack(new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo, initialPalette));
} else if (sHeader.streamType == ID_AUDS) {
PCMWaveFormat wvInfo;
wvInfo.tag = _fileStream->readUint16LE();
@@ -383,7 +397,7 @@ void AVIDecoder::readNextPacket() {
}
if (track->getTrackType() == Track::kTrackTypeAudio) {
- if (getStreamType(nextTag) != MKTAG16('w', 'b'))
+ if (getStreamType(nextTag) != kStreamTypeAudio)
error("Invalid audio track tag '%s'", tag2str(nextTag));
assert(chunk);
@@ -391,29 +405,10 @@ void AVIDecoder::readNextPacket() {
} else {
AVIVideoTrack *videoTrack = (AVIVideoTrack *)track;
- if (getStreamType(nextTag) == MKTAG16('p', 'c')) {
+ if (getStreamType(nextTag) == kStreamTypePaletteChange) {
// Palette Change
- assert(chunk);
- byte firstEntry = chunk->readByte();
- uint16 numEntries = chunk->readByte();
- chunk->readUint16LE(); // Reserved
-
- // 0 entries means all colors are going to be changed
- if (numEntries == 0)
- numEntries = 256;
-
- byte *palette = const_cast<byte *>(videoTrack->getPalette());
-
- for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) {
- palette[i * 3] = chunk->readByte();
- palette[i * 3 + 1] = chunk->readByte();
- palette[i * 3 + 2] = chunk->readByte();
- chunk->readByte(); // Flags that don't serve us any purpose
- }
-
- delete chunk;
- videoTrack->markPaletteDirty();
- } else if (getStreamType(nextTag) == MKTAG16('d', 'b')) {
+ videoTrack->loadPaletteFromChunk(chunk);
+ } else if (getStreamType(nextTag) == kStreamTypeRawVideo) {
// TODO: Check if this really is uncompressed. Many videos
// falsely put compressed data in here.
error("Uncompressed AVI frame found");
@@ -424,6 +419,201 @@ void AVIDecoder::readNextPacket() {
}
}
+bool AVIDecoder::rewind() {
+ if (!VideoDecoder::rewind())
+ return false;
+
+ _fileStream->seek(_movieListStart);
+ return true;
+}
+
+bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
+ // Can't seek beyond the end
+ if (time > getDuration())
+ return false;
+
+ // Track down our video track (optionally audio too).
+ // We only support seeking with one track right now.
+ AVIVideoTrack *videoTrack = 0;
+ AVIAudioTrack *audioTrack = 0;
+ int videoIndex = -1;
+ int audioIndex = -1;
+ uint trackID = 0;
+
+ for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++, trackID++) {
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo) {
+ if (videoTrack) {
+ // Already have one
+ // -> Not supported
+ return false;
+ }
+
+ videoTrack = (AVIVideoTrack *)*it;
+ videoIndex = trackID;
+ } else if ((*it)->getTrackType() == Track::kTrackTypeAudio) {
+ if (audioTrack) {
+ // Already have one
+ // -> Not supported
+ return false;
+ }
+
+ audioTrack = (AVIAudioTrack *)*it;
+ audioIndex = trackID;
+ }
+ }
+
+ // Need a video track to go forwards
+ // If there isn't a video track, why would anyone be using AVI then?
+ if (!videoTrack)
+ return false;
+
+ // If we seek directly to the end, just mark the tracks as over
+ if (time == getDuration()) {
+ videoTrack->setCurFrame(videoTrack->getFrameCount() - 1);
+
+ if (audioTrack)
+ audioTrack->resetStream();
+
+ return true;
+ }
+
+ // Get the frame we should be on at this time
+ uint frame = videoTrack->getFrameAtTime(time);
+
+ // Reset any palette, if necessary
+ videoTrack->useInitialPalette();
+
+ int lastKeyFrame = -1;
+ int frameIndex = -1;
+ int lastRecord = -1;
+ uint curFrame = 0;
+
+ // Go through and figure out where we should be
+ // If there's a palette, we need to find the palette too
+ for (uint32 i = 0; i < _indexEntries.size(); i++) {
+ const OldIndex &index = _indexEntries[i];
+
+ if (index.id == ID_REC) {
+ // Keep track of any records we find
+ lastRecord = i;
+ } else {
+ if (getStreamIndex(index.id) != videoIndex)
+ continue;
+
+ uint16 streamType = getStreamType(index.id);
+
+ if (streamType == kStreamTypePaletteChange) {
+ // We need to handle any palette change we see since there's no
+ // flag to tell if this is a "key" palette.
+ // Decode the palette
+ _fileStream->seek(_indexEntries[i].offset + 8);
+ Common::SeekableReadStream *chunk = 0;
+
+ if (_indexEntries[i].size != 0)
+ chunk = _fileStream->readStream(_indexEntries[i].size);
+
+ videoTrack->loadPaletteFromChunk(chunk);
+ } else {
+ // Check to see if this is a keyframe
+ // The first frame has to be a keyframe
+ if ((_indexEntries[i].flags & AVIIF_INDEX) || curFrame == 0)
+ lastKeyFrame = i;
+
+ // Did we find the target frame?
+ if (frame == curFrame) {
+ frameIndex = i;
+ break;
+ }
+
+ curFrame++;
+ }
+ }
+ }
+
+ if (frameIndex < 0) // This shouldn't happen.
+ return false;
+
+ if (audioTrack) {
+ // We need to find where the start of audio should be.
+ // Which is exactly 'initialFrames' audio chunks back from where
+ // our found frame is.
+
+ // Recreate the audio stream
+ audioTrack->resetStream();
+
+ uint framesNeeded = _header.initialFrames;
+ uint startAudioChunk = 0;
+ int startAudioSearch = (lastRecord < 0) ? (frameIndex - 1) : (lastRecord - 1);
+
+ for (int i = startAudioSearch; i >= 0; i--) {
+ if (getStreamIndex(_indexEntries[i].id) != audioIndex)
+ continue;
+
+ assert(getStreamType(_indexEntries[i].id) == kStreamTypeAudio);
+
+ framesNeeded--;
+
+ if (framesNeeded == 0) {
+ startAudioChunk = i;
+ break;
+ }
+ }
+
+ // Now go forward and queue them all
+ for (int i = startAudioChunk; i <= startAudioSearch; i++) {
+ if (_indexEntries[i].id == ID_REC)
+ continue;
+
+ if (getStreamIndex(_indexEntries[i].id) != audioIndex)
+ continue;
+
+ assert(getStreamType(_indexEntries[i].id) == kStreamTypeAudio);
+
+ _fileStream->seek(_indexEntries[i].offset + 8);
+ Common::SeekableReadStream *chunk = _fileStream->readStream(_indexEntries[i].size);
+ audioTrack->queueSound(chunk);
+ }
+
+ // Skip any audio to bring us to the right time
+ audioTrack->skipAudio(time, videoTrack->getFrameTime(frame));
+ }
+
+ // Decode from keyFrame to curFrame - 1
+ for (int i = lastKeyFrame; i < frameIndex; i++) {
+ if (_indexEntries[i].id == ID_REC)
+ continue;
+
+ if (getStreamIndex(_indexEntries[i].id) != videoIndex)
+ continue;
+
+ uint16 streamType = getStreamType(_indexEntries[i].id);
+
+ // Ignore palettes, they were already handled
+ if (streamType == kStreamTypePaletteChange)
+ continue;
+
+ // Frame, hopefully
+ _fileStream->seek(_indexEntries[i].offset + 8);
+ Common::SeekableReadStream *chunk = 0;
+
+ if (_indexEntries[i].size != 0)
+ chunk = _fileStream->readStream(_indexEntries[i].size);
+
+ videoTrack->decodeFrame(chunk);
+ }
+
+ // Seek to the right spot
+ // To the beginning of the last record, or frame if that doesn't exist
+ if (lastRecord >= 0)
+ _fileStream->seek(_indexEntries[lastRecord].offset);
+ else
+ _fileStream->seek(_indexEntries[frameIndex].offset);
+
+ videoTrack->setCurFrame((int)frame - 1);
+
+ return true;
+}
+
byte AVIDecoder::getStreamIndex(uint32 tag) const {
char string[3];
WRITE_BE_UINT16(string, tag >> 16);
@@ -431,17 +621,18 @@ byte AVIDecoder::getStreamIndex(uint32 tag) const {
return strtol(string, 0, 16);
}
-AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader)
- : _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader) {
- memset(_palette, 0, sizeof(_palette));
+AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette)
+ : _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader), _initialPalette(initialPalette) {
_videoCodec = createCodec();
- _dirtyPalette = false;
_lastFrame = 0;
_curFrame = -1;
+
+ useInitialPalette();
}
AVIDecoder::AVIVideoTrack::~AVIVideoTrack() {
delete _videoCodec;
+ delete[] _initialPalette;
}
void AVIDecoder::AVIVideoTrack::decodeFrame(Common::SeekableReadStream *stream) {
@@ -464,6 +655,47 @@ Graphics::PixelFormat AVIDecoder::AVIVideoTrack::getPixelFormat() const {
return Graphics::PixelFormat();
}
+void AVIDecoder::AVIVideoTrack::loadPaletteFromChunk(Common::SeekableReadStream *chunk) {
+ assert(chunk);
+ byte firstEntry = chunk->readByte();
+ uint16 numEntries = chunk->readByte();
+ chunk->readUint16LE(); // Reserved
+
+ // 0 entries means all colors are going to be changed
+ if (numEntries == 0)
+ numEntries = 256;
+
+ for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) {
+ _palette[i * 3] = chunk->readByte();
+ _palette[i * 3 + 1] = chunk->readByte();
+ _palette[i * 3 + 2] = chunk->readByte();
+ chunk->readByte(); // Flags that don't serve us any purpose
+ }
+
+ delete chunk;
+ _dirtyPalette = true;
+}
+
+void AVIDecoder::AVIVideoTrack::useInitialPalette() {
+ _dirtyPalette = false;
+
+ if (_initialPalette) {
+ memcpy(_palette, _initialPalette, sizeof(_palette));
+ _dirtyPalette = true;
+ }
+}
+
+bool AVIDecoder::AVIVideoTrack::rewind() {
+ _curFrame = -1;
+
+ useInitialPalette();
+
+ delete _videoCodec;
+ _videoCodec = createCodec();
+ _lastFrame = 0;
+ return true;
+}
+
Codec *AVIDecoder::AVIVideoTrack::createCodec() {
switch (_vidsHeader.streamHandler) {
case ID_CRAM:
@@ -525,6 +757,31 @@ void AVIDecoder::AVIAudioTrack::queueSound(Common::SeekableReadStream *stream) {
}
}
+void AVIDecoder::AVIAudioTrack::skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime) {
+ Audio::Timestamp timeDiff = time.convertToFramerate(_wvInfo.samplesPerSec) - frameTime.convertToFramerate(_wvInfo.samplesPerSec);
+ int skipFrames = timeDiff.totalNumberOfFrames();
+
+ if (skipFrames <= 0)
+ return;
+
+ if (_audStream->isStereo())
+ skipFrames *= 2;
+
+ int16 *tempBuffer = new int16[skipFrames];
+ _audStream->readBuffer(tempBuffer, skipFrames);
+ delete[] tempBuffer;
+}
+
+void AVIDecoder::AVIAudioTrack::resetStream() {
+ delete _audStream;
+ _audStream = createAudioStream();
+}
+
+bool AVIDecoder::AVIAudioTrack::rewind() {
+ resetStream();
+ return true;
+}
+
Audio::AudioStream *AVIDecoder::AVIAudioTrack::getAudioStream() const {
return _audStream;
}
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index f7259bf030..80c11b1e09 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -66,8 +66,13 @@ public:
uint16 getWidth() const { return _header.width; }
uint16 getHeight() const { return _header.height; }
+ bool rewind();
+ bool isRewindable() const { return true; }
+ bool isSeekable() const;
+
protected:
void readNextPacket();
+ bool seekIntern(const Audio::Timestamp &time);
struct BitmapInfoHeader {
uint32 size;
@@ -156,7 +161,7 @@ protected:
class AVIVideoTrack : public FixedRateVideoTrack {
public:
- AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader);
+ AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette = 0);
~AVIVideoTrack();
void decodeFrame(Common::SeekableReadStream *stream);
@@ -169,7 +174,12 @@ protected:
const Graphics::Surface *decodeNextFrame() { return _lastFrame; }
const byte *getPalette() const { _dirtyPalette = false; return _palette; }
bool hasDirtyPalette() const { return _dirtyPalette; }
- void markPaletteDirty() { _dirtyPalette = true; }
+ void setCurFrame(int frame) { _curFrame = frame; }
+ void loadPaletteFromChunk(Common::SeekableReadStream *chunk);
+ void useInitialPalette();
+
+ bool isRewindable() const { return true; }
+ bool rewind();
protected:
Common::Rational getFrameRate() const { return Common::Rational(_vidsHeader.rate, _vidsHeader.scale); }
@@ -178,6 +188,7 @@ protected:
AVIStreamHeader _vidsHeader;
BitmapInfoHeader _bmInfo;
byte _palette[3 * 256];
+ byte *_initialPalette;
mutable bool _dirtyPalette;
int _frameCount, _curFrame;
@@ -193,6 +204,11 @@ protected:
virtual void queueSound(Common::SeekableReadStream *stream);
Audio::Mixer::SoundType getSoundType() const { return _soundType; }
+ void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime);
+ void resetStream();
+
+ bool isRewindable() const { return true; }
+ bool rewind();
protected:
Audio::AudioStream *getAudioStream() const;
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index a512a49fac..0ab1478727 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -62,6 +62,8 @@ void VideoDecoder::close() {
delete *it;
_tracks.clear();
+ _internalTracks.clear();
+ _externalTracks.clear();
_dirtyPalette = false;
_palette = 0;
_startTime = 0;
@@ -340,6 +342,11 @@ bool VideoDecoder::seek(const Audio::Timestamp &time) {
if (!seekIntern(time))
return false;
+ // Seek any external track too
+ for (TrackListIterator it = _externalTracks.begin(); it != _externalTracks.end(); it++)
+ if (!(*it)->seek(time))
+ return false;
+
_lastTimeChange = time;
// Now that we've seeked, start all tracks again
@@ -356,12 +363,12 @@ bool VideoDecoder::seek(const Audio::Timestamp &time) {
}
bool VideoDecoder::seekToFrame(uint frame) {
+ if (!isSeekable())
+ return false;
+
VideoTrack *track = 0;
for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) {
- if (!(*it)->isSeekable())
- return false;
-
if ((*it)->getTrackType() == Track::kTrackTypeVideo) {
// We only allow seeking by frame when one video track
// is present
@@ -472,7 +479,7 @@ Audio::Timestamp VideoDecoder::getDuration() const {
}
bool VideoDecoder::seekIntern(const Audio::Timestamp &time) {
- for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ for (TrackList::iterator it = _internalTracks.begin(); it != _internalTracks.end(); it++)
if (!(*it)->seek(time))
return false;
@@ -524,10 +531,9 @@ Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getFrameTime(uint frame) con
if (frameRate == frameRate.toInt()) // The nice case (a whole number)
return Audio::Timestamp(0, frame, frameRate.toInt());
- // Just convert to milliseconds.
- Common::Rational time = frame * 1000;
- time /= frameRate;
- return Audio::Timestamp(time.toInt(), 1000);
+ // Convert as best as possible
+ Common::Rational time = frameRate.getInverse() * frame;
+ return Audio::Timestamp(0, time.getNumerator(), time.getDenominator());
}
uint VideoDecoder::FixedRateVideoTrack::getFrameAtTime(const Audio::Timestamp &time) const {
@@ -537,8 +543,10 @@ uint VideoDecoder::FixedRateVideoTrack::getFrameAtTime(const Audio::Timestamp &t
if (frameRate == time.framerate())
return time.totalNumberOfFrames();
- // Default case
- return (time.totalNumberOfFrames() * frameRate / time.framerate()).toInt();
+ // Create the rational based on the time first to hopefully cancel out
+ // *something* when multiplying by the frameRate (which can be large in
+ // some AVI videos).
+ return (Common::Rational(time.totalNumberOfFrames(), time.framerate()) * frameRate).toInt();
}
Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getDuration() const {
@@ -649,9 +657,14 @@ bool VideoDecoder::StreamFileAudioTrack::loadFromFile(const Common::String &base
return _stream != 0;
}
-void VideoDecoder::addTrack(Track *track) {
+void VideoDecoder::addTrack(Track *track, bool isExternal) {
_tracks.push_back(track);
+ if (isExternal)
+ _externalTracks.push_back(track);
+ else
+ _internalTracks.push_back(track);
+
if (track->getTrackType() == Track::kTrackTypeAudio) {
// Update volume settings if it's an audio track
((AudioTrack *)track)->setVolume(_audioVolume);
@@ -681,7 +694,7 @@ bool VideoDecoder::addStreamFileTrack(const Common::String &baseName) {
bool result = track->loadFromFile(baseName);
if (result)
- addTrack(track);
+ addTrack(track, true);
else
delete track;
@@ -712,17 +725,17 @@ void VideoDecoder::setEndTime(const Audio::Timestamp &endTime) {
}
VideoDecoder::Track *VideoDecoder::getTrack(uint track) {
- if (track > _tracks.size())
+ if (track > _internalTracks.size())
return 0;
- return _tracks[track];
+ return _internalTracks[track];
}
const VideoDecoder::Track *VideoDecoder::getTrack(uint track) const {
- if (track > _tracks.size())
+ if (track > _internalTracks.size())
return 0;
- return _tracks[track];
+ return _internalTracks[track];
}
bool VideoDecoder::endOfVideoTracks() const {
diff --git a/video/video_decoder.h b/video/video_decoder.h
index 7811734dd5..ac6586d8dd 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -594,17 +594,17 @@ protected:
virtual Audio::Timestamp getDuration() const;
Audio::Timestamp getFrameTime(uint frame) const;
- protected:
- /**
- * Get the rate at which this track is played.
- */
- virtual Common::Rational getFrameRate() const = 0;
-
/**
* Get the frame that should be displaying at the given time. This is
* helpful for someone implementing seek().
*/
uint getFrameAtTime(const Audio::Timestamp &time) const;
+
+ protected:
+ /**
+ * Get the rate at which this track is played.
+ */
+ virtual Common::Rational getFrameRate() const = 0;
};
/**
@@ -761,8 +761,11 @@ protected:
* Define a track to be used by this class.
*
* The pointer is then owned by this base class.
+ *
+ * @param track The track to add
+ * @param isExternal Is this an external track not found by loadStream()?
*/
- void addTrack(Track *track);
+ void addTrack(Track *track, bool isExternal = false);
/**
* Whether or not getTime() will sync with a playing audio track.
@@ -814,12 +817,12 @@ protected:
/**
* Get the begin iterator of the tracks
*/
- TrackListIterator getTrackListBegin() { return _tracks.begin(); }
+ TrackListIterator getTrackListBegin() { return _internalTracks.begin(); }
/**
* Get the end iterator of the tracks
*/
- TrackListIterator getTrackListEnd() { return _tracks.end(); }
+ TrackListIterator getTrackListEnd() { return _internalTracks.end(); }
/**
* The internal seek function that does the actual seeking.
@@ -833,6 +836,8 @@ protected:
private:
// Tracks owned by this VideoDecoder
TrackList _tracks;
+ TrackList _internalTracks;
+ TrackList _externalTracks;
// Current playback status
bool _needsUpdate;