aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--audio/audiostream.h4
-rw-r--r--audio/decoders/aac.h6
-rw-r--r--audio/decoders/adpcm.h4
-rw-r--r--audio/decoders/adpcm_intern.h4
-rw-r--r--audio/decoders/aiff.h4
-rw-r--r--audio/decoders/flac.h6
-rw-r--r--audio/decoders/iff_sound.h4
-rw-r--r--audio/decoders/mac_snd.h4
-rw-r--r--audio/decoders/mp3.h6
-rw-r--r--audio/decoders/raw.h4
-rw-r--r--audio/decoders/voc.h4
-rw-r--r--audio/decoders/vorbis.h6
-rw-r--r--audio/decoders/wave.h4
-rw-r--r--audio/fmopl.h4
-rw-r--r--audio/mididrv.h4
-rw-r--r--audio/midiparser.h4
-rw-r--r--audio/midiplayer.h4
-rw-r--r--audio/mixer.h4
-rw-r--r--audio/mixer_intern.h4
-rw-r--r--audio/mods/infogrames.h4
-rw-r--r--audio/mods/maxtrax.cpp4
-rw-r--r--audio/mods/maxtrax.h6
-rw-r--r--audio/mods/module.h4
-rw-r--r--audio/mods/paula.h4
-rw-r--r--audio/mods/protracker.h4
-rw-r--r--audio/mods/rjp1.h4
-rw-r--r--audio/mods/soundfx.h4
-rw-r--r--audio/mods/tfmx.cpp4
-rw-r--r--audio/mods/tfmx.h6
-rw-r--r--audio/mpu401.h4
-rw-r--r--audio/musicplugin.h4
-rw-r--r--audio/null.h4
-rw-r--r--audio/rate.h4
-rw-r--r--audio/softsynth/cms.h4
-rw-r--r--audio/softsynth/emumidi.h4
-rw-r--r--audio/softsynth/opl/dbopl.h4
-rw-r--r--audio/softsynth/opl/dosbox.h4
-rw-r--r--audio/softsynth/opl/mame.h4
-rw-r--r--audio/softsynth/pcspk.h6
-rw-r--r--audio/softsynth/sid.cpp2
-rw-r--r--audio/softsynth/sid.h6
-rw-r--r--audio/softsynth/wave6581.cpp2
-rw-r--r--audio/timestamp.h4
-rw-r--r--backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java1
-rw-r--r--common/macresman.cpp4
-rw-r--r--engines/gob/iniconfig.cpp2
-rw-r--r--engines/kyra/kyra_hof.cpp2
-rw-r--r--engines/kyra/kyra_v1.h50
-rw-r--r--engines/kyra/sequences_lol.cpp2
-rw-r--r--engines/kyra/sound.cpp128
-rw-r--r--engines/kyra/sound.h58
-rw-r--r--engines/kyra/sound_adlib.cpp528
-rw-r--r--engines/kyra/sound_adlib.h26
-rw-r--r--engines/made/screen.cpp16
-rw-r--r--engines/saga/detection.cpp2
-rw-r--r--engines/sci/engine/kernel.h1
-rw-r--r--engines/sci/engine/kernel_tables.h8
-rw-r--r--engines/sci/engine/kfile.cpp34
-rw-r--r--engines/sci/engine/kgraphics.cpp31
-rw-r--r--engines/sci/engine/kstring.cpp10
-rw-r--r--engines/sci/engine/selector.cpp1
-rw-r--r--engines/sci/engine/selector.h1
-rw-r--r--engines/sci/event.cpp13
-rw-r--r--engines/sci/graphics/controls32.cpp204
-rw-r--r--engines/sci/graphics/controls32.h51
-rw-r--r--engines/sci/graphics/frameout.cpp52
-rw-r--r--engines/sci/graphics/text32.cpp110
-rw-r--r--engines/sci/graphics/text32.h5
-rw-r--r--engines/sci/module.mk1
-rw-r--r--engines/sci/resource.cpp7
-rw-r--r--engines/sci/sci.cpp5
-rw-r--r--engines/sci/sci.h5
-rw-r--r--engines/sword1/animation.cpp15
-rw-r--r--engines/sword1/animation.h5
-rw-r--r--engines/sword1/logic.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_logic.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.cpp2
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.cpp44
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.h7
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.cpp100
-rw-r--r--engines/tsage/blue_force/blueforce_scenes3.h6
-rw-r--r--engines/tsage/blue_force/blueforce_scenes4.cpp57
-rw-r--r--engines/tsage/blue_force/blueforce_scenes4.h4
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.cpp20
-rw-r--r--engines/tsage/blue_force/blueforce_scenes5.h3
-rw-r--r--engines/tsage/blue_force/blueforce_scenes7.cpp40
-rw-r--r--engines/tsage/blue_force/blueforce_scenes7.h5
-rw-r--r--engines/tsage/core.cpp30
-rw-r--r--engines/tsage/core.h12
-rw-r--r--engines/tsage/detection.cpp1
-rw-r--r--engines/tsage/detection_tables.h15
-rw-r--r--engines/tsage/events.cpp1
-rw-r--r--engines/tsage/events.h4
-rw-r--r--engines/tsage/geekwad/geekwad_logic.cpp80
-rw-r--r--engines/tsage/geekwad/geekwad_logic.h79
-rw-r--r--engines/tsage/geekwad/geekwad_scenes0.cpp498
-rw-r--r--engines/tsage/geekwad/geekwad_scenes0.h85
-rw-r--r--engines/tsage/globals.cpp27
-rw-r--r--engines/tsage/globals.h15
-rw-r--r--engines/tsage/module.mk2
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.cpp2
-rw-r--r--engines/tsage/ringworld/ringworld_scenes6.cpp2
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp21
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h7
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp767
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.h56
-rw-r--r--engines/tsage/sound.h9
-rw-r--r--engines/tsage/staticres.cpp13
-rw-r--r--engines/tsage/staticres.h7
-rw-r--r--engines/tsage/tsage.cpp8
-rw-r--r--engines/tsage/tsage.h3
-rw-r--r--engines/tsage/user_interface.cpp11
-rw-r--r--gui/console.cpp2
-rw-r--r--gui/widgets/list.cpp1
-rw-r--r--gui/widgets/scrollbar.cpp58
-rw-r--r--gui/widgets/scrollbar.h6
116 files changed, 2904 insertions, 772 deletions
diff --git a/audio/audiostream.h b/audio/audiostream.h
index 9c28e4d67f..801f13d9d9 100644
--- a/audio/audiostream.h
+++ b/audio/audiostream.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_AUDIOSTREAM_H
-#define SOUND_AUDIOSTREAM_H
+#ifndef AUDIO_AUDIOSTREAM_H
+#define AUDIO_AUDIOSTREAM_H
#include "common/ptr.h"
#include "common/scummsys.h"
diff --git a/audio/decoders/aac.h b/audio/decoders/aac.h
index 68e322c844..9ad78b28a4 100644
--- a/audio/decoders/aac.h
+++ b/audio/decoders/aac.h
@@ -26,8 +26,8 @@
* - groovie
*/
-#ifndef SOUND_AAC_H
-#define SOUND_AAC_H
+#ifndef AUDIO_AAC_H
+#define AUDIO_AAC_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -59,4 +59,4 @@ Codec *makeAACDecoder(
} // End of namespace Audio
#endif // #ifdef USE_FAAD
-#endif // #ifndef SOUND_AAC_H
+#endif // #ifndef AUDIO_AAC_H
diff --git a/audio/decoders/adpcm.h b/audio/decoders/adpcm.h
index 1dd4d510df..ac8d529917 100644
--- a/audio/decoders/adpcm.h
+++ b/audio/decoders/adpcm.h
@@ -31,8 +31,8 @@
* - tinsel
*/
-#ifndef SOUND_ADPCM_H
-#define SOUND_ADPCM_H
+#ifndef AUDIO_ADPCM_H
+#define AUDIO_ADPCM_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h
index 38514d7fca..f7162f5f2a 100644
--- a/audio/decoders/adpcm_intern.h
+++ b/audio/decoders/adpcm_intern.h
@@ -28,8 +28,8 @@
* ADPCM decoder implementations.
*/
-#ifndef SOUND_ADPCM_INTERN_H
-#define SOUND_ADPCM_INTERN_H
+#ifndef AUDIO_ADPCM_INTERN_H
+#define AUDIO_ADPCM_INTERN_H
#include "audio/audiostream.h"
#include "common/endian.h"
diff --git a/audio/decoders/aiff.h b/audio/decoders/aiff.h
index 558a018f57..59664bb85a 100644
--- a/audio/decoders/aiff.h
+++ b/audio/decoders/aiff.h
@@ -28,8 +28,8 @@
* - sword1
*/
-#ifndef SOUND_AIFF_H
-#define SOUND_AIFF_H
+#ifndef AUDIO_AIFF_H
+#define AUDIO_AIFF_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/decoders/flac.h b/audio/decoders/flac.h
index 3182b26425..a90675cc20 100644
--- a/audio/decoders/flac.h
+++ b/audio/decoders/flac.h
@@ -37,8 +37,8 @@
* - tucker
*/
-#ifndef SOUND_FLAC_H
-#define SOUND_FLAC_H
+#ifndef AUDIO_FLAC_H
+#define AUDIO_FLAC_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -68,4 +68,4 @@ SeekableAudioStream *makeFLACStream(
} // End of namespace Audio
#endif // #ifdef USE_FLAC
-#endif // #ifndef SOUND_FLAC_H
+#endif // #ifndef AUDIO_FLAC_H
diff --git a/audio/decoders/iff_sound.h b/audio/decoders/iff_sound.h
index b266e629a1..28b2c67227 100644
--- a/audio/decoders/iff_sound.h
+++ b/audio/decoders/iff_sound.h
@@ -26,8 +26,8 @@
* - parallaction
*/
-#ifndef SOUND_IFF_H
-#define SOUND_IFF_H
+#ifndef AUDIO_IFF_H
+#define AUDIO_IFF_H
namespace Common {
class ReadStream;
diff --git a/audio/decoders/mac_snd.h b/audio/decoders/mac_snd.h
index cbbd82bbe0..7e960058ae 100644
--- a/audio/decoders/mac_snd.h
+++ b/audio/decoders/mac_snd.h
@@ -26,8 +26,8 @@
* - sci
*/
-#ifndef SOUND_MAC_SND_H
-#define SOUND_MAC_SND_H
+#ifndef AUDIO_MAC_SND_H
+#define AUDIO_MAC_SND_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/decoders/mp3.h b/audio/decoders/mp3.h
index 86ddc599ea..cb0cc8375d 100644
--- a/audio/decoders/mp3.h
+++ b/audio/decoders/mp3.h
@@ -38,8 +38,8 @@
* - tucker
*/
-#ifndef SOUND_MP3_H
-#define SOUND_MP3_H
+#ifndef AUDIO_MP3_H
+#define AUDIO_MP3_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -69,4 +69,4 @@ SeekableAudioStream *makeMP3Stream(
} // End of namespace Audio
#endif // #ifdef USE_MAD
-#endif // #ifndef SOUND_MP3_H
+#endif // #ifndef AUDIO_MP3_H
diff --git a/audio/decoders/raw.h b/audio/decoders/raw.h
index 5a7897b688..5cbf2c9b79 100644
--- a/audio/decoders/raw.h
+++ b/audio/decoders/raw.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_RAW_H
-#define SOUND_RAW_H
+#ifndef AUDIO_RAW_H
+#define AUDIO_RAW_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/decoders/voc.h b/audio/decoders/voc.h
index a920eac933..7d96d261b5 100644
--- a/audio/decoders/voc.h
+++ b/audio/decoders/voc.h
@@ -30,8 +30,8 @@
* - touche
*/
-#ifndef SOUND_VOC_H
-#define SOUND_VOC_H
+#ifndef AUDIO_VOC_H
+#define AUDIO_VOC_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/decoders/vorbis.h b/audio/decoders/vorbis.h
index e3d989e9b8..9e7600af56 100644
--- a/audio/decoders/vorbis.h
+++ b/audio/decoders/vorbis.h
@@ -38,8 +38,8 @@
* - tucker
*/
-#ifndef SOUND_VORBIS_H
-#define SOUND_VORBIS_H
+#ifndef AUDIO_VORBIS_H
+#define AUDIO_VORBIS_H
#include "common/scummsys.h"
#include "common/types.h"
@@ -69,4 +69,4 @@ SeekableAudioStream *makeVorbisStream(
} // End of namespace Audio
#endif // #ifdef USE_VORBIS
-#endif // #ifndef SOUND_VORBIS_H
+#endif // #ifndef AUDIO_VORBIS_H
diff --git a/audio/decoders/wave.h b/audio/decoders/wave.h
index 6a34bc175a..c8ac7fe318 100644
--- a/audio/decoders/wave.h
+++ b/audio/decoders/wave.h
@@ -34,8 +34,8 @@
* - tucker
*/
-#ifndef SOUND_WAVE_H
-#define SOUND_WAVE_H
+#ifndef AUDIO_WAVE_H
+#define AUDIO_WAVE_H
#include "common/scummsys.h"
#include "common/types.h"
diff --git a/audio/fmopl.h b/audio/fmopl.h
index f62587f557..323cc3d028 100644
--- a/audio/fmopl.h
+++ b/audio/fmopl.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_FMOPL_H
-#define SOUND_FMOPL_H
+#ifndef AUDIO_FMOPL_H
+#define AUDIO_FMOPL_H
#include "common/scummsys.h"
diff --git a/audio/mididrv.h b/audio/mididrv.h
index cdf2943f2a..fb3e29bd60 100644
--- a/audio/mididrv.h
+++ b/audio/mididrv.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MIDIDRV_H
-#define SOUND_MIDIDRV_H
+#ifndef AUDIO_MIDIDRV_H
+#define AUDIO_MIDIDRV_H
#include "common/scummsys.h"
#include "common/str.h"
diff --git a/audio/midiparser.h b/audio/midiparser.h
index 9dff4b54ba..c935969e72 100644
--- a/audio/midiparser.h
+++ b/audio/midiparser.h
@@ -22,8 +22,8 @@
/// \brief Declarations related to the MidiParser class
-#ifndef SOUND_MIDIPARSER_H
-#define SOUND_MIDIPARSER_H
+#ifndef AUDIO_MIDIPARSER_H
+#define AUDIO_MIDIPARSER_H
#include "common/scummsys.h"
#include "common/endian.h"
diff --git a/audio/midiplayer.h b/audio/midiplayer.h
index e1da0bfb79..e58c78cafd 100644
--- a/audio/midiplayer.h
+++ b/audio/midiplayer.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MIDIPLAYER_H
-#define SOUND_MIDIPLAYER_H
+#ifndef AUDIO_MIDIPLAYER_H
+#define AUDIO_MIDIPLAYER_H
#include "common/scummsys.h"
#include "common/mutex.h"
diff --git a/audio/mixer.h b/audio/mixer.h
index de709e13fe..e38e052bef 100644
--- a/audio/mixer.h
+++ b/audio/mixer.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MIXER_H
-#define SOUND_MIXER_H
+#ifndef AUDIO_MIXER_H
+#define AUDIO_MIXER_H
#include "common/types.h"
#include "common/noncopyable.h"
diff --git a/audio/mixer_intern.h b/audio/mixer_intern.h
index dc361ce560..c6dfa55ada 100644
--- a/audio/mixer_intern.h
+++ b/audio/mixer_intern.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MIXER_INTERN_H
-#define SOUND_MIXER_INTERN_H
+#ifndef AUDIO_MIXER_INTERN_H
+#define AUDIO_MIXER_INTERN_H
#include "common/scummsys.h"
#include "common/mutex.h"
diff --git a/audio/mods/infogrames.h b/audio/mods/infogrames.h
index 307a26d4e1..8b246eebe7 100644
--- a/audio/mods/infogrames.h
+++ b/audio/mods/infogrames.h
@@ -26,8 +26,8 @@
* - gob
*/
-#ifndef SOUND_MODS_INFOGRAMES_H
-#define SOUND_MODS_INFOGRAMES_H
+#ifndef AUDIO_MODS_INFOGRAMES_H
+#define AUDIO_MODS_INFOGRAMES_H
#include "audio/mods/paula.h"
diff --git a/audio/mods/maxtrax.cpp b/audio/mods/maxtrax.cpp
index 344d678b76..8ed51ae5c3 100644
--- a/audio/mods/maxtrax.cpp
+++ b/audio/mods/maxtrax.cpp
@@ -29,7 +29,7 @@
#include "audio/mods/maxtrax.h"
// test for engines using this class.
-#if defined(SOUND_MODS_MAXTRAX_H)
+#if defined(AUDIO_MODS_MAXTRAX_H)
namespace {
@@ -1034,4 +1034,4 @@ void MaxTrax::outPutScore(const Score &sc, int num) {}
} // End of namespace Audio
-#endif // #if defined(SOUND_MODS_MAXTRAX_H)
+#endif // #if defined(AUDIO_MODS_MAXTRAX_H)
diff --git a/audio/mods/maxtrax.h b/audio/mods/maxtrax.h
index bef6669d2a..c61f4e1b50 100644
--- a/audio/mods/maxtrax.h
+++ b/audio/mods/maxtrax.h
@@ -24,8 +24,8 @@
#if !defined(ENABLE_KYRA)
// normal Header Guard
-#elif !defined SOUND_MODS_MAXTRAX_H
-#define SOUND_MODS_MAXTRAX_H
+#elif !defined AUDIO_MODS_MAXTRAX_H
+#define AUDIO_MODS_MAXTRAX_H
// #define MAXTRAX_HAS_MODULATION
// #define MAXTRAX_HAS_MICROTONAL
@@ -219,4 +219,4 @@ private:
};
} // End of namespace Audio
-#endif // !defined SOUND_MODS_MAXTRAX_H
+#endif // !defined AUDIO_MODS_MAXTRAX_H
diff --git a/audio/mods/module.h b/audio/mods/module.h
index a57a89225e..eb7cbf260e 100644
--- a/audio/mods/module.h
+++ b/audio/mods/module.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MODS_MODULE_H
-#define SOUND_MODS_MODULE_H
+#ifndef AUDIO_MODS_MODULE_H
+#define AUDIO_MODS_MODULE_H
#include "common/scummsys.h"
diff --git a/audio/mods/paula.h b/audio/mods/paula.h
index cd797f51cb..5d11cc7bb6 100644
--- a/audio/mods/paula.h
+++ b/audio/mods/paula.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MODS_PAULA_H
-#define SOUND_MODS_PAULA_H
+#ifndef AUDIO_MODS_PAULA_H
+#define AUDIO_MODS_PAULA_H
#include "audio/audiostream.h"
#include "common/frac.h"
diff --git a/audio/mods/protracker.h b/audio/mods/protracker.h
index 15f708d801..d52322f07e 100644
--- a/audio/mods/protracker.h
+++ b/audio/mods/protracker.h
@@ -27,8 +27,8 @@
* - parallaction
*/
-#ifndef SOUND_MODS_PROTRACKER_H
-#define SOUND_MODS_PROTRACKER_H
+#ifndef AUDIO_MODS_PROTRACKER_H
+#define AUDIO_MODS_PROTRACKER_H
namespace Common {
class SeekableReadStream;
diff --git a/audio/mods/rjp1.h b/audio/mods/rjp1.h
index 232b1926e9..e7e54dafb3 100644
--- a/audio/mods/rjp1.h
+++ b/audio/mods/rjp1.h
@@ -26,8 +26,8 @@
* - queen
*/
-#ifndef SOUND_MODS_RJP1_H
-#define SOUND_MODS_RJP1_H
+#ifndef AUDIO_MODS_RJP1_H
+#define AUDIO_MODS_RJP1_H
namespace Common {
class SeekableReadStream;
diff --git a/audio/mods/soundfx.h b/audio/mods/soundfx.h
index 48ccff2da6..d517c6c78f 100644
--- a/audio/mods/soundfx.h
+++ b/audio/mods/soundfx.h
@@ -26,8 +26,8 @@
* - cine
*/
-#ifndef SOUND_MODS_SOUNDFX_H
-#define SOUND_MODS_SOUNDFX_H
+#ifndef AUDIO_MODS_SOUNDFX_H
+#define AUDIO_MODS_SOUNDFX_H
namespace Common {
class SeekableReadStream;
diff --git a/audio/mods/tfmx.cpp b/audio/mods/tfmx.cpp
index a89da78af1..8d584809c8 100644
--- a/audio/mods/tfmx.cpp
+++ b/audio/mods/tfmx.cpp
@@ -29,7 +29,7 @@
#include "audio/mods/tfmx.h"
// test for engines using this class.
-#if defined(SOUND_MODS_TFMX_H)
+#if defined(AUDIO_MODS_TFMX_H)
// couple debug-functions
namespace {
@@ -1187,4 +1187,4 @@ void displayPatternstep(const void * const vptr) {
} // End of anonymous namespace
#endif
-#endif // #if defined(SOUND_MODS_TFMX_H)
+#endif // #if defined(AUDIO_MODS_TFMX_H)
diff --git a/audio/mods/tfmx.h b/audio/mods/tfmx.h
index 2b07e2e660..4174fbfb27 100644
--- a/audio/mods/tfmx.h
+++ b/audio/mods/tfmx.h
@@ -24,8 +24,8 @@
#if !defined(ENABLE_SCUMM)
// normal Header Guard
-#elif !defined(SOUND_MODS_TFMX_H)
-#define SOUND_MODS_TFMX_H
+#elif !defined(AUDIO_MODS_TFMX_H)
+#define AUDIO_MODS_TFMX_H
#include "audio/mods/paula.h"
@@ -278,4 +278,4 @@ private:
} // End of namespace Audio
-#endif // !defined(SOUND_MODS_TFMX_H)
+#endif // !defined(AUDIO_MODS_TFMX_H)
diff --git a/audio/mpu401.h b/audio/mpu401.h
index 15728a6d97..d4580b6e79 100644
--- a/audio/mpu401.h
+++ b/audio/mpu401.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_MPU401_H
-#define SOUND_MPU401_H
+#ifndef AUDIO_MPU401_H
+#define AUDIO_MPU401_H
#include "audio/mididrv.h"
diff --git a/audio/musicplugin.h b/audio/musicplugin.h
index 307293a7c9..2a0f2f0a99 100644
--- a/audio/musicplugin.h
+++ b/audio/musicplugin.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_MUSICPLUGIN_H
-#define SOUND_MUSICPLUGIN_H
+#ifndef AUDIO_MUSICPLUGIN_H
+#define AUDIO_MUSICPLUGIN_H
#include "base/plugins.h"
#include "audio/mididrv.h"
diff --git a/audio/null.h b/audio/null.h
index 97c7c8cc93..90897be6af 100644
--- a/audio/null.h
+++ b/audio/null.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_NULL_H
-#define SOUND_NULL_H
+#ifndef AUDIO_NULL_H
+#define AUDIO_NULL_H
#include "audio/musicplugin.h"
#include "audio/mpu401.h"
diff --git a/audio/rate.h b/audio/rate.h
index 72bcbf48c5..9813b75b08 100644
--- a/audio/rate.h
+++ b/audio/rate.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_RATE_H
-#define SOUND_RATE_H
+#ifndef AUDIO_RATE_H
+#define AUDIO_RATE_H
#include "common/scummsys.h"
diff --git a/audio/softsynth/cms.h b/audio/softsynth/cms.h
index 48064746a8..0aad856a9d 100644
--- a/audio/softsynth/cms.h
+++ b/audio/softsynth/cms.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_SOFTSYNTH_CMS_H
-#define SOUND_SOFTSYNTH_CMS_H
+#ifndef AUDIO_SOFTSYNTH_CMS_H
+#define AUDIO_SOFTSYNTH_CMS_H
#include "common/scummsys.h"
diff --git a/audio/softsynth/emumidi.h b/audio/softsynth/emumidi.h
index f72dad7eaf..3e9d669933 100644
--- a/audio/softsynth/emumidi.h
+++ b/audio/softsynth/emumidi.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_SOFTSYNTH_EMUMIDI_H
-#define SOUND_SOFTSYNTH_EMUMIDI_H
+#ifndef AUDIO_SOFTSYNTH_EMUMIDI_H
+#define AUDIO_SOFTSYNTH_EMUMIDI_H
#include "audio/audiostream.h"
#include "audio/mididrv.h"
diff --git a/audio/softsynth/opl/dbopl.h b/audio/softsynth/opl/dbopl.h
index 3dbd98986d..99234ebf88 100644
--- a/audio/softsynth/opl/dbopl.h
+++ b/audio/softsynth/opl/dbopl.h
@@ -18,8 +18,8 @@
// Last synch with DOSBox SVN trunk r3752
-#ifndef SOUND_SOFTSYNTH_OPL_DBOPL_H
-#define SOUND_SOFTSYNTH_OPL_DBOPL_H
+#ifndef AUDIO_SOFTSYNTH_OPL_DBOPL_H
+#define AUDIO_SOFTSYNTH_OPL_DBOPL_H
#include "common/scummsys.h"
diff --git a/audio/softsynth/opl/dosbox.h b/audio/softsynth/opl/dosbox.h
index cdf86df114..3adfe98852 100644
--- a/audio/softsynth/opl/dosbox.h
+++ b/audio/softsynth/opl/dosbox.h
@@ -26,8 +26,8 @@
* http://www.dosbox.com
*/
-#ifndef SOUND_SOFTSYNTH_OPL_DOSBOX_H
-#define SOUND_SOFTSYNTH_OPL_DOSBOX_H
+#ifndef AUDIO_SOFTSYNTH_OPL_DOSBOX_H
+#define AUDIO_SOFTSYNTH_OPL_DOSBOX_H
#ifndef DISABLE_DOSBOX_OPL
diff --git a/audio/softsynth/opl/mame.h b/audio/softsynth/opl/mame.h
index 803ca897e7..3714fa4e0a 100644
--- a/audio/softsynth/opl/mame.h
+++ b/audio/softsynth/opl/mame.h
@@ -23,8 +23,8 @@
*/
-#ifndef SOUND_SOFTSYNTH_OPL_MAME_H
-#define SOUND_SOFTSYNTH_OPL_MAME_H
+#ifndef AUDIO_SOFTSYNTH_OPL_MAME_H
+#define AUDIO_SOFTSYNTH_OPL_MAME_H
#include "common/scummsys.h"
#include "common/random.h"
diff --git a/audio/softsynth/pcspk.h b/audio/softsynth/pcspk.h
index 3641400b1f..f27eb94904 100644
--- a/audio/softsynth/pcspk.h
+++ b/audio/softsynth/pcspk.h
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef SOUND_SOFTSYNTH_PCSPK_H
-#define SOUND_SOFTSYNTH_PCSPK_H
+#ifndef AUDIO_SOFTSYNTH_PCSPK_H
+#define AUDIO_SOFTSYNTH_PCSPK_H
#include "audio/audiostream.h"
#include "common/mutex.h"
@@ -81,4 +81,4 @@ protected:
} // End of namespace Audio
-#endif // SOUND_SOFTSYNTH_PCSPEAKER_H
+#endif // AUDIO_SOFTSYNTH_PCSPEAKER_H
diff --git a/audio/softsynth/sid.cpp b/audio/softsynth/sid.cpp
index 4b8f783ef4..1ad822b86a 100644
--- a/audio/softsynth/sid.cpp
+++ b/audio/softsynth/sid.cpp
@@ -27,7 +27,7 @@
#ifndef DISABLE_SID
-#include "sid.h"
+#include "audio/softsynth/sid.h"
#include "audio/null.h"
namespace Resid {
diff --git a/audio/softsynth/sid.h b/audio/softsynth/sid.h
index a015242844..19577e94d1 100644
--- a/audio/softsynth/sid.h
+++ b/audio/softsynth/sid.h
@@ -25,8 +25,8 @@
* Copyright (C) 2004 Dag Lem <resid@nimrod.no>
*/
-#ifndef __SID_H__
-#define __SID_H__
+#ifndef AUDIO_SOFTSYNTH_SID_H
+#define AUDIO_SOFTSYNTH_SID_H
// Inlining on/off.
#define RESID_INLINE inline
@@ -342,4 +342,4 @@ protected:
}
-#endif // not __SID_H__
+#endif // not AUDIO_SOFTSYNTH_SID_H
diff --git a/audio/softsynth/wave6581.cpp b/audio/softsynth/wave6581.cpp
index 63e08fb113..832a7272ff 100644
--- a/audio/softsynth/wave6581.cpp
+++ b/audio/softsynth/wave6581.cpp
@@ -27,7 +27,7 @@
#ifndef DISABLE_SID
-#include "sid.h"
+#include "audio/softsynth/sid.h"
namespace Resid {
diff --git a/audio/timestamp.h b/audio/timestamp.h
index ef095a2106..1683b554cb 100644
--- a/audio/timestamp.h
+++ b/audio/timestamp.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef SOUND_TIMESTAMP_H
-#define SOUND_TIMESTAMP_H
+#ifndef AUDIO_TIMESTAMP_H
+#define AUDIO_TIMESTAMP_H
#include "common/scummsys.h"
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 7c61520d43..fbd6513761 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -134,6 +134,7 @@ public class ScummVMActivity extends Activity {
// world-readable and don't get deleted on uninstall.
String savePath = Environment.getExternalStorageDirectory() + "/ScummVM/Saves/";
File saveDir = new File(savePath);
+ saveDir.mkdirs();
if (!saveDir.isDirectory()) {
// If it doesn't work, resort to the internal app path.
savePath = getDir("saves", MODE_WORLD_READABLE).getPath();
diff --git a/common/macresman.cpp b/common/macresman.cpp
index 2b9c68ade9..1317600cb7 100644
--- a/common/macresman.cpp
+++ b/common/macresman.cpp
@@ -110,7 +110,7 @@ bool MacResManager::open(String filename) {
String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
- SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();;
+ SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = filename;
@@ -173,7 +173,7 @@ bool MacResManager::open(FSNode path, String filename) {
String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc";
FSNode resFsNode = FSNode(fullPath);
if (resFsNode.exists()) {
- SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();;
+ SeekableReadStream *macResForkRawStream = resFsNode.createReadStream();
if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) {
_baseFileName = filename;
diff --git a/engines/gob/iniconfig.cpp b/engines/gob/iniconfig.cpp
index 9b8f1c703e..bba531723c 100644
--- a/engines/gob/iniconfig.cpp
+++ b/engines/gob/iniconfig.cpp
@@ -90,7 +90,7 @@ bool INIConfig::openConfig(const Common::String &file, Config &config) {
bool INIConfig::createConfig(const Common::String &file, Config &config) {
config.config = new Common::ConfigFile();
- config.created = true;;
+ config.created = true;
_configs.setVal(file, config);
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 4497ab8019..8a3229ea1f 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -1473,7 +1473,7 @@ void KyraEngine_HoF::snd_playVoiceFile(int id) {
char vocFile[9];
assert(id >= 0 && id <= 9999999);
sprintf(vocFile, "%07d", id);
- if (_sound->voiceFileIsPresent(vocFile)) {
+ if (_sound->isVoicePresent(vocFile)) {
snd_stopVoice();
while (!_sound->voicePlay(vocFile, &_speechHandle)) {
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 584176e08c..5a9feb0054 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -52,14 +52,16 @@ class KyraMetaEngine;
*
* Status of this engine:
*
- * The KYRA engine supports all three Kyrandia games by Westwood. It also supports Westwood's
- * Lands of Lore. There are various platform ports of the different games, almost all of them are
- * fully supported. Only the Macintosh port of Kyrandia 1 makes a difference here, which lacks
- * support for sound effects and music.
+ * The KYRA engine supports all three Kyrandia games by Westwood. It also
+ * supports Westwood's Lands of Lore. There are various platform ports of
+ * the different games, almost all of them are fully supported. Only the
+ * Macintosh port of Kyrandia 1 makes a difference here, which lacks support
+ * for sound effects and music.
*
- * The different translations of the games are mostly supported, since every translation
- * requires some work for kyra.dat for example, it is almost impossible to support translations,
- * without owning them. There a currently a few reported unsupported translations:
+ * The different translations of the games are mostly supported, since every
+ * translation requires some work for kyra.dat for example, it is almost
+ * impossible to support translations, without owning them. There a currently
+ * a few reported unsupported translations:
*
* - Official translations
* None known.
@@ -69,24 +71,30 @@ class KyraMetaEngine;
* Kyrandia 1 Korean (feature request #1758252 "KYRA1: Add support for Korean/DOS version")
* Kyrandia 2 Polish (feature request #2146192 "KYRA2: Add support for Polish floppy version")
* - Fan translations:
- * Kyrandia 1 Russian (no feature request)
- * Kyrandia 2 Russian (no feature request)
* Kyrandia 3 Russian (feature request #2812792 "Kyrandia3 Russian")
*
- * The engine is maintained by _athrxx.
+ * The primary maintainer for the engine is LordHoto, although some parts are
+ * maintained by _athrxx. If you have questions about parts of the code, the
+ * following rough description might help in determining who you should ask:
+ * _athrxx is the maintainer for the Lands of Lore subengine, he also
+ * maintains most of the FM-TOWNS and PC98 specific code (especially the sound
+ * code, also some ingame code) and the Kyrandia 2 sequence player code.
+ * LordHoto is responsible for the rest of the codebase, he also worked on the
+ * graphics output for 16 color PC98 games.
*
- * Other people who worked on this engine include cyx, who initially started to work on Kyrandia 1
- * support, vinterstum, who did various things for Kyrandia 1 and started to work on the Kyrandia 2
- * sequence player code and also on the TIM script code, and eriktorbjorn, who helped out naming
- * our AdLib player code and also contributed a work around for a music bug in the "Pool of Sorrow"
- * scene of Kyrandia 1, which is also present in the original. LordHoto worked on Kyrandia 1 to 3
- * support and graphics output for 16 color PC98 games and was a maintainer of the Kyrandia part.
- * All mentioned developers are not actively working on KYRA anymore.
+ * Other people who worked on this engine include cyx, who initially started
+ * to work on Kyrandia 1 support. Vinterstum, who did various things for
+ * Kyrandia 1 and started to work on the Kyrandia 2 sequence player code and
+ * also on the TIM script code. Eriktorbjorn, who helped out naming our AdLib
+ * player code and also contributed a work around for a music bug in the
+ * "Pool of Sorrow" scene of Kyrandia 1, which is also present in the original.
+ * He also contributed the VQA player for Kyrandia 3.
*
- * The engine is mostly finished code wise. A possible remaining task is proper refactoring,
- * which might help in reducing binary size and along with it runtime memory use, but of course
- * might lead to regressions (since the current code makes no problems on our low end ports, it
- * is pretty minor priority though, since the benefit would be mostly nicer code). The biggest
+ * The engine is mostly finished code wise. A possible remaining task is
+ * proper refactoring, which might help in reducing binary size and along with
+ * it runtime memory use, but of course might lead to regressions (since the
+ * current code makes no problems on our low end ports, it is pretty minor
+ * priority though, since the benefit would be mostly nicer code). The biggest
* task left is the kyra.dat handling.
*
* Games using this engine:
diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp
index 83d525d400..01db92c225 100644
--- a/engines/kyra/sequences_lol.cpp
+++ b/engines/kyra/sequences_lol.cpp
@@ -788,7 +788,7 @@ void HistoryPlayer::play() {
for (; voiceFilename[3] <= '9' && !_vm->shouldQuit() && !_vm->skipFlag(); ++voiceFilename[3], voiceFilename[4] = 'a') {
while (!_vm->shouldQuit() && !_vm->skipFlag()) {
- if (!sound->voiceFileIsPresent(voiceFilename))
+ if (!sound->isVoicePresent(voiceFilename))
break;
if (data[part * 15] == voiceFilename[3] && data[part * 15 + 1] == voiceFilename[4]) {
diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp
index 0e83c1cb1f..5195271808 100644
--- a/engines/kyra/sound.cpp
+++ b/engines/kyra/sound.cpp
@@ -43,25 +43,30 @@ Sound::Sound(KyraEngine_v1 *vm, Audio::Mixer *mixer)
Sound::~Sound() {
}
-bool Sound::voiceFileIsPresent(const char *file) {
- for (int i = 0; _supportedCodecs[i].fileext; ++i) {
- Common::String f = file;
- f += _supportedCodecs[i].fileext;
- if (_vm->resource()->getFileSize(f.c_str()) > 0)
- return true;
- }
+Sound::kType Sound::getSfxType() const {
+ return getMusicType();
+}
+
+void Sound::setSoundList(const AudioDataStruct *list) {
+ _soundDataList = list;
+}
+bool Sound::hasSoundFile(uint file) const {
+ return (fileListEntry(file) != 0);
+}
+
+bool Sound::isPlaying() const {
return false;
}
-bool Sound::isVoicePresent(const char *file) {
- char filenamebuffer[25];
+bool Sound::isVoicePresent(const char *file) const {
+ Common::String filename;
for (int i = 0; _supportedCodecs[i].fileext; ++i) {
- strcpy(filenamebuffer, file);
- strcat(filenamebuffer, _supportedCodecs[i].fileext);
+ filename = file;
+ filename += _supportedCodecs[i].fileext;
- if (_vm->resource()->exists(filenamebuffer))
+ if (_vm->resource()->exists(filename.c_str()))
return true;
}
@@ -80,15 +85,15 @@ int32 Sound::voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volum
return playTime;
}
-Audio::SeekableAudioStream *Sound::getVoiceStream(const char *file) {
- char filenamebuffer[25];
+Audio::SeekableAudioStream *Sound::getVoiceStream(const char *file) const {
+ Common::String filename;
Audio::SeekableAudioStream *audioStream = 0;
for (int i = 0; _supportedCodecs[i].fileext; ++i) {
- strcpy(filenamebuffer, file);
- strcat(filenamebuffer, _supportedCodecs[i].fileext);
+ filename = file;
+ filename += _supportedCodecs[i].fileext;
- Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filenamebuffer);
+ Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
if (!stream)
continue;
@@ -136,7 +141,7 @@ void Sound::voiceStop(const Audio::SoundHandle *handle) {
}
}
-bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) {
+bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) const {
if (!handle) {
for (int h = 0; h < kNumChannelHandles; ++h) {
if (_mixer->isSoundHandleActive(_soundChannels[h]))
@@ -149,7 +154,7 @@ bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) {
return false;
}
-bool Sound::allVoiceChannelsPlaying() {
+bool Sound::allVoiceChannelsPlaying() const {
for (int i = 0; i < kNumChannelHandles; ++i)
if (!_mixer->isSoundHandleActive(_soundChannels[i]))
return false;
@@ -158,6 +163,91 @@ bool Sound::allVoiceChannelsPlaying() {
#pragma mark -
+MixedSoundDriver::MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx)
+ : Sound(vm, mixer), _music(music), _sfx(sfx) {
+}
+
+MixedSoundDriver::~MixedSoundDriver() {
+ delete _music;
+ delete _sfx;
+}
+
+Sound::kType MixedSoundDriver::getMusicType() const {
+ return _music->getMusicType();
+}
+
+Sound::kType MixedSoundDriver::getSfxType() const {
+ return _sfx->getSfxType();
+}
+
+bool MixedSoundDriver::init() {
+ return (_music->init() && _sfx->init());
+}
+
+void MixedSoundDriver::process() {
+ _music->process();
+ _sfx->process();
+}
+
+void MixedSoundDriver::updateVolumeSettings() {
+ _music->updateVolumeSettings();
+ _sfx->updateVolumeSettings();
+}
+
+void MixedSoundDriver::setSoundList(const AudioDataStruct *list) {
+ _music->setSoundList(list);
+ _sfx->setSoundList(list);
+}
+
+bool MixedSoundDriver::hasSoundFile(uint file) const {
+ return _music->hasSoundFile(file) && _sfx->hasSoundFile(file);
+}
+
+void MixedSoundDriver::loadSoundFile(uint file) {
+ _music->loadSoundFile(file);
+ _sfx->loadSoundFile(file);
+}
+
+void MixedSoundDriver::loadSoundFile(Common::String file) {
+ _music->loadSoundFile(file);
+ _sfx->loadSoundFile(file);
+}
+
+void MixedSoundDriver::loadSfxFile(Common::String file) {
+ _sfx->loadSoundFile(file);
+}
+
+void MixedSoundDriver::playTrack(uint8 track) {
+ _music->playTrack(track);
+}
+
+void MixedSoundDriver::haltTrack() {
+ _music->haltTrack();
+}
+
+bool MixedSoundDriver::isPlaying() const {
+ return _music->isPlaying() | _sfx->isPlaying();
+}
+
+void MixedSoundDriver::playSoundEffect(uint8 track) {
+ _sfx->playSoundEffect(track);
+}
+
+void MixedSoundDriver::stopAllSoundEffects() {
+ _sfx->stopAllSoundEffects();
+}
+
+void MixedSoundDriver::beginFadeOut() {
+ _music->beginFadeOut();
+}
+
+void MixedSoundDriver::pause(bool paused) {
+ _music->pause(paused);
+ _sfx->pause(paused);
+}
+
+#pragma mark -
+
void KyraEngine_v1::snd_playTheme(int file, int track) {
if (_curMusicTheme == file)
return;
diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h
index c3c32331be..f3de56520e 100644
--- a/engines/kyra/sound.h
+++ b/engines/kyra/sound.h
@@ -58,7 +58,7 @@ public:
};
virtual kType getMusicType() const = 0;
- virtual kType getSfxType() const { return getMusicType(); }
+ virtual kType getSfxType() const;
/**
* Initializes the output device.
@@ -83,7 +83,7 @@ public:
*
* @param list soundfile list
*/
- virtual void setSoundList(const AudioDataStruct *list) { _soundDataList = list; }
+ virtual void setSoundList(const AudioDataStruct *list);
/**
* Checks if a given sound file is present.
@@ -91,7 +91,7 @@ public:
* @param track track number
* @return true if available, false otherwise
*/
- virtual bool hasSoundFile(uint file) const { return (fileListEntry(file) != 0); }
+ virtual bool hasSoundFile(uint file) const;
/**
* Load a specifc sound file for use of
@@ -140,7 +140,7 @@ public:
*
* @return true if playing, false otherwise
*/
- virtual bool isPlaying() const { return false; }
+ virtual bool isPlaying() const;
/**
* Starts fading out the volume.
@@ -163,15 +163,13 @@ public:
void enableSFX(bool enable) { _sfxEnabled = enable; }
bool sfxEnabled() const { return _sfxEnabled; }
- virtual bool voiceFileIsPresent(const char *file);
-
/**
* Checks whether a voice file with the given name is present
*
* @param file file name
* @return true if available, false otherwise
*/
- bool isVoicePresent(const char *file);
+ bool isVoicePresent(const char *file) const;
/**
* Plays the specified voice file.
@@ -188,7 +186,7 @@ public:
*/
virtual int32 voicePlay(const char *file, Audio::SoundHandle *handle = 0, uint8 volume = 255, bool isSfx = false);
- Audio::SeekableAudioStream *getVoiceStream(const char *file);
+ Audio::SeekableAudioStream *getVoiceStream(const char *file) const;
bool playVoiceStream(Audio::AudioStream *stream, Audio::SoundHandle *handle = 0, uint8 volume = 255, bool isSfx = false);
@@ -197,21 +195,21 @@ public:
*
* @return true when playing, else false
*/
- bool voiceIsPlaying(const Audio::SoundHandle *handle = 0);
+ bool voiceIsPlaying(const Audio::SoundHandle *handle = 0) const;
/**
* Checks if all voice handles are used.
*
* @return false when a handle is free, else true
*/
- bool allVoiceChannelsPlaying();
+ bool allVoiceChannelsPlaying() const;
/**
* Checks how long a voice has been playing
*
* @return time in milliseconds
*/
- uint32 voicePlayedTime(const Audio::SoundHandle &handle) {
+ uint32 voicePlayedTime(const Audio::SoundHandle &handle) const {
return _mixer->getSoundElapsedTime(handle);
}
@@ -253,34 +251,34 @@ private:
class MixedSoundDriver : public Sound {
public:
- MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx) : Sound(vm, mixer), _music(music), _sfx(sfx) {}
- ~MixedSoundDriver() { delete _music; delete _sfx; }
+ MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx);
+ ~MixedSoundDriver();
- kType getMusicType() const { return _music->getMusicType(); }
- kType getSfxType() const { return _sfx->getSfxType(); }
+ virtual kType getMusicType() const;
+ virtual kType getSfxType() const;
- bool init() { return (_music->init() && _sfx->init()); }
- void process() { _music->process(); _sfx->process(); }
+ virtual bool init();
+ virtual void process();
- void updateVolumeSettings() { _music->updateVolumeSettings(); _sfx->updateVolumeSettings(); }
+ virtual void updateVolumeSettings();
- void setSoundList(const AudioDataStruct * list) { _music->setSoundList(list); _sfx->setSoundList(list); }
- bool hasSoundFile(uint file) const { return _music->hasSoundFile(file) && _sfx->hasSoundFile(file); }
- void loadSoundFile(uint file) { _music->loadSoundFile(file); _sfx->loadSoundFile(file); }
- void loadSoundFile(Common::String file) { _music->loadSoundFile(file); _sfx->loadSoundFile(file); }
+ virtual void setSoundList(const AudioDataStruct *list);
+ virtual bool hasSoundFile(uint file) const;
+ virtual void loadSoundFile(uint file);
+ virtual void loadSoundFile(Common::String file);
- void loadSfxFile(Common::String file) { _sfx->loadSoundFile(file); }
+ virtual void loadSfxFile(Common::String file);
- void playTrack(uint8 track) { _music->playTrack(track); }
- void haltTrack() { _music->haltTrack(); }
- bool isPlaying() const { return _music->isPlaying() | _sfx->isPlaying(); }
+ virtual void playTrack(uint8 track);
+ virtual void haltTrack();
+ virtual bool isPlaying() const;
- void playSoundEffect(uint8 track) { _sfx->playSoundEffect(track); }
+ virtual void playSoundEffect(uint8 track);
- void stopAllSoundEffects() { _sfx->stopAllSoundEffects(); }
+ virtual void stopAllSoundEffects();
- void beginFadeOut() { _music->beginFadeOut(); }
- void pause(bool paused) { _music->pause(paused); _sfx->pause(paused); }
+ virtual void beginFadeOut();
+ virtual void pause(bool paused);
private:
Sound *_music, *_sfx;
};
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp
index 8976eba99c..b04abea080 100644
--- a/engines/kyra/sound_adlib.cpp
+++ b/engines/kyra/sound_adlib.cpp
@@ -42,6 +42,7 @@
#include "common/system.h"
#include "common/mutex.h"
+#include "common/config-manager.h"
#include "audio/mixer.h"
#include "audio/fmopl.h"
@@ -59,7 +60,13 @@ public:
AdLibDriver(Audio::Mixer *mixer, bool v2);
~AdLibDriver();
- int callback(int opcode, ...);
+ void initDriver();
+ void setSoundData(uint8 *data);
+ void queueTrack(int track);
+ bool isChannelPlaying(int channel) const;
+ void stopAllChannels();
+ int getSoundTrigger() const { return _soundTrigger; }
+
void callback();
// AudioStream API
@@ -92,36 +99,10 @@ public:
void setSyncJumpMask(uint16 mask) { _syncJumpMask = mask; }
-private:
- struct OpcodeEntry {
- typedef int (AdLibDriver::*DriverOpcode)(va_list &list);
- DriverOpcode function;
- const char *name;
- };
-
- void setupOpcodeList();
- const OpcodeEntry *_opcodeList;
- int _opcodesEntries;
-
- int snd_ret0x100(va_list &list);
- int snd_ret0x1983(va_list &list);
- int snd_initDriver(va_list &list);
- int snd_deinitDriver(va_list &list);
- int snd_setSoundData(va_list &list);
- int snd_unkOpcode1(va_list &list);
- int snd_startSong(va_list &list);
- int snd_isChannelPlaying(va_list &list);
- int snd_stopChannel(va_list &list);
- int snd_readByte(va_list &list);
- int snd_writeByte(va_list &list);
- int snd_getSoundTrigger(va_list &list);
- int snd_unkOpcode4(va_list &list);
- int snd_dummy(va_list &list);
- int snd_getNullvar4(va_list &list);
- int snd_setNullvar3(va_list &list);
- int snd_setFlag(va_list &list);
- int snd_clearFlag(va_list &list);
+ void setMusicVolume(uint8 volume);
+ void setSfxVolume(uint8 volume);
+private:
// These variables have not yet been named, but some of them are partly
// known nevertheless:
//
@@ -195,6 +176,7 @@ private:
uint8 tempoReset;
uint8 rawNote;
int8 unk16;
+ uint8 volumeModifier;
};
void primaryEffect1(Channel &channel);
@@ -346,11 +328,8 @@ private:
int32 _samplesTillCallback;
int32 _samplesTillCallbackRemainder;
- int _lastProcessed;
- int8 _flagTrigger;
int _curChannel;
uint8 _soundTrigger;
- int _soundsPlaying;
uint16 _rnd;
@@ -375,12 +354,19 @@ private:
uint8 _unkValue19;
uint8 _unkValue20;
- int _flags;
FM_OPL *_adlib;
uint8 *_soundData;
- uint8 _soundIdTable[0x10];
+ int _programStartTimeout;
+ uint8 *_programQueue[16];
+ int _programQueueStart, _programQueueEnd;
+
+ void adjustSfxData(uint8 *data);
+ uint8 *_sfxPointer;
+ int _sfxPriority;
+ int _sfxVelocity;
+
Channel _channels[10];
uint8 _vibratoAndAMDepthBits;
@@ -406,18 +392,18 @@ private:
Audio::Mixer *_mixer;
Audio::SoundHandle _soundHandle;
+ uint8 _musicVolume, _sfxVolume;
+
bool _v2;
};
AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
- setupOpcodeList();
setupParserOpcodeTable();
_v2 = v2;
_mixer = mixer;
- _flags = 0;
_adlib = makeAdLibOPL(getRate());
assert(_adlib);
@@ -426,12 +412,12 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
_vibratoAndAMDepthBits = _curRegOffset = 0;
- _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0;
- _soundsPlaying = 0;
+ _curChannel = _rhythmSectionBits = 0;
_rnd = 0x1234;
_tempo = 0;
_soundTrigger = 0;
+ _programStartTimeout = 0;
_callbackTimer = 0xFF;
_unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0;
@@ -441,14 +427,7 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
_tablePtr1 = _tablePtr2 = 0;
- // HACK: We use MusicSoundType here for now so we can adjust the volume in the launcher dialog.
- // This affects SFX too, but if we want to support different volumes for SFX and music we would
- // have to change our player implementation, currently we setup the volume for an AdLib channel
- // in AdLibDriver::adjustVolume, so if that would be called, we would have to know if the channel
- // is used by SFX or music, and then adjust the volume accordingly. Since Kyrandia 2 supports
- // different volumes for SFX and music, looking at the disasm and checking how the original does it
- // would be a good idea.
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
_samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
_samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
@@ -456,6 +435,13 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) {
_samplesTillCallbackRemainder = 0;
_syncJumpMask = 0;
+
+ _musicVolume = 0;
+ _sfxVolume = 0;
+
+ _sfxPointer = 0;
+
+ _programQueueStart = _programQueueEnd = 0;
}
AdLibDriver::~AdLibDriver() {
@@ -464,100 +450,108 @@ AdLibDriver::~AdLibDriver() {
_adlib = 0;
}
-int AdLibDriver::callback(int opcode, ...) {
+void AdLibDriver::setMusicVolume(uint8 volume) {
Common::StackLock lock(_mutex);
- if (opcode >= _opcodesEntries || opcode < 0) {
- warning("AdLibDriver: calling unknown opcode '%d'", opcode);
- return 0;
+
+ _musicVolume = volume;
+
+ for (uint i = 0; i < 6; ++i) {
+ Channel &chan = _channels[i];
+ chan.volumeModifier = volume;
+
+ const uint8 regOffset = _regOffset[i];
+
+ // Level Key Scaling / Total Level
+ writeOPL(0x40 + regOffset, calculateOpLevel1(chan));
+ writeOPL(0x43 + regOffset, calculateOpLevel2(chan));
}
- debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d)", _opcodeList[opcode].name, opcode);
+ // For now we use the music volume for both sfx and music in Kyra1.
+ if (!_v2) {
+ _sfxVolume = volume;
- va_list args;
- va_start(args, opcode);
- int returnValue = (this->*(_opcodeList[opcode].function))(args);
- va_end(args);
- return returnValue;
-}
+ for (uint i = 6; i < 9; ++i) {
+ Channel &chan = _channels[i];
+ chan.volumeModifier = volume;
-// Opcodes
+ const uint8 regOffset = _regOffset[i];
-int AdLibDriver::snd_ret0x100(va_list &list) {
- return 0x100;
+ // Level Key Scaling / Total Level
+ writeOPL(0x40 + regOffset, calculateOpLevel1(chan));
+ writeOPL(0x43 + regOffset, calculateOpLevel2(chan));
+ }
+ }
}
-int AdLibDriver::snd_ret0x1983(va_list &list) {
- return 0x1983;
-}
+void AdLibDriver::setSfxVolume(uint8 volume) {
+ // We only support sfx volume in v2 games.
+ if (!_v2)
+ return;
-int AdLibDriver::snd_initDriver(va_list &list) {
- _lastProcessed = _soundsPlaying = 0;
- resetAdLibState();
- return 0;
+ Common::StackLock lock(_mutex);
+
+ _sfxVolume = volume;
+
+ for (uint i = 6; i < 9; ++i) {
+ Channel &chan = _channels[i];
+ chan.volumeModifier = volume;
+
+ const uint8 regOffset = _regOffset[i];
+
+ // Level Key Scaling / Total Level
+ writeOPL(0x40 + regOffset, calculateOpLevel1(chan));
+ writeOPL(0x43 + regOffset, calculateOpLevel2(chan));
+ }
}
-int AdLibDriver::snd_deinitDriver(va_list &list) {
+void AdLibDriver::initDriver() {
+ Common::StackLock lock(_mutex);
resetAdLibState();
- return 0;
}
-int AdLibDriver::snd_setSoundData(va_list &list) {
+void AdLibDriver::setSoundData(uint8 *data) {
+ Common::StackLock lock(_mutex);
+
+ // Drop all tracks that are still queued. These would point to the old
+ // sound data.
+ _programQueueStart = _programQueueEnd = 0;
+ memset(_programQueue, 0, sizeof(_programQueue));
+
if (_soundData) {
delete[] _soundData;
_soundData = 0;
}
- _soundData = va_arg(list, uint8 *);
- return 0;
-}
-int AdLibDriver::snd_unkOpcode1(va_list &list) {
- warning("unimplemented snd_unkOpcode1");
- return 0;
+ _soundData = data;
}
-int AdLibDriver::snd_startSong(va_list &list) {
- int songId = va_arg(list, int);
- _flags |= 8;
- _flagTrigger = 1;
+void AdLibDriver::queueTrack(int track) {
+ Common::StackLock lock(_mutex);
- uint8 *ptr = getProgram(songId);
- assert(ptr);
- uint8 chan = *ptr;
+ uint8 *trackData = getProgram(track);
+ if (!trackData)
+ return;
- if ((songId << 1) != 0) {
- if (chan == 9) {
- if (_flags & 2)
- return 0;
- } else {
- if (_flags & 1)
- return 0;
- }
+ if (_programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd] != 0) {
+ warning("AdLibDriver: Program queue full, dropping track %d", track);
+ return;
}
- _soundIdTable[_soundsPlaying++] = songId;
- _soundsPlaying &= 0x0F;
-
- return 0;
+ _programQueue[_programQueueEnd++] = trackData;
+ _programQueueEnd &= 15;
}
-int AdLibDriver::snd_isChannelPlaying(va_list &list) {
- int channel = va_arg(list, int);
+bool AdLibDriver::isChannelPlaying(int channel) const {
+ Common::StackLock lock(_mutex);
+
assert(channel >= 0 && channel <= 9);
- return (_channels[channel].dataptr != 0) ? 1 : 0;
+ return (_channels[channel].dataptr != 0);
}
-int AdLibDriver::snd_stopChannel(va_list &list) {
- int channel = va_arg(list, int);
-
- int maxChannel;
- if (channel < 0) {
- channel = 0;
- maxChannel = 9;
- } else {
- maxChannel = channel;
- }
+void AdLibDriver::stopAllChannels() {
+ Common::StackLock lock(_mutex);
- for (; channel <= maxChannel; ++channel) {
+ for (int channel = 0; channel <= 9; ++channel) {
_curChannel = channel;
Channel &chan = _channels[_curChannel];
@@ -567,71 +561,16 @@ int AdLibDriver::snd_stopChannel(va_list &list) {
if (channel != 9)
noteOff(chan);
}
-
- return 0;
-}
-
-int AdLibDriver::snd_readByte(va_list &list) {
- int a = va_arg(list, int);
- int b = va_arg(list, int);
- uint8 *ptr = getProgram(a) + b;
- assert(ptr);
- return *ptr;
-}
-
-int AdLibDriver::snd_writeByte(va_list &list) {
- int a = va_arg(list, int);
- int b = va_arg(list, int);
- uint8 value = va_arg(list, int);
- uint8 *ptr = getProgram(a) + b;
- assert(ptr);
- SWAP(*ptr, value);
- return value;
-}
-
-int AdLibDriver::snd_getSoundTrigger(va_list &list) {
- return _soundTrigger;
-}
-
-int AdLibDriver::snd_unkOpcode4(va_list &list) {
- warning("unimplemented snd_unkOpcode4");
- return 0;
-}
-
-int AdLibDriver::snd_dummy(va_list &list) {
- return 0;
-}
-
-int AdLibDriver::snd_getNullvar4(va_list &list) {
- warning("unimplemented snd_getNullvar4");
- return 0;
-}
-
-int AdLibDriver::snd_setNullvar3(va_list &list) {
- warning("unimplemented snd_setNullvar3");
- return 0;
-}
-
-int AdLibDriver::snd_setFlag(va_list &list) {
- int oldFlags = _flags;
- _flags |= va_arg(list, int);
- return oldFlags;
-}
-
-int AdLibDriver::snd_clearFlag(va_list &list) {
- int oldFlags = _flags;
- _flags &= ~(va_arg(list, int));
- return oldFlags;
}
// timer callback
void AdLibDriver::callback() {
Common::StackLock lock(_mutex);
- --_flagTrigger;
- if (_flagTrigger < 0)
- _flags &= ~8;
- setupPrograms();
+ if (_programStartTimeout)
+ --_programStartTimeout;
+ else
+ setupPrograms();
executePrograms();
uint8 temp = _callbackTimer;
@@ -645,36 +584,86 @@ void AdLibDriver::callback() {
}
void AdLibDriver::setupPrograms() {
- while (_lastProcessed != _soundsPlaying) {
- uint8 *ptr = getProgram(_soundIdTable[_lastProcessed]);
- uint8 chan = *ptr++;
- uint8 priority = *ptr++;
-
- // Only start this sound if its priority is higher than the one
- // already playing.
-
- Channel &channel = _channels[chan];
-
- if (priority >= channel.priority) {
- initChannel(channel);
- channel.priority = priority;
- channel.dataptr = ptr;
- channel.tempo = 0xFF;
- channel.position = 0xFF;
- channel.duration = 1;
- unkOutput2(chan);
- }
+ // If there is no program queued, we skip this.
+ if (_programQueueStart == _programQueueEnd)
+ return;
+
+ uint8 *ptr = _programQueue[_programQueueStart];
+ // Clear the queue entry
+ _programQueue[_programQueueStart] = 0;
+ _programQueueStart = (_programQueueStart + 1) & 15;
+
+ // Adjust data in case we hit a sound effect.
+ adjustSfxData(ptr);
+
+ const int chan = *ptr++;
+ const int priority = *ptr++;
+
+ // Only start this sound if its priority is higher than the one
+ // already playing.
+
+ Channel &channel = _channels[chan];
- // What we have set up now is, probably, the controlling
- // channel for the sound. It is assumed that this program will
- // set up all the other channels it needs, clearing their locks
- // along the way.
+ if (priority >= channel.priority) {
+ initChannel(channel);
+ channel.priority = priority;
+ channel.dataptr = ptr;
+ channel.tempo = 0xFF;
+ channel.position = 0xFF;
+ channel.duration = 1;
- ++_lastProcessed;
- _lastProcessed &= 0x0F;
+ if (chan <= 5)
+ channel.volumeModifier = _musicVolume;
+ else
+ channel.volumeModifier = _sfxVolume;
+
+ unkOutput2(chan);
+
+ // We need to wait two callback calls till we can start another track.
+ // This is (probably) required to assure that the sfx are started with
+ // the correct priority and velocity.
+ _programStartTimeout = 2;
}
}
+void AdLibDriver::adjustSfxData(uint8 *ptr) {
+ // Check whether we need to reset the data of an old sfx which has been
+ // started.
+ if (_sfxPointer) {
+ _sfxPointer[1] = _sfxPriority;
+ _sfxPointer[3] = _sfxVelocity;
+ _sfxPointer = 0;
+ }
+
+ // Only music tracks are started on channel 9, thus we need to make sure
+ // we do not have a music track here.
+ if (*ptr == 9)
+ return;
+
+ // Store the pointer so we can reset the data when a new program is started.
+ _sfxPointer = ptr;
+
+ // Store the old values.
+ _sfxPriority = ptr[1];
+ _sfxVelocity = ptr[3];
+
+ // In the cases I've seen, the mysterious fourth byte has been
+ // the parameter for the update_setExtraLevel3() callback.
+ //
+ // The extra level is part of the channels "total level", which
+ // is a six-bit value where larger values means softer volume.
+ //
+ // So what seems to be happening here is that sounds which are
+ // started by this function are given a slightly lower priority
+ // and a slightly higher (i.e. softer) extra level 3 than they
+ // would have if they were started from anywhere else. Strange.
+
+ // Adjust the values.
+ int newVal = ((((ptr[3]) + 63) * 0xFF) >> 8) & 0xFF;
+ ptr[3] = -newVal + 63;
+ ptr[1] = ((ptr[1] * 0xFF) >> 8) & 0xFF;
+}
+
// A few words on opcode parsing and timing:
//
// First of all, We simulate a timer callback 72 times per second. Each timeout
@@ -1273,9 +1262,21 @@ uint8 AdLibDriver::calculateOpLevel1(Channel &channel) {
if (channel.twoChan) {
value += channel.opExtraLevel1;
value += channel.opExtraLevel2;
- value += channel.opExtraLevel3;
+
+ uint16 level3 = (channel.opExtraLevel3 ^ 0x3F) * channel.volumeModifier;
+ if (level3) {
+ level3 += 0x3F;
+ level3 >>= 8;
+ }
+
+ value += level3 ^ 0x3F;
}
+ value = CLIP<int8>(value, 0, 0x3F);
+
+ if (!channel.volumeModifier)
+ value = 0x3F;
+
// Preserve the scaling level bits from opLevel1
return checkValue(value) | (channel.opLevel1 & 0xC0);
@@ -1286,7 +1287,19 @@ uint8 AdLibDriver::calculateOpLevel2(Channel &channel) {
value += channel.opExtraLevel1;
value += channel.opExtraLevel2;
- value += channel.opExtraLevel3;
+
+ uint16 level3 = (channel.opExtraLevel3 ^ 0x3F) * channel.volumeModifier;
+ if (level3) {
+ level3 += 0x3F;
+ level3 >>= 8;
+ }
+
+ value += level3 ^ 0x3F;
+
+ value = CLIP<int8>(value, 0, 0x3F);
+
+ if (!channel.volumeModifier)
+ value = 0x3F;
// Preserve the scaling level bits from opLevel2
@@ -1323,14 +1336,22 @@ int AdLibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 va
Channel &channel2 = _channels[chan];
if (priority >= channel2.priority) {
- _flagTrigger = 1;
- _flags |= 8;
+ // We keep new tracks from being started for two further iterations of
+ // the callback. This assures the correct velocity is used for this
+ // program.
+ _programStartTimeout = 2;
initChannel(channel2);
channel2.priority = priority;
channel2.dataptr = ptr;
channel2.tempo = 0xFF;
channel2.position = 0xFF;
channel2.duration = 1;
+
+ if (chan <= 5)
+ channel2.volumeModifier = _musicVolume;
+ else
+ channel2.volumeModifier = _sfxVolume;
+
unkOutput2(chan);
}
@@ -1911,32 +1932,6 @@ int AdLibDriver::updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value
#define COMMAND(x) { &AdLibDriver::x, #x }
-void AdLibDriver::setupOpcodeList() {
- static const OpcodeEntry opcodeList[] = {
- COMMAND(snd_ret0x100),
- COMMAND(snd_ret0x1983),
- COMMAND(snd_initDriver),
- COMMAND(snd_deinitDriver),
- COMMAND(snd_setSoundData),
- COMMAND(snd_unkOpcode1),
- COMMAND(snd_startSong),
- COMMAND(snd_isChannelPlaying),
- COMMAND(snd_stopChannel),
- COMMAND(snd_readByte),
- COMMAND(snd_writeByte),
- COMMAND(snd_getSoundTrigger),
- COMMAND(snd_unkOpcode4),
- COMMAND(snd_dummy),
- COMMAND(snd_getNullvar4),
- COMMAND(snd_setNullvar3),
- COMMAND(snd_setFlag),
- COMMAND(snd_clearFlag)
- };
-
- _opcodeList = opcodeList;
- _opcodesEntries = ARRAYSIZE(opcodeList);
-}
-
void AdLibDriver::setupParserOpcodeTable() {
static const ParserOpcode parserOpcodeTable[] = {
// 0
@@ -2266,13 +2261,12 @@ SoundAdLibPC::~SoundAdLibPC() {
}
bool SoundAdLibPC::init() {
- _driver->callback(2);
- _driver->callback(16, int(4));
+ _driver->initDriver();
return true;
}
void SoundAdLibPC::process() {
- uint8 trigger = _driver->callback(11);
+ int trigger = _driver->getSoundTrigger();
if (trigger < _numSoundTriggers) {
int soundId = _soundTriggers[trigger];
@@ -2285,6 +2279,23 @@ void SoundAdLibPC::process() {
}
}
+void SoundAdLibPC::updateVolumeSettings() {
+ bool mute = false;
+ if (ConfMan.hasKey("mute"))
+ mute = ConfMan.getBool("mute");
+
+ int newMusicVolume = mute ? 0 : ConfMan.getInt("music_volume");
+ //newMusicVolume = (newMusicVolume * 145) / Audio::Mixer::kMaxMixerVolume + 110;
+ newMusicVolume = CLIP(newMusicVolume, 0, 255);
+
+ int newSfxVolume = mute ? 0 : ConfMan.getInt("sfx_volume");
+ //newSfxVolume = (newSfxVolume * 200) / Audio::Mixer::kMaxMixerVolume + 55;
+ newSfxVolume = CLIP(newSfxVolume, 0, 255);
+
+ _driver->setMusicVolume(newMusicVolume);
+ _driver->setSfxVolume(newSfxVolume);
+}
+
void SoundAdLibPC::playTrack(uint8 track) {
if (_musicEnabled) {
// WORKAROUND: There is a bug in the Kyra 1 "Pool of Sorrow"
@@ -2301,13 +2312,13 @@ void SoundAdLibPC::playTrack(uint8 track) {
}
void SoundAdLibPC::haltTrack() {
- playSoundEffect(0);
- playSoundEffect(0);
+ play(0);
+ play(0);
//_vm->_system->delayMillis(3 * 60);
}
bool SoundAdLibPC::isPlaying() const {
- return _driver->callback(7, int(0)) != 0;
+ return _driver->isChannelPlaying(0);
}
void SoundAdLibPC::playSoundEffect(uint8 track) {
@@ -2326,60 +2337,11 @@ void SoundAdLibPC::play(uint8 track) {
if ((soundId == 0xFFFF && _v2) || (soundId == 0xFF && !_v2) || !_soundDataPtr)
return;
- // HACK: Since we might call this when the engines is paused (on game load via GMM)
- // we must unpause the engine here, so this will work properly
-
- int pauseCount = 0;
- while (_vm->isPaused()) {
- ++pauseCount;
- _vm->pauseEngine(false);
- }
-
- while ((_driver->callback(16, 0) & 8)) {
- // We call the system delay and not the game delay to avoid concurrency issues.
- _vm->_system->delayMillis(10);
- }
-
- while (pauseCount--)
- _vm->pauseEngine(true);
-
- if (_sfxPlayingSound != -1) {
- // Restore the sounds's normal values.
- _driver->callback(10, _sfxPlayingSound, int(1), int(_sfxPriority));
- _driver->callback(10, _sfxPlayingSound, int(3), int(_sfxFourthByteOfSong));
- _sfxPlayingSound = -1;
- }
-
- int chan = _driver->callback(9, soundId, int(0));
-
- if (chan != 9) {
- _sfxPlayingSound = soundId;
- _sfxPriority = _driver->callback(9, soundId, int(1));
- _sfxFourthByteOfSong = _driver->callback(9, soundId, int(3));
-
- // In the cases I've seen, the mysterious fourth byte has been
- // the parameter for the update_setExtraLevel3() callback.
- //
- // The extra level is part of the channels "total level", which
- // is a six-bit value where larger values means softer volume.
- //
- // So what seems to be happening here is that sounds which are
- // started by this function are given a slightly lower priority
- // and a slightly higher (i.e. softer) extra level 3 than they
- // would have if they were started from anywhere else. Strange.
-
- int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF;
- newVal = -newVal + 63;
- _driver->callback(10, soundId, int(3), newVal);
- newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF;
- _driver->callback(10, soundId, int(1), newVal);
- }
-
- _driver->callback(6, soundId);
+ _driver->queueTrack(soundId);
}
void SoundAdLibPC::beginFadeOut() {
- playSoundEffect(1);
+ play(1);
}
void SoundAdLibPC::loadSoundFile(uint file) {
@@ -2409,7 +2371,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) {
playSoundEffect(0);
playSoundEffect(0);
- _driver->callback(8, int(-1));
+ _driver->stopAllChannels();
_soundDataPtr = 0;
int soundDataSize = fileSize;
@@ -2434,7 +2396,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) {
fileData = p = 0;
fileSize = 0;
- _driver->callback(4, _soundDataPtr);
+ _driver->setSoundData(_soundDataPtr);
_soundFileLoaded = file;
}
diff --git a/engines/kyra/sound_adlib.h b/engines/kyra/sound_adlib.h
index c09fec997e..923a4cb75f 100644
--- a/engines/kyra/sound_adlib.h
+++ b/engines/kyra/sound_adlib.h
@@ -62,22 +62,23 @@ public:
SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer);
~SoundAdLibPC();
- kType getMusicType() const { return kAdLib; }
+ virtual kType getMusicType() const { return kAdLib; }
- bool init();
- void process();
+ virtual bool init();
+ virtual void process();
- void loadSoundFile(uint file);
- void loadSoundFile(Common::String file);
- void loadSoundFile(const uint8 *soundData, int dataSize) {}
+ virtual void updateVolumeSettings();
- void playTrack(uint8 track);
- void haltTrack();
- bool isPlaying() const;
+ virtual void loadSoundFile(uint file);
+ virtual void loadSoundFile(Common::String file);
- void playSoundEffect(uint8 track);
+ virtual void playTrack(uint8 track);
+ virtual void haltTrack();
+ virtual bool isPlaying() const;
- void beginFadeOut();
+ virtual void playSoundEffect(uint8 track);
+
+ virtual void beginFadeOut();
private:
void internalLoadFile(Common::String file);
@@ -92,9 +93,6 @@ private:
Common::String _soundFileLoaded;
- uint8 _sfxPriority;
- uint8 _sfxFourthByteOfSong;
-
int _numSoundTriggers;
const int *_soundTriggers;
diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp
index dbe2f1c7ba..168902d577 100644
--- a/engines/made/screen.cpp
+++ b/engines/made/screen.cpp
@@ -437,15 +437,15 @@ uint16 Screen::placeSprite(uint16 channelIndex, uint16 flexIndex, int16 x, int16
PictureResource *flex = _vm->_res->getPicture(flexIndex);
if (flex) {
- Graphics::Surface *surf = flex->getPicture();
+ //Graphics::Surface *surf = flex->getPicture();
int16 state = 1;
- int16 x1, y1, x2, y2;
+ /*int16 x1, y1, x2, y2;
x1 = x;
y1 = y;
x2 = x + surf->w + 1;
- y2 = y + surf->h + 1;
+ y2 = y + surf->h + 1;*/
if (_ground == 0)
state |= 2;
@@ -485,12 +485,12 @@ uint16 Screen::placeAnim(uint16 channelIndex, uint16 animIndex, int16 x, int16 y
if (anim) {
int16 state = 1;
- int16 x1, y1, x2, y2;
+ /*int16 x1, y1, x2, y2;
x1 = x;
y1 = y;
x2 = x + anim->getWidth();
- y2 = y + anim->getHeight();
+ y2 = y + anim->getHeight();*/
if (anim->getFlags() == 1 || _ground == 0)
state |= 2;
@@ -543,7 +543,7 @@ uint16 Screen::placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, i
Object *obj = _vm->_dat->getObject(textObjectIndex);
const char *text = obj->getString();
- int16 x1, y1, x2, y2;
+ //int16 x1, y1, x2, y2;
setFont(fontNum);
@@ -557,10 +557,10 @@ uint16 Screen::placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, i
y--;
}
- x1 = x;
+ /*x1 = x;
y1 = y;
x2 = x + textWidth;
- y2 = y + textHeight;
+ y2 = y + textHeight;*/
if (textWidth > 0 && outlineColor != -1) {
x++;
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index 091ec8d427..d39ec34cc8 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -209,7 +209,7 @@ int SagaMetaEngine::getMaximumSaveSlot() const { return MAX_SAVES - 1; }
void SagaMetaEngine::removeSaveState(const char *target, int slot) const {
Common::String filename = target;
- filename += Common::String::format(".s%02d", slot);;
+ filename += Common::String::format(".s%02d", slot);
g_system->getSavefileManager()->removeSavefile(filename);
}
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 8cb294e166..e549c1f8ae 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -457,6 +457,7 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv);
reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv);
reg_t kInPolygon(EngineState *s, int argc, reg_t *argv);
reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv);
+reg_t kEditText(EngineState *s, int argc, reg_t *argv);
// SCI2.1 Kernel Functions
reg_t kText(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index afe6b176e5..d8d9f6bd82 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -499,6 +499,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(UpdatePlane), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(ObjectIntersect), SIG_EVERYWHERE, "oo", NULL, NULL },
+ { MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL },
// SCI2 unmapped functions - TODO!
@@ -523,13 +524,6 @@ static SciKernelMapEntry s_kernelMap[] = {
// TODO: Implement once the original save/load menus are implemented.
{ MAP_DUMMY(MakeSaveFileName), SIG_EVERYWHERE, "(.*)", NULL, NULL },
- // Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl,
- // but it handles events on its own, using an internal loop, instead of using SCI
- // scripts for event management like kEditControl does. Called by script 64914,
- // DEdit::hilite().
- // TODO: Implement once the original save/load menus are implemented.
- { MAP_DUMMY(EditText), SIG_EVERYWHERE, "o", NULL, NULL },
-
// Unused / debug SCI2 unused functions, always mapped to kDummy
// AddMagnify/DeleteMagnify are both called by script 64979 (the Magnifier
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 9e9441847d..ce903626e7 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -22,6 +22,7 @@
#include "common/archive.h"
#include "common/config-manager.h"
+#include "common/debug-channels.h"
#include "common/file.h"
#include "common/str.h"
#include "common/savefile.h"
@@ -52,9 +53,10 @@ struct SavegameDesc {
* arbitrary data files, simply because many of our target platforms do not
* support this. The only files one can create are savestates. But SCI has an
* opcode to create and write to seemingly 'arbitrary' files. This is mainly
- * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver) and
- * in LSL5 for MEMORY.DRV (which is again a game data file and contains the
- * game's password).
+ * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver, used
+ * for persisting the results of the "age quiz" across restarts) and in LSL5
+ * for MEMORY.DRV (which is again a game data file and contains the game's
+ * password, XOR encrypted).
* To implement that opcode, we combine the SaveFileManager with regular file
* code, similarly to how the SCUMM HE engine does it.
*
@@ -115,20 +117,6 @@ reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool u
if (!inFile)
inFile = SearchMan.createReadStreamForMember(englishName);
- // Special case for LSL3: It tries to create a new dummy file,
- // LARRY3.DRV. Apparently, if the file doesn't exist here, it should be
- // created. The game scripts then go ahead and fill its contents with
- // data. It seems to be a similar case as the dummy MEMORY.DRV file in
- // LSL5, but LSL5 creates the file if it can't find it with a separate
- // call to file_open().
- if (!inFile && englishName == "LARRY3.DRV") {
- outFile = saveFileMan->openForSaving(wrappedName);
- outFile->finalize();
- delete outFile;
- outFile = 0;
- inFile = SearchMan.createReadStreamForMember(wrappedName);
- }
-
if (!inFile)
debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str());
} else if (mode == _K_FILE_MODE_CREATE) {
@@ -1060,6 +1048,18 @@ reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) {
exists = !saveFileMan->listSavefiles(wrappedName).empty();
}
+ // SCI2+ debug mode
+ if (DebugMan.isDebugChannelEnabled(kDebugLevelDebugMode)) {
+ if (!exists && name == "1.scr") // PQ4
+ exists = true;
+ if (!exists && name == "18.scr") // QFG4
+ exists = true;
+ if (!exists && name == "99.scr") // GK1, KQ7
+ exists = true;
+ if (!exists && name == "classes") // GK2, SQ6, LSL7
+ exists = true;
+ }
+
// Special case for non-English versions of LSL5: The English version of
// LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if
// memory.drv exists (which is where the game's password is stored). If
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 566f2a9a7d..76c6778f0a 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -49,6 +49,7 @@
#include "sci/graphics/text16.h"
#include "sci/graphics/view.h"
#ifdef ENABLE_SCI32
+#include "sci/graphics/controls32.h"
#include "sci/graphics/font.h" // TODO: remove once kBitmap is moved in a separate class
#include "sci/graphics/text32.h"
#include "sci/graphics/frameout.h"
@@ -1665,8 +1666,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
memset(memoryPtr + BITMAP_HEADER_SIZE, back, width * height);
// Save totalWidth, totalHeight
// TODO: Save the whole bitmap header, like SSCI does
- WRITE_LE_UINT16((void *)memoryPtr, width);
- WRITE_LE_UINT16((void *)(memoryPtr + 2), height);
+ WRITE_LE_UINT16(memoryPtr, width);
+ WRITE_LE_UINT16(memoryPtr + 2, height);
return memoryId;
}
break;
@@ -1692,8 +1693,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
// Get totalWidth, totalHeight
- uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr);
- uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2));
+ uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+ uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
GfxView *view = g_sci->_gfxCache->getView(viewNum);
@@ -1733,8 +1734,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
// Get totalWidth, totalHeight
- uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr);
- uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2));
+ uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+ uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
GfxFont *font = g_sci->_gfxCache->getFont(fontId);
@@ -1776,8 +1777,8 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
byte *memoryPtr = s->_segMan->getHunkPointer(hunkId);
// Get totalWidth, totalHeight
- uint16 totalWidth = READ_LE_UINT16((void *)memoryPtr);
- uint16 totalHeight = READ_LE_UINT16((void *)(memoryPtr + 2));
+ uint16 totalWidth = READ_LE_UINT16(memoryPtr);
+ uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2);
uint16 width = MIN<uint16>(totalWidth - x, fillWidth);
uint16 height = MIN<uint16>(totalHeight - y, fillHeight);
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
@@ -1798,6 +1799,20 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) {
return s->r_acc;
}
+// Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl,
+// but it handles events on its own, using an internal loop, instead of using SCI
+// scripts for event management like kEditControl does. Called by script 64914,
+// DEdit::hilite().
+reg_t kEditText(EngineState *s, int argc, reg_t *argv) {
+ reg_t controlObject = argv[0];
+
+ if (!controlObject.isNull()) {
+ g_sci->_gfxControls32->kernelTexteditChange(controlObject);
+ }
+
+ return s->r_acc;
+}
+
#endif
} // End of namespace Sci
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 1a9359bb26..5ae18c1367 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -697,13 +697,15 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
case 6: { // Cpy
const char *string2 = 0;
uint32 string2Size = 0;
+ Common::String string;
if (argv[3].segment == s->_segMan->getStringSegmentId()) {
- SciString *string = s->_segMan->lookupString(argv[3]);
- string2 = string->getRawData();
- string2Size = string->getSize();
+ SciString *sstr;
+ sstr = s->_segMan->lookupString(argv[3]);
+ string2 = sstr->getRawData();
+ string2Size = sstr->getSize();
} else {
- Common::String string = s->_segMan->getString(argv[3]);
+ string = s->_segMan->getString(argv[3]);
string2 = string.c_str();
string2Size = string.size() + 1;
}
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index a9aca9e22f..a8b1cf7ec2 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -178,6 +178,7 @@ void Kernel::mapSelectors() {
FIND_SELECTOR(dimmed);
FIND_SELECTOR(fore);
FIND_SELECTOR(back);
+ FIND_SELECTOR(skip);
FIND_SELECTOR(fixPriority);
FIND_SELECTOR(mirrored);
FIND_SELECTOR(useInsetRect);
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index bbd86bb03e..4b913a866a 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -144,6 +144,7 @@ struct SelectorCache {
Selector fore;
Selector back;
+ Selector skip;
Selector dimmed;
Selector fixPriority;
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index c14cfada07..378e88b7df 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -253,14 +253,11 @@ SciEvent EventManager::getScummVMEvent() {
if ((modifiers & Common::KBD_ALT) && input.character > 0 && input.character < 27)
input.character += 96; // 0x01 -> 'a'
- if (getSciVersion() <= SCI_VERSION_1_MIDDLE) {
- // TODO: find out if altify is also not needed for sci1late+, couldnt find any game that uses those keys
- // Scancodify if appropriate
- if (modifiers & Common::KBD_ALT)
- input.character = altify(input.character);
- else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
- input.character += 96; // 0x01 -> 'a'
- }
+ // Scancodify if appropriate
+ if (modifiers & Common::KBD_ALT)
+ input.character = altify(input.character);
+ else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
+ input.character += 96; // 0x01 -> 'a'
// If no actual key was pressed (e.g. if only a modifier key was pressed),
// ignore the event
diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp
new file mode 100644
index 0000000000..ad1d9e8623
--- /dev/null
+++ b/engines/sci/graphics/controls32.cpp
@@ -0,0 +1,204 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+
+#include "sci/sci.h"
+#include "sci/event.h"
+#include "sci/engine/kernel.h"
+#include "sci/engine/seg_manager.h"
+#include "sci/graphics/cache.h"
+#include "sci/graphics/compare.h"
+#include "sci/graphics/controls32.h"
+#include "sci/graphics/font.h"
+#include "sci/graphics/screen.h"
+#include "sci/graphics/text32.h"
+
+namespace Sci {
+
+GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text)
+ : _segMan(segMan), _cache(cache), _screen(screen), _text(text) {
+}
+
+GfxControls32::~GfxControls32() {
+}
+
+void GfxControls32::kernelTexteditChange(reg_t controlObject) {
+ SciEvent curEvent;
+ uint16 maxChars = 40; //readSelectorValue(_segMan, controlObject, SELECTOR(max)); // TODO
+ reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text));
+ GfxFont *font = _cache->getFont(readSelectorValue(_segMan, controlObject, SELECTOR(font)));
+ Common::String text;
+ uint16 textSize;
+ bool textChanged = false;
+ bool textAddChar = false;
+ Common::Rect rect;
+
+ if (textReference.isNull())
+ error("kEditControl called on object that doesnt have a text reference");
+ text = _segMan->getString(textReference);
+
+ // TODO: Finish this
+ warning("kEditText ('%s')", text.c_str());
+ return;
+
+ uint16 cursorPos = 0;
+ //uint16 oldCursorPos = cursorPos;
+ bool captureEvents = true;
+ EventManager* eventMan = g_sci->getEventManager();
+
+ while (captureEvents) {
+ curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK);
+
+ if (curEvent.type == SCI_EVENT_NONE) {
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ } else {
+ textSize = text.size();
+
+ switch (curEvent.type) {
+ case SCI_EVENT_MOUSE_PRESS:
+ // TODO: Implement mouse support for cursor change
+ break;
+ case SCI_EVENT_KEYBOARD:
+ switch (curEvent.data) {
+ case SCI_KEY_BACKSPACE:
+ if (cursorPos > 0) {
+ cursorPos--; text.deleteChar(cursorPos);
+ textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_DELETE:
+ if (cursorPos < textSize) {
+ text.deleteChar(cursorPos);
+ textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_HOME: // HOME
+ cursorPos = 0; textChanged = true;
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_END: // END
+ cursorPos = textSize; textChanged = true;
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_LEFT: // LEFT
+ if (cursorPos > 0) {
+ cursorPos--; textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_RIGHT: // RIGHT
+ if (cursorPos + 1 <= textSize) {
+ cursorPos++; textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case 3: // returned in SCI1 late and newer when Control - C is pressed
+ if (curEvent.modifiers & SCI_KEYMOD_CTRL) {
+ // Control-C erases the whole line
+ cursorPos = 0; text.clear();
+ textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ case SCI_KEY_UP:
+ case SCI_KEY_DOWN:
+ case SCI_KEY_ENTER:
+ case SCI_KEY_ESC:
+ case SCI_KEY_TAB:
+ case SCI_KEY_SHIFT_TAB:
+ captureEvents = false;
+ break;
+ default:
+ if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.data == 99) {
+ // Control-C in earlier SCI games (SCI0 - SCI1 middle)
+ // Control-C erases the whole line
+ cursorPos = 0; text.clear();
+ textChanged = true;
+ } else if (curEvent.data > 31 && curEvent.data < 256 && textSize < maxChars) {
+ // insert pressed character
+ textAddChar = true;
+ textChanged = true;
+ }
+ eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
+ break;
+ }
+ break;
+ }
+ }
+
+ if (textChanged) {
+ rect = g_sci->_gfxCompare->getNSRect(controlObject);
+
+ if (textAddChar) {
+ const char *textPtr = text.c_str();
+
+ // We check if we are really able to add the new char
+ uint16 textWidth = 0;
+ while (*textPtr)
+ textWidth += font->getCharWidth((byte)*textPtr++);
+ textWidth += font->getCharWidth(curEvent.data);
+
+ // Does it fit?
+ if (textWidth >= rect.width()) {
+ return;
+ }
+
+ text.insertChar(curEvent.data, cursorPos++);
+
+ // Note: the following checkAltInput call might make the text
+ // too wide to fit, but SSCI fails to check that too.
+ }
+
+ reg_t hunkId = readSelector(_segMan, controlObject, SELECTOR(bitmap));
+ Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(controlObject);
+ //texteditCursorErase(); // TODO: Cursor
+
+ // Write back string
+ _segMan->strcpy(textReference, text.c_str());
+ // Modify the buffer and show it
+ _text->createTextBitmap(controlObject, 0, 0, hunkId);
+
+ _text->drawTextBitmap(0, 0, nsRect, controlObject);
+ //texteditCursorDraw(rect, text.c_str(), cursorPos); // TODO: Cursor
+ g_system->updateScreen();
+ } else {
+ // TODO: Cursor
+ /*
+ if (g_system->getMillis() >= _texteditBlinkTime) {
+ _paint16->invertRect(_texteditCursorRect);
+ _paint16->bitsShow(_texteditCursorRect);
+ _texteditCursorVisible = !_texteditCursorVisible;
+ texteditSetBlinkTime();
+ }
+ */
+ }
+
+ textAddChar = false;
+ textChanged = false;
+ g_sci->sleep(10);
+ } // while
+}
+
+} // End of namespace Sci
diff --git a/engines/sci/graphics/controls32.h b/engines/sci/graphics/controls32.h
new file mode 100644
index 0000000000..68dca59462
--- /dev/null
+++ b/engines/sci/graphics/controls32.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCI_GRAPHICS_CONTROLS32_H
+#define SCI_GRAPHICS_CONTROLS32_H
+
+namespace Sci {
+
+class GfxCache;
+class GfxScreen;
+class GfxText32;
+
+/**
+ * Controls class, handles drawing of controls in SCI32 (SCI2, SCI2.1, SCI3) games
+ */
+class GfxControls32 {
+public:
+ GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text);
+ ~GfxControls32();
+
+ void kernelTexteditChange(reg_t controlObject);
+
+private:
+ SegManager *_segMan;
+ GfxCache *_cache;
+ GfxScreen *_screen;
+ GfxText32 *_text;
+};
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index a41efd6a9f..aa53576b13 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -488,12 +488,10 @@ void GfxFrameout::kernelFrameout() {
itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, it->planePictureMirrored);
// warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);
- } else if (itemEntry->viewId != 0xFFFF) {
- GfxView *view = _cache->getView(itemEntry->viewId);
-
-// warning("view %s %04x:%04x", _segMan->getObjectName(itemEntry->object), PRINT_REG(itemEntry->object));
-
- if (view->isSci2Hires()) {
+ } else {
+ GfxView *view = (itemEntry->viewId != 0xFFFF) ? _cache->getView(itemEntry->viewId) : NULL;
+
+ if (view && view->isSci2Hires()) {
int16 dummyX = 0;
view->adjustToUpscaledCoordinates(itemEntry->y, itemEntry->x);
view->adjustToUpscaledCoordinates(itemEntry->z, dummyX);
@@ -513,24 +511,27 @@ void GfxFrameout::kernelFrameout() {
itemEntry->celRect.left = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inLeft));
itemEntry->celRect.bottom = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inBottom)) + 1;
itemEntry->celRect.right = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inRight)) + 1;
- if (view->isSci2Hires()) {
+ if (view && view->isSci2Hires()) {
view->adjustToUpscaledCoordinates(itemEntry->celRect.top, itemEntry->celRect.left);
view->adjustToUpscaledCoordinates(itemEntry->celRect.bottom, itemEntry->celRect.right);
}
itemEntry->celRect.translate(itemEntry->x, itemEntry->y);
// TODO: maybe we should clip the cels rect with this, i'm not sure
// the only currently known usage is game menu of gk1
- } else {
- if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
- view->getCelRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect);
- else
- view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, itemEntry->scaleY, itemEntry->celRect);
+ } else if (view) {
+ if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
+ view->getCelRect(itemEntry->loopNo, itemEntry->celNo,
+ itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect);
+ else
+ view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo,
+ itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX,
+ itemEntry->scaleY, itemEntry->celRect);
Common::Rect nsRect = itemEntry->celRect;
// Translate back to actual coordinate within scrollable plane
nsRect.translate(it->planeOffsetX, it->planeOffsetY);
- if (view->isSci2Hires()) {
+ if (view && view->isSci2Hires()) {
view->adjustBackUpscaledCoordinates(nsRect.top, nsRect.left);
view->adjustBackUpscaledCoordinates(nsRect.bottom, nsRect.right);
} else if (getSciVersion() == SCI_VERSION_2_1) {
@@ -552,7 +553,7 @@ void GfxFrameout::kernelFrameout() {
int16 screenHeight = _screen->getHeight();
int16 screenWidth = _screen->getWidth();
- if (view->isSci2Hires()) {
+ if (view && view->isSci2Hires()) {
screenHeight = _screen->getDisplayHeight();
screenWidth = _screen->getDisplayWidth();
}
@@ -565,7 +566,8 @@ void GfxFrameout::kernelFrameout() {
Common::Rect clipRect, translatedClipRect;
clipRect = itemEntry->celRect;
- if (view->isSci2Hires()) {
+
+ if (view && view->isSci2Hires()) {
clipRect.clip(it->upscaledPlaneClipRect);
translatedClipRect = clipRect;
translatedClipRect.translate(it->upscaledPlaneRect.left, it->upscaledPlaneRect.top);
@@ -575,16 +577,20 @@ void GfxFrameout::kernelFrameout() {
translatedClipRect.translate(it->planeRect.left, it->planeRect.top);
}
- if (!clipRect.isEmpty()) {
- if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
- view->draw(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires());
- else
- view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY);
+ if (view) {
+ if (!clipRect.isEmpty()) {
+ if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
+ view->draw(itemEntry->celRect, clipRect, translatedClipRect,
+ itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires());
+ else
+ view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect,
+ itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY);
+ }
}
- } else {
- // Most likely a text entry
+
+ // Draw text, if it exists
if (lookupSelector(_segMan, itemEntry->object, SELECTOR(text), NULL, NULL) == kSelectorVariable) {
- g_sci->_gfxText32->drawTextBitmap(itemEntry->object);
+ g_sci->_gfxText32->drawTextBitmap(itemEntry->x, itemEntry->y, it->planeRect, itemEntry->object);
}
}
}
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index 029030165d..fd6637f313 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -41,6 +41,10 @@ namespace Sci {
#define BITMAP_HEADER_SIZE 46
+#define SCI_TEXT32_ALIGNMENT_RIGHT -1
+#define SCI_TEXT32_ALIGNMENT_CENTER 1
+#define SCI_TEXT32_ALIGNMENT_LEFT 0
+
GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen)
: _segMan(segMan), _cache(fonts), _screen(screen) {
}
@@ -48,7 +52,7 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen)
GfxText32::~GfxText32() {
}
-reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight) {
+reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text));
// The object in the text selector of the item can be either a raw string
@@ -58,13 +62,21 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
stringObject = readSelector(_segMan, stringObject, SELECTOR(data));
Common::String text = _segMan->getString(stringObject);
- GfxFont *font = _cache->getFont(readSelectorValue(_segMan, textObject, SELECTOR(font)));
+ // HACK: The character offsets of the up and down arrow buttons are off by one
+ // in GK1, for some unknown reason. Fix them here.
+ if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) {
+ text.setChar(text[0] + 1, 0);
+ }
+ GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font));
+ GfxFont *font = _cache->getFont(fontId);
bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed));
+ int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode));
uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore));
+ uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));
- Common::Rect planeRect = getPlaneRect(textObject);
- uint16 width = planeRect.width() + 1;
- uint16 height = planeRect.height() + 1;
+ Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject);
+ uint16 width = nsRect.width() + 1;
+ uint16 height = nsRect.height() + 1;
// Limit rectangle dimensions, if requested
if (maxWidth > 0)
@@ -79,24 +91,74 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
}
int entrySize = width * height + BITMAP_HEADER_SIZE;
- reg_t memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
- writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
+ reg_t memoryId = NULL_REG;
+ if (prevHunk.isNull()) {
+ memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
+ writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
+ } else {
+ memoryId = prevHunk;
+ }
byte *memoryPtr = _segMan->getHunkPointer(memoryId);
- memset(memoryPtr, 0, entrySize);
+
+ if (prevHunk.isNull())
+ memset(memoryPtr, 0, BITMAP_HEADER_SIZE);
+
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
+ memset(bitmap, backColor, width * height);
+
+ // Save totalWidth, totalHeight
+ WRITE_LE_UINT16(memoryPtr, width);
+ WRITE_LE_UINT16(memoryPtr + 2, height);
int16 charCount = 0;
uint16 curX = 0, curY = 0;
const char *txt = text.c_str();
+ int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0;
+ uint16 start = 0;
+ // Calculate total text height
while (*txt) {
charCount = GetLongest(txt, width, font);
if (charCount == 0)
break;
+ Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true);
+
+ totalHeight += textHeight;
+ txt += charCount;
+ while (*txt == ' ')
+ txt++; // skip over breaking spaces
+ }
+
+ txt = text.c_str();
+
+ // Draw text in buffer
+ while (*txt) {
+ charCount = GetLongest(txt, width, font);
+ if (charCount == 0)
+ break;
+ Width(txt, start, charCount, fontId, textWidth, textHeight, true);
+
+ switch (alignment) {
+ case SCI_TEXT32_ALIGNMENT_RIGHT:
+ offsetX = width - textWidth;
+ break;
+ case SCI_TEXT32_ALIGNMENT_CENTER:
+ // Center text both horizontally and vertically
+ offsetX = (width - textWidth) / 2;
+ offsetY = (height - totalHeight) / 2;
+ break;
+ case SCI_TEXT32_ALIGNMENT_LEFT:
+ offsetX = 0;
+ break;
+
+ default:
+ warning("Invalid alignment %d used in TextBox()", alignment);
+ }
+
for (int i = 0; i < charCount; i++) {
unsigned char curChar = txt[i];
- font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, bitmap, width, height);
+ font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height);
curX += font->getCharWidth(curChar);
}
@@ -114,7 +176,7 @@ void GfxText32::disposeTextBitmap(reg_t hunkId) {
_segMan->freeHunkEntry(hunkId);
}
-void GfxText32::drawTextBitmap(reg_t textObject) {
+void GfxText32::drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t textObject) {
reg_t hunkId = readSelector(_segMan, textObject, SELECTOR(bitmap));
// Sanity check: Check if the hunk is set. If not, either the game scripts
// didn't set it, or an old saved game has been loaded, where it wasn't set.
@@ -129,46 +191,28 @@ void GfxText32::drawTextBitmap(reg_t textObject) {
byte *surface = memoryPtr + BITMAP_HEADER_SIZE;
int curByte = 0;
- Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject);
- Common::Rect planeRect = getPlaneRect(textObject);
- uint16 x = readSelectorValue(_segMan, textObject, SELECTOR(x));
- uint16 y = readSelectorValue(_segMan, textObject, SELECTOR(y));
+ uint16 skipColor = readSelectorValue(_segMan, textObject, SELECTOR(skip));
uint16 textX = planeRect.left + x;
uint16 textY = planeRect.top + y;
- uint16 width = nsRect.width() + 1;
- uint16 height = nsRect.height() + 1;
+ // Get totalWidth, totalHeight
+ uint16 width = READ_LE_UINT16(memoryPtr);
+ uint16 height = READ_LE_UINT16(memoryPtr + 2);
// Upscale the coordinates/width if the fonts are already upscaled
if (_screen->fontIsUpscaled()) {
textX = textX * _screen->getDisplayWidth() / _screen->getWidth();
textY = textY * _screen->getDisplayHeight() / _screen->getHeight();
- width = width * _screen->getDisplayWidth() / _screen->getWidth();
- height = height * _screen->getDisplayHeight() / _screen->getHeight();
}
for (int curY = 0; curY < height; curY++) {
for (int curX = 0; curX < width; curX++) {
byte pixel = surface[curByte++];
- if (pixel)
+ if (pixel != skipColor)
_screen->putFontPixel(textY, curX + textX, curY, pixel);
}
}
}
-Common::Rect GfxText32::getPlaneRect(reg_t textObject) {
- Common::Rect planeRect(0, 0, _screen->getWidth(), _screen->getHeight());
-
- reg_t planeObject = readSelector(_segMan, textObject, SELECTOR(plane));
- if (!planeObject.isNull()) {
- planeRect.top = readSelectorValue(_segMan, planeObject, SELECTOR(top));
- planeRect.left = readSelectorValue(_segMan, planeObject, SELECTOR(left));
- planeRect.bottom = readSelectorValue(_segMan, planeObject, SELECTOR(bottom));
- planeRect.right = readSelectorValue(_segMan, planeObject, SELECTOR(right));
- }
-
- return planeRect;
-}
-
int16 GfxText32::GetLongest(const char *text, int16 maxWidth, GfxFont *font) {
uint16 curChar = 0;
int16 maxChars = 0, curCharCount = 0;
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index dfcbf63ccf..3a411ce663 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -35,9 +35,9 @@ class GfxText32 {
public:
GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen);
~GfxText32();
- reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0);
+ reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG);
void disposeTextBitmap(reg_t hunkId);
- void drawTextBitmap(reg_t textObject);
+ void drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t textObject);
int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font);
void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
@@ -46,7 +46,6 @@ private:
int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth);
void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont);
void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
- Common::Rect getPlaneRect(reg_t textObject);
SegManager *_segMan;
GfxCache *_cache;
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 828a36298d..25fbbab207 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -78,6 +78,7 @@ MODULE_OBJS := \
ifdef ENABLE_SCI32
MODULE_OBJS += \
+ graphics/controls32.o \
graphics/frameout.o \
graphics/paint32.o \
graphics/text32.o \
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index c50d1b8d8a..9171e5e5d9 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -169,8 +169,11 @@ ResourceType ResourceManager::convertResType(byte type) {
if (type < ARRAYSIZE(s_resTypeMapSci21)) {
// LSL6 hires doesn't have the chunk resource type, to match
// the resource types of the lowres version, thus we use the
- // older resource types here
- if (g_sci && g_sci->getGameId() == GID_LSL6HIRES)
+ // older resource types here.
+ // PQ4 CD and QFG4 CD are SCI2.1, but use the resource types of the
+ // corresponding SCI2 floppy disk versions.
+ if (g_sci && (g_sci->getGameId() == GID_LSL6HIRES ||
+ g_sci->getGameId() == GID_QFG4 || g_sci->getGameId() == GID_PQ4))
return s_resTypeMapSci0[type];
else
return s_resTypeMapSci21[type];
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 2dc8c95fec..6eeed66e4f 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -47,6 +47,7 @@
#include "sci/graphics/cache.h"
#include "sci/graphics/compare.h"
#include "sci/graphics/controls16.h"
+#include "sci/graphics/controls32.h"
#include "sci/graphics/coordadjuster.h"
#include "sci/graphics/cursor.h"
#include "sci/graphics/maciconbar.h"
@@ -113,6 +114,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
DebugMan.addDebugChannel(kDebugLevelGC, "GC", "Garbage Collector debugging");
DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging");
DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game");
+ DebugMan.addDebugChannel(kDebugLevelDebugMode, "DebugMode", "Enable game debug mode at start of game");
const Common::FSNode gameDataDir(ConfMan.get("path"));
@@ -147,6 +149,7 @@ SciEngine::~SciEngine() {
DebugMan.clearAllDebugChannels();
#ifdef ENABLE_SCI32
+ delete _gfxControls32;
delete _gfxText32;
delete _robotDecoder;
delete _gfxFrameout;
@@ -600,6 +603,7 @@ void SciEngine::initGraphics() {
_gfxText16 = 0;
_gfxTransitions = 0;
#ifdef ENABLE_SCI32
+ _gfxControls32 = 0;
_gfxText32 = 0;
_robotDecoder = 0;
_gfxFrameout = 0;
@@ -622,6 +626,7 @@ void SciEngine::initGraphics() {
_gfxPaint32 = new GfxPaint32(_resMan, _gamestate->_segMan, _kernel, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette);
_gfxPaint = _gfxPaint32;
_gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache, _gfxScreen);
+ _gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxText32);
_robotDecoder = new RobotDecoder(g_system->getMixer(), getPlatform() == Common::kPlatformMacintosh);
_gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32);
} else {
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index e76b71b61e..9bead768a6 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -60,6 +60,7 @@ class GfxAnimate;
class GfxCache;
class GfxCompare;
class GfxControls16;
+class GfxControls32;
class GfxCoordAdjuster;
class GfxCursor;
class GfxMacIconBar;
@@ -101,7 +102,8 @@ enum kDebugLevels {
kDebugLevelScripts = 1 << 17,
kDebugLevelGC = 1 << 18,
kDebugLevelResMan = 1 << 19,
- kDebugLevelOnStartup = 1 << 20
+ kDebugLevelOnStartup = 1 << 20,
+ kDebugLevelDebugMode = 1 << 21
};
enum SciGameId {
@@ -304,6 +306,7 @@ public:
GfxCache *_gfxCache;
GfxCompare *_gfxCompare;
GfxControls16 *_gfxControls16; // Controls for 16-bit gfx
+ GfxControls32 *_gfxControls32; // Controls for 32-bit gfx
GfxCoordAdjuster *_gfxCoordAdjuster;
GfxCursor *_gfxCursor;
GfxMenu *_gfxMenu; // Menu for 16-bit gfx
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 324154f709..d55a08293e 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -28,6 +28,7 @@
#include "sword1/sword1.h"
#include "sword1/animation.h"
#include "sword1/text.h"
+#include "sword1/resman.h"
#include "common/str.h"
#include "common/system.h"
@@ -65,8 +66,8 @@ static const char *const sequenceList[20] = {
// Basic movie player
///////////////////////////////////////////////////////////////////////////////
-MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType)
- : _vm(vm), _textMan(textMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) {
+MoviePlayer::MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType)
+ : _vm(vm), _textMan(textMan), _resMan(resMan), _snd(snd), _bgSoundHandle(bgSoundHandle), _system(system) {
_bgSoundStream = NULL;
_decoderType = decoderType;
_decoder = decoder;
@@ -183,8 +184,8 @@ void MoviePlayer::performPostProcessing(byte *screen) {
_textMan->makeTextSprite(2, (const uint8 *)_movieTexts.front()._text.c_str(), 600, LETTER_COL);
FrameHeader *frame = _textMan->giveSpriteData(2);
- _textWidth = frame->width;
- _textHeight = frame->height;
+ _textWidth = _resMan->toUint16(frame->width);
+ _textHeight = _resMan->toUint16(frame->height);
_textX = 320 - _textWidth / 2;
_textY = 420 - _textHeight;
}
@@ -323,7 +324,7 @@ uint32 DXADecoderWithSound::getElapsedTime() const {
// Factory function for creating the appropriate cutscene player
///////////////////////////////////////////////////////////////////////////////
-MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system) {
+MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system) {
Common::String filename;
Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle;
@@ -331,7 +332,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::M
if (Common::File::exists(filename)) {
Video::SmackerDecoder *smkDecoder = new Video::SmackerDecoder(snd);
- return new MoviePlayer(vm, textMan, snd, system, bgSoundHandle, smkDecoder, kVideoDecoderSMK);
+ return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, smkDecoder, kVideoDecoderSMK);
}
filename = Common::String::format("%s.dxa", sequenceList[id]);
@@ -339,7 +340,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::M
if (Common::File::exists(filename)) {
#ifdef USE_ZLIB
DXADecoderWithSound *dxaDecoder = new DXADecoderWithSound(snd, bgSoundHandle);
- return new MoviePlayer(vm, textMan, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA);
+ return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, dxaDecoder, kVideoDecoderDXA);
#else
GUI::MessageDialog dialog(_("DXA cutscenes found but ScummVM has been built without zlib support"), _("OK"));
dialog.runModal();
diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h
index fc3061bbf9..1c03c66342 100644
--- a/engines/sword1/animation.h
+++ b/engines/sword1/animation.h
@@ -67,7 +67,7 @@ private:
class MoviePlayer {
public:
- MoviePlayer(SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType);
+ MoviePlayer(SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system, Audio::SoundHandle *bgSoundHandle, Video::VideoDecoder *decoder, DecoderType decoderType);
virtual ~MoviePlayer();
bool load(uint32 id);
void play();
@@ -75,6 +75,7 @@ public:
protected:
SwordEngine *_vm;
Text *_textMan;
+ ResMan *_resMan;
Audio::Mixer *_snd;
OSystem *_system;
Common::List<MovieText> _movieTexts;
@@ -93,7 +94,7 @@ protected:
byte findWhitePalIndex();
};
-MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, Audio::Mixer *snd, OSystem *system);
+MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *resMan, Audio::Mixer *snd, OSystem *system);
} // End of namespace Sword1
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index d1c69c80ff..9d92a29a63 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -959,7 +959,7 @@ int Logic::fnPlaySequence(Object *cpt, int32 id, int32 sequenceId, int32 d, int3
// meantime, we don't want any looping sound effects still playing.
_sound->quitScreen();
- MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _mixer, _system);
+ MoviePlayer *player = makeMoviePlayer(sequenceId, _vm, _textMan, _resMan, _mixer, _system);
if (player) {
_screen->clearScreen();
if (player->load(sequenceId))
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
index 91fd5d3197..77609715c7 100644
--- a/engines/tsage/blue_force/blueforce_logic.cpp
+++ b/engines/tsage/blue_force/blueforce_logic.cpp
@@ -955,7 +955,7 @@ void SceneHandlerExt::process(Event &event) {
return;
}
- // If the user clicks the button whislt the introduction is active, prompt for playing the game
+ // If the user clicks the button whilst the introduction is active, prompt for playing the game
if ((BF_GLOBALS._dayNumber == 0) && (event.eventType == EVENT_BUTTON_DOWN)) {
// Prompt user for whether to start play or watch introduction
BF_GLOBALS._player.enableControl();
diff --git a/engines/tsage/blue_force/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp
index bb283d051e..69a2273237 100644
--- a/engines/tsage/blue_force/blueforce_scenes0.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes0.cpp
@@ -121,7 +121,7 @@ void Scene20::Action1::signal() {
void Scene20::postInit(SceneObjectList *OwnerList) {
loadScene(20);
- Scene::postInit();
+ SceneExt::postInit();
setZoomPercents(60, 85, 200, 100);
BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp
index 425446d6fb..c73f3f8499 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes1.cpp
@@ -243,8 +243,8 @@ void Scene109::Action1::signal() {
scene->_drunk.show();
scene->_drunk.setAction(&scene->_action3);
scene->_object2.show();
- scene->_object9.show();
- scene->_object9.setAction(&scene->_action2);
+ scene->_beerSign.show();
+ scene->_beerSign.setAction(&scene->_action2);
BF_GLOBALS._v501FC = 170;
setDelay(60);
@@ -257,27 +257,27 @@ void Scene109::Action1::signal() {
break;
case 5:
// Open briefcase and pass over disk
- setAction(&scene->_sequenceManager6, this, 105, &scene->_object10, NULL);
+ setAction(&scene->_sequenceManager6, this, 105, &scene->_animationInset, NULL);
break;
case 6:
// Protaginist 2 walk to the bar
- scene->_object10.remove();
+ scene->_animationInset.remove();
setAction(&scene->_sequenceManager6, this, 100, &scene->_protaginist2, NULL);
break;
case 7:
// Two thugs enter and walk to table
- scene->_object7.setAction(&scene->_sequenceManager7, NULL, 103, &scene->_object7, NULL);
- scene->_object5.setAction(&scene->_sequenceManager8, this, 102, &scene->_object5, NULL);
+ scene->_cop2.setAction(&scene->_sequenceManager7, NULL, 103, &scene->_cop2, NULL);
+ scene->_cop1.setAction(&scene->_sequenceManager8, this, 102, &scene->_cop1, NULL);
scene->_protaginist2.setAction(&scene->_sequenceManager6, NULL, 104, &scene->_protaginist2, &scene->_bartender, NULL);
break;
case 8:
// Protaginist 1 leaves, protaginist 2 stands up
- setAction(&scene->_sequenceManager8, this, 101, &scene->_object5, &scene->_protaginist1, NULL);
+ setAction(&scene->_sequenceManager8, this, 101, &scene->_cop1, &scene->_protaginist1, NULL);
break;
case 9:
// Shots fired!
scene->_protaginist1.setAction(&scene->_sequenceManager5, this, 98, &scene->_protaginist1, NULL);
- scene->_object7.setAction(&scene->_sequenceManager7, NULL, 99, &scene->_object7, NULL);
+ scene->_cop2.setAction(&scene->_sequenceManager7, NULL, 99, &scene->_cop2, NULL);
break;
case 10:
// End scene
@@ -289,12 +289,12 @@ void Scene109::Action1::signal() {
void Scene109::Action2::signal() {
Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene;
- scene->setAction(&scene->_sequenceManager2, this, 3117, &scene->_object9, NULL);
+ setAction(&scene->_sequenceManager2, this, 3117, &scene->_beerSign, NULL);
}
void Scene109::Action3::signal() {
Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene;
- scene->setAction(&scene->_sequenceManager3, this, 108, &scene->_drunk, NULL);
+ setAction(&scene->_sequenceManager3, this, 108, &scene->_drunk, NULL);
}
/*--------------------------------------------------------------------------*/
@@ -353,21 +353,21 @@ void Scene109::postInit(SceneObjectList *OwnerList) {
_object2.setPosition(Common::Point(104, 64));
_object2.hide();
- _object9.postInit();
- _object9.setVisage(115);
- _object9.setStrip(4);
- _object9.setFrame(1);
- _object9.setPosition(Common::Point(262, 29));
- _object9.hide();
+ _beerSign.postInit();
+ _beerSign.setVisage(115);
+ _beerSign.setStrip(4);
+ _beerSign.setFrame(1);
+ _beerSign.setPosition(Common::Point(262, 29));
+ _beerSign.hide();
- _object5.postInit();
- _object5.hide();
+ _cop1.postInit();
+ _cop1.hide();
- _object7.postInit();
- _object7.hide();
+ _cop2.postInit();
+ _cop2.hide();
- _object10.postInit();
- _object10.hide();
+ _animationInset.postInit();
+ _animationInset.hide();
BF_GLOBALS._player.disableControl();
setAction(&_action1, this);
diff --git a/engines/tsage/blue_force/blueforce_scenes1.h b/engines/tsage/blue_force/blueforce_scenes1.h
index bdf414ec9b..403fbfbab6 100644
--- a/engines/tsage/blue_force/blueforce_scenes1.h
+++ b/engines/tsage/blue_force/blueforce_scenes1.h
@@ -99,11 +99,12 @@ public:
SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3;
SequenceManager _sequenceManager4, _sequenceManager5, _sequenceManager6;
SequenceManager _sequenceManager7, _sequenceManager8;
- SceneObject _object1, _object2, _protaginist2, _protaginist1, _object5;
- SceneObject _drunk, _object7, _bartender, _object9, _object10;
+ SceneObject _object1, _object2, _protaginist2, _protaginist1, _cop1;
+ SceneObject _drunk, _cop2, _bartender, _beerSign, _animationInset;
IntroSceneText _text;
Action1 _action1;
- Action _action2, _action3;
+ Action2 _action2;
+ Action3 _action3;
public:
Scene109();
diff --git a/engines/tsage/blue_force/blueforce_scenes3.cpp b/engines/tsage/blue_force/blueforce_scenes3.cpp
index d1ed2cd5e6..3d42304926 100644
--- a/engines/tsage/blue_force/blueforce_scenes3.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes3.cpp
@@ -58,7 +58,7 @@ bool Scene300::Object19::startAction(CursorType action, Event &event) {
return true;
}
-
+// entrance door
bool Scene300::Item1::startAction(CursorType action, Event &event) {
if (action == CURSOR_USE) {
Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
@@ -75,6 +75,8 @@ bool Scene300::Item1::startAction(CursorType action, Event &event) {
bool Scene300::Item2::startAction(CursorType action, Event &event) {
if ((action == CURSOR_LOOK) || (action == CURSOR_USE)) {
Scene300 *scene = (Scene300 *)BF_GLOBALS._sceneManager._scene;
+ BF_GLOBALS._player.disableControl();
+ scene->_sceneMode = 0;
scene->setAction(&scene->_sequenceManager1, scene, 304, &scene->_object11, NULL);
return true;
} else {
@@ -108,7 +110,7 @@ void Scene300::Action1::signal() {
setDelay(1);
break;
case 2: {
- ADD_PLAYER_MOVER_THIS(BF_GLOBALS._player, BF_GLOBALS._player._position.x - 8,
+ ADD_MOVER(BF_GLOBALS._player, BF_GLOBALS._player._position.x - 8,
BF_GLOBALS._player._position.y);
break;
}
@@ -183,12 +185,13 @@ void Scene300::Action4::signal() {
break;
case 2:
BF_GLOBALS._sceneManager.changeScene(60);
+ setDelay(15);
break;
case 3:
setAction(&scene->_sequenceManager1, this, 319, &scene->_object19, NULL);
break;
case 4:
- BF_GLOBALS.setFlag(2);
+ BF_GLOBALS.setFlag(onBike);
BF_GLOBALS._sceneManager.changeScene(190);
break;
default:
@@ -213,6 +216,7 @@ void Scene300::Action5::signal() {
break;
case 3: {
ADD_PLAYER_MOVER_NULL(BF_GLOBALS._player, 186, 140);
+ setDelay(3);
break;
}
case 4:
@@ -474,10 +478,10 @@ void Scene300::signal() {
_object10.postInit();
_object10.hide();
- if (BF_GLOBALS.getFlag(1)) {
+ if (BF_GLOBALS.getFlag(gunClean)) {
BF_GLOBALS._player.disableControl();
_sceneMode = 4308;
- setAction(&_sequenceManager1, this, 6307, &_object2, &_object1, &_object9, &_object10, NULL);
+ setAction(&_sequenceManager1, this, 6307, &_object12, &_object1, &_object9, &_object10, NULL);
} else {
BF_GLOBALS._player.disableControl();
_sceneMode = 4308;
@@ -638,7 +642,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
- if (scene->_field1B60 || scene->_field1B64)
+ if (scene->_invGreenCount || scene->_invGangCount)
SceneItem::display2(320, 51);
else
NamedHotspot::startAction(action, event);
@@ -667,7 +671,7 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) {
scene->_stripNumber = 3174;
scene->setAction(&scene->_action1);
} else {
- ++scene->_field1B62;
+ ++scene->_bookGreenCount;
scene->_stripNumber = (action == INV_GREENS_GUN) ? 3168 : 0;
scene->_sceneMode = 3153;
scene->setAction(&scene->_sequenceManager, scene, 3153, &BF_GLOBALS._player, NULL);
@@ -717,8 +721,8 @@ bool Scene315::Barry::startAction(CursorType action, Event &event) {
scene->_stripNumber = 3174;
scene->setAction(&scene->_action1);
} else {
- ++scene->_field1B66;
- if (!scene->_field1B6C && (scene->_field1B66 == 1)) {
+ ++scene->_bookGangCount;
+ if (!scene->_field1B6C && (scene->_bookGangCount == 1)) {
scene->_field1B6C = 1;
scene->_stripNumber = 3169;
} else {
@@ -759,9 +763,9 @@ bool Scene315::SutterSlot::startAction(CursorType action, Event &event) {
case INV_BOOKING_FRANKIE:
case INV_BOOKING_GANG:
if (action == INV_BOOKING_GREEN)
- ++scene->_field1B62;
+ ++scene->_bookGreenCount;
else
- ++scene->_field1B66;
+ ++scene->_bookGangCount;
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 12;
@@ -874,6 +878,7 @@ bool Scene315::BulletinMemo::startAction(CursorType action, Event &event) {
}
}
+// Own Mail Slot
bool Scene315::Object2::startAction(CursorType action, Event &event) {
Scene315 *scene = (Scene315 *)BF_GLOBALS._sceneManager._scene;
@@ -957,9 +962,9 @@ Scene315::Scene315() {
BF_GLOBALS.clearFlag(fCanDrawGun);
_field1B68 = true;
- _field1B6A = false;
- _field1B60 = _field1B62 = 0;
- _field1B64 = _field1B66 = 0;
+ _doorOpened = false;
+ _invGreenCount = _bookGreenCount = 0;
+ _invGangCount = _bookGangCount = 0;
}
void Scene315::synchronize(Serializer &s) {
@@ -968,18 +973,19 @@ void Scene315::synchronize(Serializer &s) {
s.syncAsSint16LE(_field1390);
s.syncAsSint16LE(_stripNumber);
s.syncAsSint16LE(_field1398);
- s.syncAsSint16LE(_field1B60);
- s.syncAsSint16LE(_field1B62);
- s.syncAsSint16LE(_field1B64);
- s.syncAsSint16LE(_field1B66);
+ s.syncAsSint16LE(_invGreenCount);
+ s.syncAsSint16LE(_bookGreenCount);
+ s.syncAsSint16LE(_invGangCount);
+ s.syncAsSint16LE(_bookGangCount);
s.syncAsSint16LE(_field1B6C);
s.syncAsSint16LE(_field139C);
s.syncAsByte(_field1B68);
- s.syncAsByte(_field1B6A);
+ s.syncAsByte(_doorOpened);
s.syncAsSint16LE(_currentCursor);
}
void Scene315::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit(OwnerList);
loadScene(315);
if (BF_GLOBALS._sceneManager._previousScene != 325)
@@ -1061,29 +1067,29 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
// Set up evidence objects in inventory
if (BF_INVENTORY._bookingGreen.inInventory())
- ++_field1B60;
+ ++_invGreenCount;
if (BF_INVENTORY._greensGun.inInventory())
- ++_field1B60;
+ ++_invGreenCount;
if (BF_INVENTORY._greensKnife.inInventory())
- ++_field1B60;
+ ++_invGreenCount;
if (BF_INVENTORY._bullet22.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._autoRifle.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._wig.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._bookingFrankie.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._bookingGang.inInventory())
- ++_field1B64;
+ ++_invGangCount;
if (BF_INVENTORY._snub22.inInventory())
- ++_field1B64;
+ ++_invGangCount;
switch (BF_GLOBALS._sceneManager._previousScene) {
case 190:
if (_field1398)
- _field1B6A = true;
+ _doorOpened = true;
_sceneMode = BF_GLOBALS.getFlag(onDuty) ? 3150 : 3165;
setAction(&_sequenceManager, this, _sceneMode, &BF_GLOBALS._player, NULL);
break;
@@ -1099,7 +1105,7 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
case 300:
default:
if (_field1398)
- _field1B6A = true;
+ _doorOpened = true;
if (!BF_GLOBALS.getFlag(onDuty))
_sceneMode = 3166;
else if (!_field1398)
@@ -1111,7 +1117,7 @@ void Scene315::postInit(SceneObjectList *OwnerList) {
break;
}
- if (_field1B6A) {
+ if (_doorOpened) {
_object8.setFrame(8);
} else {
BF_GLOBALS._walkRegions.disableRegion(4);
@@ -1135,15 +1141,15 @@ void Scene315::signal() {
BF_GLOBALS._player.enableControl();
break;
case 10:
- if (_field1B62) {
- if (_field1B62 >= _field1B60)
+ if (_bookGreenCount) {
+ if (_bookGreenCount >= _invGreenCount)
BF_GLOBALS.setFlag(fLeftTraceIn910);
else
++ctr;
}
- if (_field1B66) {
- if (_field1B66 < _field1B64)
+ if (_bookGangCount) {
+ if (_bookGangCount < _invGangCount)
++ctr;
else if (BF_GLOBALS._bookmark < bBookedFrankieEvidence)
BF_GLOBALS._bookmark = bBookedFrankieEvidence;
@@ -1158,15 +1164,15 @@ void Scene315::signal() {
BF_GLOBALS._sound1.fadeOut2(NULL);
break;
case 11:
- if (_field1B62) {
- if (_field1B62 >= _field1B60)
+ if (_bookGreenCount) {
+ if (_bookGreenCount >= _invGreenCount)
BF_GLOBALS.setFlag(fLeftTraceIn910);
else
++ctr;
}
- if (_field1B66) {
- if (_field1B66 < _field1B64)
+ if (_bookGangCount) {
+ if (_bookGangCount < _invGangCount)
++ctr;
else if (BF_GLOBALS._bookmark < bBookedFrankie)
BF_GLOBALS._bookmark = bBookedFrankie;
@@ -1195,7 +1201,7 @@ void Scene315::signal() {
T2_GLOBALS._uiElements.addScore(30);
BF_INVENTORY.setObjectScene((int)_currentCursor, 315);
- if (!_field1B64 || (_field1B66 != _field1B64))
+ if (!_invGangCount || (_bookGangCount != _invGangCount))
BF_GLOBALS._player.enableControl();
else {
_field139C = 1;
@@ -1217,7 +1223,8 @@ void Scene315::signal() {
BF_GLOBALS._walkRegions.disableRegion(4);
_object7.remove();
_object6.remove();
-
+ // No break on purpose
+ case 3155:
BF_GLOBALS._player.enableControl();
_field1B68 = false;
BF_GLOBALS._walkRegions.disableRegion(4);
@@ -1230,7 +1237,7 @@ void Scene315::signal() {
if (_stripNumber != 0)
setAction(&_action1);
- else if (!_field1B64 || (_field1B66 != _field1B64))
+ else if (!_invGangCount || (_bookGangCount != _invGangCount))
BF_GLOBALS._player.enableControl();
else {
_stripNumber = 3171;
@@ -1238,13 +1245,6 @@ void Scene315::signal() {
_field139C = 1;
}
break;
- case 3155:
- BF_GLOBALS._player.enableControl();
- _field1B68 = false;
- BF_GLOBALS._walkRegions.disableRegion(4);
- T2_GLOBALS._uiElements._active = true;
- T2_GLOBALS._uiElements.show();
- break;
case 3156:
T2_GLOBALS._uiElements.addScore(10);
BF_INVENTORY.setObjectScene(INV_DA_NOTE, 1);
@@ -1318,7 +1318,7 @@ void Scene315::dispatch() {
if (_field1B68)
return;
- if (_field1B6A) {
+ if (_doorOpened) {
if (BF_GLOBALS._player._position.y < 69) {
BF_GLOBALS._player.disableControl();
_field1B68 = true;
diff --git a/engines/tsage/blue_force/blueforce_scenes3.h b/engines/tsage/blue_force/blueforce_scenes3.h
index 73fcef2851..2cff4d5df8 100644
--- a/engines/tsage/blue_force/blueforce_scenes3.h
+++ b/engines/tsage/blue_force/blueforce_scenes3.h
@@ -213,9 +213,9 @@ public:
int _field1390;
int _stripNumber;
int _field1398;
- int _field1B60, _field1B62, _field1B64;
- int _field1B66, _field1B6C, _field139C;
- bool _field1B68, _field1B6A;
+ int _invGreenCount, _bookGreenCount, _invGangCount;
+ int _bookGangCount, _field1B6C, _field139C;
+ bool _field1B68, _doorOpened;
CursorType _currentCursor;
Scene315();
diff --git a/engines/tsage/blue_force/blueforce_scenes4.cpp b/engines/tsage/blue_force/blueforce_scenes4.cpp
index 4cff38feab..deff4f2518 100644
--- a/engines/tsage/blue_force/blueforce_scenes4.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes4.cpp
@@ -371,21 +371,27 @@ bool Scene410::Passenger::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_USE:
if (!BF_GLOBALS.getFlag(fCalledBackup)) {
- if (BF_GLOBALS.getFlag(fTalkedShooterNoBkup)) {
+ if (BF_GLOBALS.getFlag(fTalkedShooterNoBkup))
scene->setAction(&scene->_action3);
- } else {
- SceneItem::display2(410, 5);
- }
+ else
+ SceneItem::display(410, 5, SET_WIDTH, 300,
+ SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
+ SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
+ SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99,
+ SET_EXT_FGCOLOR, 13, LIST_END);
} else if (!scene->_field1FBA) {
- SceneItem::display2(410, 5);
+ SceneItem::display(410, 5, SET_WIDTH, 300,
+ SET_X, 10 + GLOBALS._sceneManager._scene->_sceneBounds.left,
+ SET_Y, GLOBALS._sceneManager._scene->_sceneBounds.top + UI_INTERFACE_Y + 2,
+ SET_FONT, 4, SET_BG_COLOR, 1, SET_FG_COLOR, 96, SET_EXT_BGCOLOR, 99,
+ SET_EXT_FGCOLOR, 13, LIST_END);
} else if (!scene->_field1FBE) {
scene->_sceneMode = 4121;
scene->_field1FBE = 1;
T2_GLOBALS._uiElements.addScore(50);
scene->signal();
- } else {
+ } else
break;
- }
return true;
case CURSOR_TALK:
scene->setAction(&scene->_action5);
@@ -711,6 +717,7 @@ void Scene410::signal() {
break;
case 7:
BF_INVENTORY.setObjectScene(INV_TYRONE_ID, 1);
+ _sceneMode = 0;
signal();
break;
case 8:
@@ -778,6 +785,7 @@ void Scene410::signal() {
BF_GLOBALS._player.setObjectWrapper(new SceneObjectWrapper());
BF_GLOBALS._player.updateAngle(Common::Point(100, 170));
BF_GLOBALS._walkRegions.enableRegion(22);
+ BF_GLOBALS._walkRegions.enableRegion(7);
BF_GLOBALS._walkRegions.enableRegion(16);
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
@@ -920,6 +928,17 @@ bool Scene415::GunInset::startAction(CursorType action, Event &event) {
}
}
+void Scene415::GunInset::remove() {
+ Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
+
+ BF_GLOBALS._player.disableControl();
+ scene->_gunAndWig.remove();
+ FocusObject::remove();
+
+ scene->_sceneMode = 0;
+ scene->_animatedSeat.animate(ANIM_MODE_6, scene);
+}
+
bool Scene415::GunAndWig::startAction(CursorType action, Event &event) {
Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
@@ -954,7 +973,7 @@ bool Scene415::BulletsInset::startAction(CursorType action, Event &event) {
Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
if (action == CURSOR_USE) {
- if (BF_GLOBALS.getFlag(fGotAutoWeapon)) {
+ if (BF_GLOBALS.getFlag(fGotBulletsFromDash)) {
FocusObject::startAction(action, event);
} else {
remove();
@@ -966,6 +985,13 @@ bool Scene415::BulletsInset::startAction(CursorType action, Event &event) {
}
}
+void Scene415::BulletsInset::remove() {
+ Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
+
+ scene->_theBullets.remove();
+ FocusObject::remove();
+}
+
bool Scene415::DashDrawer::startAction(CursorType action, Event &event) {
Scene415 *scene = (Scene415 *)BF_GLOBALS._sceneManager._scene;
@@ -993,7 +1019,6 @@ bool Scene415::TheBullets::startAction(CursorType action, Event &event) {
case INV_FOREST_RAP:
if (scene->_scoreBulletRapFlag) {
SceneItem::display2(415, 35);
- return true;
} else {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 0;
@@ -1001,7 +1026,7 @@ bool Scene415::TheBullets::startAction(CursorType action, Event &event) {
T2_GLOBALS._uiElements.addScore(50);
scene->_scoreBulletRapFlag = true;
}
- break;
+ return true;
default:
break;
}
@@ -1021,7 +1046,7 @@ bool Scene415::Lever::startAction(CursorType action, Event &event) {
} else {
BF_GLOBALS._player.disableControl();
scene->_sceneMode = 2;
- scene->setAction(&scene->_sequenceManager, scene, 4150, &scene->_object6, NULL);
+ scene->setAction(&scene->_sequenceManager, scene, 4150, &scene->_animatedSeat, NULL);
}
return true;
default:
@@ -1053,11 +1078,11 @@ void Scene415::postInit(SceneObjectList *OwnerList) {
_dashDrawer.setPosition(Common::Point(151, 97));
_dashDrawer.setDetails(415, 22, -1, -1, 1, NULL);
- _object6.postInit();
- _object6.setVisage(419);
- _object6.setStrip(1);
- _object6.setPosition(Common::Point(306, 116));
- _object6.fixPriority(80);
+ _animatedSeat.postInit();
+ _animatedSeat.setVisage(419);
+ _animatedSeat.setStrip(1);
+ _animatedSeat.setPosition(Common::Point(306, 116));
+ _animatedSeat.fixPriority(80);
_windowLever.setDetails(16, 415, 25, -1, 26, 1);
_item7.setDetails(17, 415, 32, -1, 33, 1);
diff --git a/engines/tsage/blue_force/blueforce_scenes4.h b/engines/tsage/blue_force/blueforce_scenes4.h
index 48b48ec7f8..937c015a4c 100644
--- a/engines/tsage/blue_force/blueforce_scenes4.h
+++ b/engines/tsage/blue_force/blueforce_scenes4.h
@@ -133,6 +133,7 @@ class Scene415: public SceneExt {
class GunInset: public FocusObject {
public:
virtual bool startAction(CursorType action, Event &event);
+ virtual void remove();
};
class GunAndWig: public NamedObject {
public:
@@ -141,6 +142,7 @@ class Scene415: public SceneExt {
class BulletsInset: public FocusObject {
public:
virtual bool startAction(CursorType action, Event &event);
+ virtual void remove();
};
class DashDrawer: public NamedObject {
public:
@@ -166,7 +168,7 @@ public:
BulletsInset _bulletsInset;
DashDrawer _dashDrawer;
TheBullets _theBullets;
- NamedObject _object6;
+ NamedObject _animatedSeat;
NamedHotspot _item1, _steeringWheel, _horn, _dashboard;
NamedHotspot _seat, _windowLever, _item7, _seatBelt;
Lever _lever;
diff --git a/engines/tsage/blue_force/blueforce_scenes5.cpp b/engines/tsage/blue_force/blueforce_scenes5.cpp
index d1f1e90234..f5f05c8148 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes5.cpp
@@ -924,7 +924,7 @@ void Scene560::Action1::signal() {
scene->_deskChair.setStrip(BF_GLOBALS._player._strip);
scene->_deskChair.setPosition(BF_GLOBALS._player._position);
- scene->_field380 = 1;
+ scene->_field380 = true;
BF_GLOBALS._player.enableControl();
remove();
break;
@@ -950,7 +950,7 @@ void Scene560::Action2::signal() {
BF_GLOBALS._player.animate(ANIM_MODE_6, this);
break;
case 2:
- scene->_field380 = 0;
+ scene->_field380 = false;
scene->_deskChair.setPosition(Common::Point(81, 149));
scene->_deskChair.setVisage(561);
scene->_deskChair.setStrip(3);
@@ -1378,7 +1378,7 @@ bool Scene560::Computer::startAction(CursorType action, Event &event) {
/*--------------------------------------------------------------------------*/
Scene560::Scene560(): SceneExt() {
- _field380 = _field11EA = 0;
+ _field380 = _field11EA = false;
}
void Scene560::postInit(SceneObjectList *OwnerList) {
@@ -1433,12 +1433,12 @@ void Scene560::postInit(SceneObjectList *OwnerList) {
_deskChair.setStrip(BF_GLOBALS._player._strip);
_deskChair.setPosition(BF_GLOBALS._player._position);
- _field11EA = 0;
- _field380 = 1;
+ _field11EA = false;
+ _field380 = true;
} else {
// Entering study through doorway
- _field11EA = 0;
- _field380 = 0;
+ _field11EA = false;
+ _field380 = false;
BF_GLOBALS._player.postInit();
BF_GLOBALS._player.setVisage(563);
@@ -1529,7 +1529,7 @@ void Scene560::signal() {
}
break;
case 10:
- _field11EA = 0;
+ _field11EA = false;
BF_GLOBALS._player.enableControl();
break;
case 11:
@@ -1540,7 +1540,7 @@ void Scene560::signal() {
void Scene560::process(Event &event) {
if ((event.eventType == EVENT_BUTTON_DOWN) && (BF_GLOBALS._events.getCursor() == CURSOR_WALK) &&
- (_field380 == 1) && !_action) {
+ (_field380) && !_action) {
_destPosition = event.mousePos;
BF_GLOBALS._player.disableControl();
setAction(&_action2);
@@ -1553,7 +1553,7 @@ void Scene560::process(Event &event) {
void Scene560::dispatch() {
if (!_field11EA && (BF_GLOBALS._player._position.y < 105)) {
- _field11EA = 1;
+ _field11EA = true;
BF_GLOBALS._player.disableControl();
BF_GLOBALS._sceneManager.changeScene(270);
}
diff --git a/engines/tsage/blue_force/blueforce_scenes5.h b/engines/tsage/blue_force/blueforce_scenes5.h
index 34328ab9e8..76bf4cdbc3 100644
--- a/engines/tsage/blue_force/blueforce_scenes5.h
+++ b/engines/tsage/blue_force/blueforce_scenes5.h
@@ -228,7 +228,8 @@ public:
NamedHotspot _chair, _lamp, _item4, _trophy, _watercolours, _fileCabinets;
NamedHotspot _certificate, _bookcase, _desk, _carpet, _item12, _office;
ASound _sound1;
- int _field380, _field11EA;
+ bool _field380;
+ bool _field11EA;
Common::Point _destPosition;
Scene560();
diff --git a/engines/tsage/blue_force/blueforce_scenes7.cpp b/engines/tsage/blue_force/blueforce_scenes7.cpp
index 21a27640e9..7b84e3ccdd 100644
--- a/engines/tsage/blue_force/blueforce_scenes7.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes7.cpp
@@ -37,7 +37,7 @@ namespace BlueForce {
void Scene710::Timer1::signal() {
PaletteRotation *rotation = BF_GLOBALS._scenePalette.addRotation(136, 138, -1);
- rotation->setDelay(25);
+ rotation->setDelay(20);
rotation = BF_GLOBALS._scenePalette.addRotation(146, 148, -1);
rotation->setDelay(30);
rotation = BF_GLOBALS._scenePalette.addRotation(187, 191, -1);
@@ -113,19 +113,19 @@ bool Scene710::Object5::startAction(CursorType action, Event &event) {
switch (action) {
case CURSOR_LOOK:
- if (scene->_v1D64 <= 2)
+ if (scene->_stickThrowCount <= 2)
return NamedObject::startAction(action, event);
else {
SceneItem::display2(710, 3);
- scene->_v1D66 = 1;
+ scene->_watchCrate = true;
return true;
}
case CURSOR_USE:
- if ((scene->_kid._position.x < 0) && (scene->_v1D62 == 1)) {
- scene->_v1D64++;
- if (scene->_v1D66 == 0) {
+ if ((scene->_kid._position.x < 0) && (scene->_dogLying)) {
+ scene->_stickThrowCount++;
+ if (!scene->_watchCrate) {
BF_GLOBALS._player.disableControl();
- scene->_v1D62 = 0;
+ scene->_dogLying = false;
scene->_sceneMode = 7105;
scene->setAction(&scene->_sequenceManager1, scene, 7105, &BF_GLOBALS._player, &scene->_stick, &scene->_dog, NULL);
} else {
@@ -187,7 +187,8 @@ void Scene710::postInit(SceneObjectList *OwnerList) {
_item7.setDetails(Rect(0, 0, 640, 52), 710, 11, 17, -1, 1, NULL);
_item9.setDetails(Rect(0, 0, 640, 128), 710, 5, 15, -1, 1, NULL);
- _v1D62 = _v1D64 = _v1D66 = _v1D68 = 0;
+ _stickThrowCount = 0;
+ _dogLying = _watchCrate = _throwStick = false;
_action1._state = 7100;
_timer1.set(2, NULL);
_sceneMode = 7100;
@@ -205,6 +206,7 @@ void Scene710::signal() {
setAction(&_sequenceManager1, this, 7102, &_dog, NULL);
break;
case 7101:
+ // Pick up crate part
BF_GLOBALS._player.enableControl();
BF_INVENTORY.setObjectScene(INV_CRATE1, 1);
_stick.remove();
@@ -214,19 +216,19 @@ void Scene710::signal() {
_stick.setPosition(Common::Point(100, 122));
_stick.animate(ANIM_MODE_NONE, NULL);
_stick._strip = 2;
- if (_v1D64 <= 2)
+ if (_stickThrowCount <= 2)
_stick._frame = 2;
else {
- if (_v1D64 == 3) {
+ if (_stickThrowCount == 3) {
BF_GLOBALS._player.disableControl();
_sceneMode = 0;
_stripManager.start(7108, this);
}
_stick._frame = 1;
}
- _v1D62 = 1;
+ _dogLying = true;
BF_GLOBALS._walkRegions.disableRegion(2);
- if ((_v1D68 != 0) && (_sceneMode != 0))
+ if ((_throwStick) && (_sceneMode != 0))
BF_GLOBALS._player.enableControl();
break;
case 7103:
@@ -239,7 +241,7 @@ void Scene710::signal() {
}
break;
case 7105:
- _v1D68 = 1;
+ _throwStick = true;
// No break on purpose
case 7104:
_sceneMode = 7102;
@@ -256,8 +258,8 @@ void Scene710::signal() {
}
void Scene710::dispatch() {
- if ((_kid._position.x > 0) && (_v1D62 == 1) && (_sceneMode != 7106)) {
- _v1D62 = 0;
+ if ((_kid._position.x > 0) && (_dogLying) && (_sceneMode != 7106)) {
+ _dogLying = false;
_sceneMode = 7103;
setAction(&_sequenceManager1, this, 7103, &_kid, &_stick, &_dog, NULL);
}
@@ -266,10 +268,10 @@ void Scene710::dispatch() {
void Scene710::synchronize(Serializer &s) {
SceneExt::synchronize(s);
- s.syncAsSint16LE(_v1D62);
- s.syncAsSint16LE(_v1D64);
- s.syncAsSint16LE(_v1D66);
- s.syncAsSint16LE(_v1D68);
+ s.syncAsSint16LE(_dogLying);
+ s.syncAsSint16LE(_stickThrowCount);
+ s.syncAsSint16LE(_watchCrate);
+ s.syncAsSint16LE(_throwStick);
}
diff --git a/engines/tsage/blue_force/blueforce_scenes7.h b/engines/tsage/blue_force/blueforce_scenes7.h
index 91bd1e537f..161d94cc2c 100644
--- a/engines/tsage/blue_force/blueforce_scenes7.h
+++ b/engines/tsage/blue_force/blueforce_scenes7.h
@@ -89,7 +89,10 @@ public:
NamedHotspot _item7;
NamedHotspot _item8;
NamedHotspot _item9;
- int _v1D62, _v1D64, _v1D66, _v1D68;
+ int _stickThrowCount;
+ bool _dogLying;
+ bool _watchCrate;
+ bool _throwStick;
virtual void postInit(SceneObjectList *OwnerList = NULL);
virtual void signal();
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index 5a51a9c9ef..84ab98d4e0 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -1081,7 +1081,7 @@ void PaletteRotation::signal() {
uint32 frameNumber = g_globals->_events.getFrameNumber();
if (frameNumber >= _frameNumber) {
- _delayCtr = frameNumber - _frameNumber;
+ _delayCtr -= frameNumber - _frameNumber;
_frameNumber = frameNumber;
if (_delayCtr < 0)
@@ -1438,8 +1438,8 @@ void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) {
}
Rect tempRect = bounds;
- if (g_vm->getGameID() != GType_Ringworld)
- tempRect.setHeight(BF_GLOBALS._interfaceY);
+ if ((g_vm->getGameID() != GType_Ringworld) && (g_vm->getGameID() != GType_Geekwad))
+ tempRect.setHeight(T2_GLOBALS._interfaceY);
g_globals->_screenSurface.copyFrom(g_globals->_sceneManager._scene->_backSurface,
tempRect, Rect(0, 0, tempRect.width(), tempRect.height()), NULL);
@@ -2929,6 +2929,16 @@ Player::Player(): SceneObject() {
_enabled = false;
_uiEnabled = false;
_field8C = 0;
+
+ // Return to Ringworld specific fields
+ _characterIndex = 0;
+ _oldSceneNumber = 0;
+
+ for (int i = 0; i < MAX_CHARACTERS; ++i) {
+ _characterScene[i] = 0;
+ _characterStrip[i] = 0;
+ _characterFrame[i] = 0;
+ }
}
void Player::postInit(SceneObjectList *OwnerList) {
@@ -3017,6 +3027,19 @@ void Player::synchronize(Serializer &s) {
if (g_vm->getGameID() != GType_Ringworld)
s.syncAsByte(_enabled);
+
+ if (g_vm->getGameID() == GType_Ringworld2) {
+ s.syncAsSint16LE(_characterIndex);
+ s.syncAsSint16LE(_oldSceneNumber);
+
+ for (int i = 0; i < MAX_CHARACTERS; ++i) {
+ s.syncAsSint16LE(_characterScene[i]);
+ s.syncAsSint16LE(_characterPos[i].x);
+ s.syncAsSint16LE(_characterPos[i].y);
+ s.syncAsSint16LE(_characterStrip[i]);
+ s.syncAsSint16LE(_characterFrame[i]);
+ }
+ }
}
/*--------------------------------------------------------------------------*/
@@ -3458,6 +3481,7 @@ void WalkRegions::clear() {
_field18.clear();
_idxList.clear();
_idxList2.clear();
+ _disabledRegions.clear();
}
void WalkRegions::load(int sceneNum) {
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index 1a50d0beae..23e720929c 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -418,6 +418,7 @@ public:
virtual void destroy() {}
virtual bool startAction(CursorType action, Event &event);
virtual void doAction(int action);
+ virtual bool performAction(CursorType action, Event &event) { return startAction(action, event); }
bool contains(const Common::Point &pt);
void setBounds(const Rect &newBounds) { _bounds = newBounds; }
@@ -616,12 +617,22 @@ public:
virtual void updateScreen();
};
+#define MAX_CHARACTERS 4
+
class Player : public SceneObject {
public:
bool _canWalk;
bool _uiEnabled;
int _field8C;
bool _enabled;
+
+ // Return to Ringworld specific fields
+ int _characterIndex;
+ int _oldSceneNumber;
+ int _characterScene[MAX_CHARACTERS];
+ Common::Point _characterPos[MAX_CHARACTERS];
+ int _characterStrip[MAX_CHARACTERS];
+ int _characterFrame[MAX_CHARACTERS];
public:
Player();
@@ -810,6 +821,7 @@ public:
Common::List<int> _disabledRegions;
public:
WalkRegions() { _resNum = -1; }
+ virtual ~WalkRegions() {}
virtual void synchronize(Serializer &s);
void clear();
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index 12add10c58..ab179cbac8 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -62,6 +62,7 @@ static const PlainGameDescriptor tSageGameTitles[] = {
{ "ringworld", "Ringworld: Revenge of the Patriarch" },
{ "blueforce", "Blue Force" },
{ "ringworld2", "Return to Ringworld" },
+ { "geekwad", "The Geekwad: Games Of The Galaxy" },
{ 0, 0 }
};
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
index 360dbac0ae..e9796426cd 100644
--- a/engines/tsage/detection_tables.h
+++ b/engines/tsage/detection_tables.h
@@ -156,6 +156,21 @@ static const tSageGameDescription gameDescriptions[] = {
GF_CD | GF_ALT_REGIONS
},
+ // Geekwad
+ {
+ {
+ "geekwad",
+ "CD",
+ AD_ENTRY1s("geekwad.rlb", "0a441f7c4c7ce20fd3ac7707a5d64ee5", 5570365),
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_CD | ADGF_UNSTABLE,
+ GUIO2(GUIO_NOSPEECH, GUIO_NOSFX)
+ },
+ GType_Geekwad,
+ GF_CD | GF_ALT_REGIONS
+ },
+
{ AD_TABLE_END_MARKER, 0, 0 }
};
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index d42b996e41..8958482404 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -320,7 +320,6 @@ void EventsClass::setCursor(Graphics::Surface &cursor, int transColor, const Com
}
void EventsClass::setCursor(GfxSurface &cursor) {
- // TODO: Find proper parameters for this form in Blue Force
Graphics::Surface s = cursor.lockSurface();
const byte *cursorData = (const byte *)s.getBasePtr(0, 0);
diff --git a/engines/tsage/events.h b/engines/tsage/events.h
index 67d56ceb87..2ffa862ca6 100644
--- a/engines/tsage/events.h
+++ b/engines/tsage/events.h
@@ -83,8 +83,8 @@ enum CursorType {
INV_CARAVAN_KEY = 67, BF_LAST_INVENT = 68,
// Ringworld 2 objects
- R2_1 = 1, R2_2 = 2, R2_NEGATOR_GUN = 3, R2_STEPPING_DISKS = 4, R2_5 = 5, R2_6 = 6, R2_7 = 7,
- R2_8 = 8, R2_9 = 9, R2_10 = 10, R2_11 = 11, R2_12 = 12, R2_13 = 13, R2_14 = 14,
+ R2_OPTO_DISK = 1, R2_2 = 2, R2_NEGATOR_GUN = 3, R2_STEPPING_DISKS = 4, R2_5 = 5, R2_6 = 6,
+ R2_7 = 7, R2_8 = 8, R2_9 = 9, R2_10 = 10, R2_11 = 11, R2_12 = 12, R2_13 = 13, R2_14 = 14,
R2_15 = 15, R2_16 = 16, R2_17 = 17, R2_18 = 18, R2_19 = 19, R2_20 = 20, R2_21 = 21,
R2_22 = 22, R2_23 = 23, R2_24 = 24, R2_25 = 25, R2_26 = 26, R2_27 = 27, R2_28 = 28,
R2_29 = 29, R2_30 = 30, R2_31 = 31, R2_32 = 32, R2_33 = 33, R2_34 = 34, R2_35 = 35,
diff --git a/engines/tsage/geekwad/geekwad_logic.cpp b/engines/tsage/geekwad/geekwad_logic.cpp
new file mode 100644
index 0000000000..a2d4fcb0f4
--- /dev/null
+++ b/engines/tsage/geekwad/geekwad_logic.cpp
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/geekwad/geekwad_logic.h"
+#include "tsage/geekwad/geekwad_scenes0.h"
+
+namespace TsAGE {
+
+namespace Geekwad {
+
+void GeekwadGame::start() {
+ // Start the game
+ g_globals->_sceneManager.changeScene(150);
+}
+
+Scene *GeekwadGame::createScene(int sceneNumber) {
+ switch (sceneNumber) {
+ /* Scene group #0 */
+ // Tsunami title screen
+ case 150: return new Scene150();
+
+ // Geekwad credits screen
+ case 200: return new Scene200();
+
+ default:
+ error("Unknown scene number - %d", sceneNumber);
+ break;
+ }
+}
+
+void GeekwadGame::rightClick() {
+}
+
+/**
+ * Returns true if it is currently okay to restore a game
+ */
+bool GeekwadGame::canLoadGameStateCurrently() {
+ return true;
+}
+
+/**
+ * Returns true if it is currently okay to save the game
+ */
+bool GeekwadGame::canSaveGameStateCurrently() {
+ return true;
+}
+
+void GeekwadGame::processEvent(Event &event) {
+}
+
+/*--------------------------------------------------------------------------*/
+
+SceneExt::SceneExt(): Scene() {
+}
+
+} // End of namespace Geekwad
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/geekwad/geekwad_logic.h b/engines/tsage/geekwad/geekwad_logic.h
new file mode 100644
index 0000000000..fbccaeee00
--- /dev/null
+++ b/engines/tsage/geekwad/geekwad_logic.h
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TSAGE_GEEKWAD_LOGIC_H
+#define TSAGE_GEEKWAD_LOGIC_H
+
+#include "common/scummsys.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+
+namespace TsAGE {
+
+namespace Geekwad {
+
+using namespace TsAGE;
+
+class SceneFactory {
+public:
+ static Scene *createScene(int sceneNumber);
+};
+
+class SceneExt: public Scene {
+public:
+public:
+ SceneExt();
+
+ virtual Common::String getClassName() { return "SceneExt"; }
+};
+
+class GeekwadGame: public Game {
+public:
+ virtual void start();
+
+ virtual Scene *createScene(int sceneNumber);
+ virtual void processEvent(Event &event);
+ virtual void rightClick();
+ virtual bool canSaveGameStateCurrently();
+ virtual bool canLoadGameStateCurrently();
+};
+
+class SceneObject2: public SceneObject {
+public:
+ int _v1, _v2;
+
+ SceneObject2() { _v1 = _v2 = 0; }
+ virtual Common::String getClassName() { return "SceneObject2"; }
+ virtual void synchronize(Serializer &s) {
+ SceneObject::synchronize(s);
+ s.syncAsSint16LE(_v1);
+ s.syncAsSint16LE(_v2);
+ }
+};
+
+} // End of namespace Geekwad
+
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/geekwad/geekwad_scenes0.cpp b/engines/tsage/geekwad/geekwad_scenes0.cpp
new file mode 100644
index 0000000000..9241b1dace
--- /dev/null
+++ b/engines/tsage/geekwad/geekwad_scenes0.cpp
@@ -0,0 +1,498 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+#include "tsage/geekwad/geekwad_scenes0.h"
+
+namespace TsAGE {
+
+namespace Geekwad {
+
+/*--------------------------------------------------------------------------
+ * Scene 150 - Tsunami Title Screen
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene150::Action1::signal() {
+ Scene150 *scene = (Scene150 *)GW_GLOBALS._sceneManager._scene;
+ static byte black[3] = { 0, 0, 0 };
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(2);
+ break;
+ case 1:
+ GW_GLOBALS._sound1.play(1);
+ GW_GLOBALS._scenePalette.addRotation(64, 127, -1, 1, this);
+ break;
+ case 2:
+ scene->_object1.setVisage(822);
+ scene->_object1._strip = 1;
+ scene->_object1._frame = 1;
+ scene->_object1.changeZoom(100);
+
+ scene->_object2.setVisage(822);
+ scene->_object2._strip = 2;
+ scene->_object2._frame = 1;
+ scene->_object2.changeZoom(100);
+
+ scene->_object3.setVisage(822);
+ scene->_object3._strip = 3;
+ scene->_object3._frame = 1;
+ scene->_object3.changeZoom(100);
+
+ scene->_object4.setVisage(822);
+ scene->_object4._strip = 4;
+ scene->_object4._frame = 1;
+ scene->_object4.changeZoom(100);
+
+ scene->_object5.setVisage(822);
+ scene->_object5._strip = 5;
+ scene->_object5._frame = 1;
+ scene->_object5.changeZoom(100);
+
+ scene->_object6.setVisage(822);
+ scene->_object6._strip = 6;
+ scene->_object6._frame = 1;
+ scene->_object6.changeZoom(100);
+
+ scene->_object7.setVisage(822);
+ scene->_object7._strip = 7;
+ scene->_object7._frame = 1;
+ scene->_object7.changeZoom(100);
+
+ scene->_object8.setVisage(822);
+ scene->_object8._strip = 8;
+ scene->_object8._frame = 1;
+ scene->_object8.changeZoom(100);
+
+ setDelay(1);
+ break;
+ case 3:
+ GW_GLOBALS._scenePalette.addFader(scene->_scenePalette._palette, 256, 8, this);
+ break;
+ case 4:
+ setDelay(60);
+ break;
+ case 5:
+ scene->_object2.animate(ANIM_MODE_5, NULL);
+ scene->_object3.animate(ANIM_MODE_5, NULL);
+ scene->_object4.animate(ANIM_MODE_5, NULL);
+ scene->_object5.animate(ANIM_MODE_5, NULL);
+ scene->_object6.animate(ANIM_MODE_5, NULL);
+ scene->_object7.animate(ANIM_MODE_5, this);
+ break;
+ case 6:
+ setDelay(120);
+ break;
+ case 7:
+ GW_GLOBALS._scenePalette.addFader(black, 1, 5, this);
+ break;
+ case 8:
+ GW_GLOBALS._sceneManager.changeScene(200);
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene150::postInit(SceneObjectList *OwnerList) {
+ loadScene(820);
+ Scene::postInit();
+ setZoomPercents(60, 85, 200, 100);
+
+ _scenePalette.loadPalette(822);
+
+ _object1.postInit();
+ _object1.setVisage(821);
+ _object1._strip = 1;
+ _object1._frame = 1;
+ _object1.animate(ANIM_MODE_NONE, NULL);
+ _object1.setPosition(Common::Point(62, 85));
+
+ _object2.postInit();
+ _object2.setVisage(821);
+ _object2._strip = 2;
+ _object2._frame = 1;
+ _object2.animate(ANIM_MODE_NONE, NULL);
+ _object2.setPosition(Common::Point(27, 94));
+
+ _object3.postInit();
+ _object3.setVisage(821);
+ _object3._strip = 2;
+ _object3._frame = 2;
+ _object3.animate(ANIM_MODE_NONE, NULL);
+ _object3.setPosition(Common::Point(68, 94));
+
+ _object4.postInit();
+ _object4.setVisage(821);
+ _object4._strip = 2;
+ _object4._frame = 3;
+ _object4.animate(ANIM_MODE_NONE, NULL);
+ _object4.setPosition(Common::Point(110, 94));
+
+ _object5.postInit();
+ _object5.setVisage(821);
+ _object5._strip = 2;
+ _object5._frame = 4;
+ _object5.animate(ANIM_MODE_NONE, NULL);
+ _object5.setPosition(Common::Point(154, 94));
+
+ _object6.postInit();
+ _object6.setVisage(821);
+ _object6._strip = 2;
+ _object6._frame = 5;
+ _object6.animate(ANIM_MODE_NONE, NULL);
+ _object6.setPosition(Common::Point(199, 94));
+
+ _object7.postInit();
+ _object7.setVisage(821);
+ _object7._strip = 2;
+ _object7._frame = 6;
+ _object7.animate(ANIM_MODE_NONE, NULL);
+ _object7.setPosition(Common::Point(244, 94));
+
+ _object8.postInit();
+ _object8.setVisage(821);
+ _object8._strip = 2;
+ _object8._frame = 7;
+ _object8.animate(ANIM_MODE_NONE, NULL);
+ _object8.setPosition(Common::Point(286, 94));
+
+ setAction(&_action1);
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 200 - Geekwad credits screen
+ *
+ *--------------------------------------------------------------------------*/
+
+struct CreditEntry {
+ int visage;
+ int strip;
+ int frame;
+};
+
+const CreditEntry credits[] = {
+ {5500, 1, 1}, {5500, 1, 2}, {5500, 2, 1}, {5500, 2, 2}, {5500, 8, 2}, {5500, 3, 1},
+ {5500, 3, 2}, {5500, 4, 1}, {5500, 4, 2}, {5500, 5, 1}, {5500, 5, 2}, {5500, 8, 2},
+ {5500, 6, 1}, {5500, 6, 2}, {5500, 7, 1}, {5500, 7, 2}, {5500, 8, 1}
+};
+#define TOTAL_CREDITS 17
+
+void Scene200::Action1::signal() {
+ Scene200 *scene = (Scene200 *)GW_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex) {
+ case 0: {
+ ++scene->_fieldAB2;
+
+ if ((scene->_creditIndex < TOTAL_CREDITS) && (!scene->_creditIndex || (*scene->_list2.begin())->_position.y < 192)) {
+ SceneObject2 *obj = new SceneObject2();
+ obj->postInit();
+ obj->setVisage(credits[scene->_creditIndex].visage);
+ obj->setStrip(credits[scene->_creditIndex].strip);
+ obj->setFrame(credits[scene->_creditIndex].frame);
+ obj->changeZoom(106);
+ obj->fixPriority(100);
+ obj->setPosition(Common::Point(160, 210));
+ obj->_flags |= OBJFLAG_CLONED;
+ obj->_v1 = obj->_v2 = 0;
+
+ scene->_list2.push_back(obj);
+ ++scene->_creditIndex;
+ }
+
+ SceneObject2 *item;
+ SynchronizedList<SceneObject2 *>::iterator i;
+ for (i = scene->_list2.begin(); i != scene->_list2.end(); ++i) {
+ item = *i;
+ item->setPosition(Common::Point(item->_position.x, item->_position.y - 1));
+ item->changeZoom(item->_percent - ((210 - item->_position.y + 100) / 100));
+ }
+
+ item = *scene->_list2.begin();
+ if (item->_percent < 20) {
+ item->remove();
+ scene->_list2.remove(item);
+
+ if (scene->_list2.empty()) {
+ ++_actionIndex;
+ scene->_sound1.fadeOut(this);
+ }
+ }
+
+ setDelay(6);
+ break;
+ }
+ case 1:
+ setDelay(1);
+ ++_actionIndex;
+ break;
+ case 2:
+ scene->_sound1.play(3);
+ scene->_sound1.setVol(127);
+
+ scene->_object1.postInit();
+ scene->_object1.setVisage(5510);
+ scene->_object1.setStrip(1);
+ scene->_object1.setFrame(1);
+ scene->_object1.changeZoom(10);
+ scene->_object1.fixPriority(100);
+ scene->_object1.setPosition(Common::Point(160, 190));
+
+ setDelay(3);
+ ++_actionIndex;
+ break;
+ case 3:
+ scene->_object1.changeZoom(scene->_object1._percent + 5);
+ if (scene->_object1._percent >= 100)
+ ++_actionIndex;
+
+ setDelay(3);
+ break;
+ case 4:
+ scene->_object2.postInit();
+ scene->_object2.setVisage(5000);
+ scene->_object2.setStrip(1);
+ scene->_object2.setFrame(1);
+ scene->_object2.fixPriority(110);
+ scene->_object2.setPosition(Common::Point(-30, 100));
+ scene->_object2.animate(ANIM_MODE_2);
+
+ scene->_object3.postInit();
+ scene->_object3.setVisage(5505);
+ scene->_object3.setStrip(1);
+ scene->_object3.setFrame(1);
+ scene->_object3.fixPriority(100);
+ scene->_object3.setPosition(Common::Point(412, 117));
+
+ scene->_object4.postInit();
+ scene->_object4.setVisage(5505);
+ scene->_object4.setStrip(2);
+ scene->_object4.setFrame(1);
+ scene->_object4.fixPriority(101);
+ scene->_object4.setPosition(Common::Point(scene->_object3._position.x + 35,
+ scene->_object3._position.y - 19));
+
+ ++_actionIndex;
+ setDelay(6);
+ break;
+ case 5:
+ scene->_creditIndex = 0;
+ scene->_object2.setPosition(Common::Point(scene->_object2._position.x +12, scene->_object2._position.y));
+
+ if (scene->_object2._position.x > 240)
+ ++_actionIndex;
+ break;
+ case 6:
+ ++scene->_creditIndex;
+ if ((scene->_creditIndex % 2) != 0) {
+ scene->_object2.setPosition(Common::Point(scene->_object2._position.x - 12, scene->_object2._position.y));
+ scene->_sound2.play(611);
+ } else {
+ scene->_object2.setPosition(Common::Point(scene->_object2._position.x + 12, scene->_object2._position.y));
+ }
+
+ if (scene->_creditIndex >= 6)
+ ++_actionIndex;
+ break;
+ case 7:
+ scene->loadBackground(8, 0);
+ scene->_object2.setPosition(Common::Point(scene->_object2._position.x, scene->_object2._position.y + 2));
+ scene->_object1.setPosition(Common::Point(scene->_object1._position.x - 12, scene->_object1._position.y));
+
+ if (scene->_sceneBounds.left >= 160) {
+ scene->_object1.remove();
+ ++_actionIndex;
+ }
+ break;
+ case 8:
+ scene->_object2.setPosition(Common::Point(scene->_object2._position.x + 12, scene->_object2._position.y));
+
+ if (scene->_object2._position.x > 321)
+ ++_actionIndex;
+ break;
+ case 9:
+ scene->_sound2.play(611);
+ scene->_object2.setPosition(Common::Point(scene->_object2._position.x - 12, scene->_object2._position.y));
+ scene->_object3.setPosition(Common::Point(scene->_object3._position.x + 12, scene->_object3._position.y));
+ scene->_object4.setPosition(Common::Point(scene->_object4._position.x + 12, scene->_object2._position.y));
+ scene->_object4.setFrame(scene->_object4.getFrameCount());
+
+ setDelay(6);
+ ++_actionIndex;
+ break;
+ case 10:
+ scene->_object3.setPosition(Common::Point(scene->_object3._position.x - 12, scene->_object3._position.y));
+ scene->_object4.setPosition(Common::Point(scene->_object4._position.x - 12, scene->_object2._position.y));
+ scene->_object4.setAction(&scene->_action2);
+ scene->_object2.setPosition(Common::Point(scene->_object2._position.x - 12, scene->_object2._position.y));
+ scene->_object2.fixPriority(80);
+
+ setDelay(6);
+ ++_actionIndex;
+ break;
+ case 11:
+ scene->_object2.changeZoom(scene->_object2._percent - 5);
+ if (scene->_object2._percent < 20)
+ ++_actionIndex;
+ break;
+ case 12:
+ scene->_object2.setPosition(Common::Point(scene->_object2._position.x + 2,
+ scene->_object2._position.y - ((scene->_object2._position.y <= 80) ? 0 : 2)));
+ if (scene->_object2._position.x > 390)
+ ++_actionIndex;
+ break;
+ case 13:
+ scene->_field846 = GW_GLOBALS._events.getFrameNumber() - scene->_field846;
+ scene->_field848 = (scene->_field846 > 3600) ? 2 : 1;
+ scene->_creditIndex = 0;
+ ++_actionIndex;
+ // Deliberate fall-through
+ case 14: {
+ setDelay(2);
+
+ if ((scene->_creditIndex != 0) && ((scene->_creditIndex == -1) || ((*scene->_list1.begin())->_position.y >= 142))) {
+ Common::String msg = g_resourceManager->getMessage(200, scene->_creditIndex);
+
+ if (msg.hasPrefix("~")) {
+ scene->_creditIndex = -1;
+ } else {
+ if (msg.empty())
+ msg = " ";
+
+ SceneText *sceneText = new SceneText();
+ sceneText->_fontNumber = 71;
+
+ if (msg.hasPrefix("@")) {
+ sceneText->_color1 = 43;
+ sceneText->_color2 = 46;
+ sceneText->_color3 = 80;
+ msg.deleteChar(0);
+ } else {
+ sceneText->_color1 = 100;
+ sceneText->_color2 = 103;
+ sceneText->_color3 = 16;
+ }
+
+ sceneText->_width = 400;
+ sceneText->setup(msg);
+ sceneText->_flags |= OBJFLAG_CLONED;
+ sceneText->fixPriority(199);
+
+ int fontNumber = GW_GLOBALS.gfxManager()._font._fontNumber;
+ GW_GLOBALS.gfxManager()._font.setFontNumber(sceneText->_fontNumber);
+ int strWidth = GW_GLOBALS.gfxManager().getStringWidth(msg.c_str());
+
+ sceneText->setPosition(Common::Point(270 - (strWidth / 2), 150));
+ GW_GLOBALS.gfxManager()._font.setFontNumber(fontNumber);
+
+ scene->_list1.push_back(sceneText);
+ }
+ }
+
+ SynchronizedList<SceneText *>::iterator i;
+ for (i = scene->_list1.begin(); i != scene->_list1.end(); ++i) {
+ SceneText *item = *i;
+ item->setPosition(Common::Point(item->_position.x, item->_position.y - scene->_field848));
+ }
+
+ SceneText *topItem = *scene->_list1.begin();
+ if (topItem->_position.y < 50) {
+ topItem->remove();
+ scene->_list1.remove(topItem);
+
+ if (scene->_list1.empty()) {
+ setDelay(10);
+ ++_actionIndex;
+ }
+ }
+ break;
+ }
+ case 15:
+ ++_actionIndex;
+ scene->_sound1.fade(0, 5, 4, true, this);
+ break;
+ case 16:
+ GW_GLOBALS._sceneManager.changeScene(500);
+ remove();
+ break;
+ }
+}
+
+void Scene200::Action2::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ ++_actionIndex;
+ setDelay(GW_GLOBALS._randomSource.getRandomNumber(50) + 50);
+ break;
+ case 1:
+ ++_actionIndex;
+ static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_8, 1, this);
+ break;
+ case 2:
+ _actionIndex = 0;
+ static_cast<SceneObject *>(_owner)->setFrame(1);
+ setDelay(1);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene200::Scene200(): Scene() {
+ _creditIndex = _fieldAB2 = 0;
+ _field846 = GW_GLOBALS._events.getFrameNumber();
+}
+
+void Scene200::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit();
+ loadScene(5500);
+ _sound1.play(2);
+
+ setAction(&_action1);
+}
+
+void Scene200::process(Event &event) {
+ switch (event.eventType) {
+ case EVENT_BUTTON_DOWN:
+ GW_GLOBALS._sceneManager.changeScene(500);
+ break;
+ case EVENT_KEYPRESS:
+ if ((event.kbd.keycode == Common::KEYCODE_ESCAPE) || (event.kbd.keycode == Common::KEYCODE_RETURN))
+ GW_GLOBALS._sceneManager.changeScene(500);
+ break;
+ default:
+ break;
+ }
+
+ if (!event.handled)
+ Scene::process(event);
+}
+
+} // End of namespace Geekwad
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/geekwad/geekwad_scenes0.h b/engines/tsage/geekwad/geekwad_scenes0.h
new file mode 100644
index 0000000000..8c04f12486
--- /dev/null
+++ b/engines/tsage/geekwad/geekwad_scenes0.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TSAGE_GEEKWAD_SCENES0_H
+#define TSAGE_GEEKWAD_SCENES0_H
+
+#include "common/scummsys.h"
+#include "tsage/converse.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/sound.h"
+#include "tsage/geekwad/geekwad_logic.h"
+
+namespace TsAGE {
+
+namespace Geekwad {
+
+using namespace TsAGE;
+
+class Scene150: public Scene {
+ /* Actions */
+ class Action1 : public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ Action1 _action1;
+ ScenePalette _scenePalette;
+ SceneObject _object1, _object2, _object3, _object4;
+ SceneObject _object5, _object6, _object7, _object8;
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+class Scene200: public Scene {
+ /* Actions */
+ class Action1: public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2: public Action {
+ public:
+ virtual void signal();
+ };
+public:
+ Action1 _action1;
+ Action2 _action2;
+ ASound _sound1, _sound2;
+ SceneObject _object1, _object2, _object3, _object4;
+ int _field846, _field848;
+ int _fieldAB2, _fieldAB4, _creditIndex;
+ SynchronizedList<SceneText *> _list1;
+ SynchronizedList<SceneObject2 *> _list2;
+
+ Scene200();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void process(Event &event);
+};
+
+} // End of namespace Geekwad
+
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 9bae180bc6..23898b5449 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -23,6 +23,7 @@
#include "tsage/globals.h"
#include "tsage/tsage.h"
#include "tsage/blue_force/blueforce_logic.h"
+#include "tsage/geekwad/geekwad_logic.h"
#include "tsage/ringworld/ringworld_demo.h"
#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/ringworld2/ringworld2_logic.h"
@@ -84,6 +85,14 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_fontColors.background = 88;
_fontColors.foreground = 92;
_dialogCenter.y = 140;
+ } else if (g_vm->getGameID() == GType_Geekwad) {
+ // Blue Force
+ _gfxFontNumber = 0;
+ _gfxColors.background = 89;
+ _gfxColors.foreground = 83;
+ _fontColors.background = 88;
+ _fontColors.foreground = 92;
+ _dialogCenter.y = 140;
} else if ((g_vm->getGameID() == GType_Ringworld) && (g_vm->getFeatures() & GF_CD)) {
_gfxFontNumber = 50;
_gfxColors.background = 53;
@@ -94,6 +103,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_color2 = 18;
_color3 = 18;
} else {
+ // Ringworld
_gfxFontNumber = 50;
_gfxColors.background = 53;
_gfxColors.foreground = 18;
@@ -137,6 +147,12 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
case GType_Ringworld2:
_inventory = new Ringworld2::Ringworld2InvObjectList();
_game = new Ringworld2::Ringworld2Game();
+ _sceneHandler = new Ringworld2::SceneHandlerExt();
+ break;
+
+ case GType_Geekwad:
+ _game = new Geekwad::GeekwadGame();
+ _inventory = NULL;
_sceneHandler = new SceneHandler();
break;
}
@@ -367,10 +383,21 @@ void Ringworld2Globals::reset() {
R2_INVENTORY.reset();
T2_GLOBALS._uiElements.updateInventory();
T2_GLOBALS._uiElements._active = false;
+
+ // Reset fields
+ _v5657C = 0;
+ _v565F5 = 0;
+ _diskScene = 0;
+ _v57C2C = 0;
}
void Ringworld2Globals::synchronize(Serializer &s) {
TsAGE2Globals::synchronize(s);
+
+ s.syncAsSint16LE(_v5657C);
+ s.syncAsSint16LE(_v565F5);
+ s.syncAsSint16LE(_diskScene);
+ s.syncAsSint16LE(_v57C2C);
}
} // end of namespace Ringworld2
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index 1e50c08f56..5eaa68deab 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -121,6 +121,7 @@ extern Globals *g_globals;
#define T2_GLOBALS (*((::TsAGE::TsAGE2Globals *)g_globals))
#define BF_GLOBALS (*((::TsAGE::BlueForce::BlueForceGlobals *)g_globals))
#define R2_GLOBALS (*((::TsAGE::Ringworld2::Ringworld2Globals *)g_globals))
+#define GW_GLOBALS (*((::TsAGE::Geekwad::GeekwadGlobals *)g_globals))
// Note: Currently this can't be part of the g_globals structure, since it needs to be constructed
// prior to many of the fields in Globals execute their constructors
@@ -243,6 +244,11 @@ namespace Ringworld2 {
class Ringworld2Globals: public TsAGE2Globals {
public:
ASoundExt _sound1, _sound2, _sound3, _sound4;
+ PlayStream _playStream;
+ int _diskScene;
+ int _v565F5;
+ int _v5657C;
+ int _v57C2C;
virtual void reset();
virtual void synchronize(Serializer &s);
@@ -250,6 +256,15 @@ public:
} // End of namespace Ringworld2
+namespace Geekwad {
+
+class GeekwadGlobals: public Globals {
+public:
+ ASoundExt _sound1;
+};
+
+} // End of namespace Geekwad
+
} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk
index 0ea8916647..60f1823da7 100644
--- a/engines/tsage/module.mk
+++ b/engines/tsage/module.mk
@@ -20,6 +20,8 @@ MODULE_OBJS := \
detection.o \
dialogs.o \
events.o \
+ geekwad/geekwad_logic.o \
+ geekwad/geekwad_scenes0.o \
globals.o \
graphics.o \
resources.o \
diff --git a/engines/tsage/ringworld/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp
index 3cf1207e9e..2090bc5da7 100644
--- a/engines/tsage/ringworld/ringworld_scenes5.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes5.cpp
@@ -2173,7 +2173,7 @@ void Scene4050::Action4::signal() {
case 5:
scene->_hotspot16.setStrip2(4);
scene->_hotspot16.setFrame(1);
- scene->_hotspot16.animate(ANIM_MODE_4, 4, 1, this);;
+ scene->_hotspot16.animate(ANIM_MODE_4, 4, 1, this);
break;
case 6:
scene->_hotspot16.animate(ANIM_MODE_5, NULL);
diff --git a/engines/tsage/ringworld/ringworld_scenes6.cpp b/engines/tsage/ringworld/ringworld_scenes6.cpp
index 57a073caee..30a91b57aa 100644
--- a/engines/tsage/ringworld/ringworld_scenes6.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes6.cpp
@@ -1124,7 +1124,7 @@ void Scene5100::postInit(SceneObjectList *OwnerList) {
_hotspot4.setVisage(5363);
_hotspot4.setPosition(Common::Point(1025, 65));
_hotspot4.setStrip(4);
- _hotspot4.animate(ANIM_MODE_7, 0, NULL);;
+ _hotspot4.animate(ANIM_MODE_7, 0, NULL);
g_globals->_sceneItems.push_back(&_hotspot4);
_hotspot9.postInit();
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index d033627ae9..642d265e42 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -38,6 +38,9 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Quinn's room
case 100: return new Scene100();
+ // Computer console
+ case 125: return new Scene125();
+
default:
error("Unknown scene number - %d", sceneNumber);
break;
@@ -221,6 +224,22 @@ void SceneExt::refreshBackground(int xAmount, int yAmount) {
/*--------------------------------------------------------------------------*/
+void SceneHandlerExt::postInit(SceneObjectList *OwnerList) {
+ SceneHandler::postInit(OwnerList);
+}
+
+void SceneHandlerExt::process(Event &event) {
+ if (T2_GLOBALS._uiElements._active) {
+ T2_GLOBALS._uiElements.process(event);
+ if (event.handled)
+ return;
+ }
+
+ SceneHandler::process(event);
+}
+
+/*--------------------------------------------------------------------------*/
+
DisplayHotspot::DisplayHotspot(int regionId, ...) {
_sceneRegionId = regionId;
@@ -398,7 +417,7 @@ void Ringworld2InvObjectList::reset() {
}
// Set up default inventory
- setObjectScene(R2_1, 800);
+ setObjectScene(R2_OPTO_DISK, 800);
setObjectScene(R2_2, 400);
setObjectScene(R2_NEGATOR_GUN, 100);
setObjectScene(R2_STEPPING_DISKS, 100);
diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h
index b12978344c..b0f388a2ae 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.h
+++ b/engines/tsage/ringworld2/ringworld2_logic.h
@@ -73,6 +73,13 @@ public:
void clearScreen();
};
+class SceneHandlerExt: public SceneHandler {
+public:
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void process(Event &event);
+};
+
+
class DisplayHotspot : public SceneObject {
private:
Common::Array<int> _actions;
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
index a2fb011d23..c03005ba8f 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp
@@ -346,6 +346,773 @@ void Scene100::dispatch() {
}
}
+/*--------------------------------------------------------------------------
+ * Scene 125 - Computer Terminal
+ *
+ *--------------------------------------------------------------------------*/
+
+bool Scene125::Object5::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return true;
+ else
+ return SceneActor::startAction(action, event);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Scene125::Icon::postInit(SceneObjectList *OwnerList) {
+ SceneObject::postInit();
+ _lookLineNum = 0;
+ _pressed = false;
+
+ _object1.postInit();
+ _object1.hide();
+
+ _sceneText1._color1 = 92;
+ _sceneText1._color2 = 0;
+ _sceneText1._width = 200;
+ _sceneText2._color1 = 0;
+ _sceneText2._color2 = 0;
+ _sceneText2._width = 200;
+ setDetails(125, -1, -1, -1, 2, NULL);
+}
+
+void Scene125::Icon::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+ s.syncAsSint16LE(_lookLineNum);
+ s.syncAsSint16LE(_field98);
+ s.syncAsSint16LE(_pressed);
+}
+
+void Scene125::Icon::process(Event &event) {
+ Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
+
+ if (!event.handled && !(_flags & OBJFLAG_HIDING) && R2_GLOBALS._player._uiEnabled &&
+ (event.eventType == EVENT_BUTTON_DOWN)) {
+
+ int regionIndex = R2_GLOBALS._sceneRegions.indexOf(event.mousePos);
+
+ switch (R2_GLOBALS._events.getCursor()) {
+ case CURSOR_LOOK:
+ if (regionIndex == _sceneRegionId) {
+ event.handled = true;
+ if (_lookLineNum == 26) {
+ SceneItem::display2(130, 7);
+ } else {
+ SceneItem::display2(130, _lookLineNum);
+ }
+ }
+ break;
+
+ case CURSOR_USE:
+ if ((regionIndex == _sceneRegionId) && !_pressed) {
+ scene->_sound1.play(14);
+ setFrame(2);
+
+ switch (_object1._strip) {
+ case 1:
+ _object1.setStrip(2);
+ break;
+ case 3:
+ _object1.setStrip(4);
+ break;
+ case 5:
+ _object1.setStrip(6);
+ break;
+ default:
+ break;
+ }
+
+ _pressed = true;
+ event.handled = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if ((event.eventType == EVENT_BUTTON_UP) && _pressed) {
+ switch (_object1._strip) {
+ case 2:
+ _object1.setStrip(1);
+ break;
+ case 4:
+ _object1.setStrip(3);
+ break;
+ case 6:
+ _object1.setStrip(5);
+ break;
+ default:
+ break;
+ }
+
+ _pressed = false;
+ event.handled = true;
+ scene->consoleAction(_lookLineNum);
+ }
+ }
+}
+
+void Scene125::Icon::setIcon(int id) {
+ Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
+
+ _lookLineNum = _field98 = id;
+ SceneActor::_lookLineNum = id;
+
+ _sceneText1.remove();
+ _sceneText2.remove();
+
+ if (_lookLineNum) {
+ showIcon();
+ _object1.setup(161, ((id - 1) / 10) * 2 + 1, ((id - 1) % 10) + 1);
+ _object1.setPosition(_position);
+
+ _sceneText1._fontNumber = scene->_iconFontNumber;
+ _sceneText1.setup(CONSOLE_MESSAGES[id]);
+ _sceneText1.fixPriority(20);
+
+ _sceneText2._fontNumber = scene->_iconFontNumber;
+ _sceneText2.setup(CONSOLE_MESSAGES[id]);
+ _sceneText2.fixPriority(20);
+
+ _sceneText2._fontNumber = scene->_iconFontNumber;
+ _sceneText2.setup(CONSOLE_MESSAGES[id]);
+ _sceneText2.fixPriority(10);
+
+ switch (_lookLineNum) {
+ case 5:
+ _sceneText1.setPosition(Common::Point(62, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(64, _position.y + 10));
+ break;
+ case 6:
+ case 7:
+ case 24:
+ case 25:
+ _sceneText1.setPosition(Common::Point(65, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(67, _position.y + 10));
+ break;
+ case 26:
+ _sceneText1.setPosition(Common::Point(83, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(85, _position.y + 10));
+ break;
+ default:
+ _sceneText1.setPosition(Common::Point(121, _position.y + 8));
+ _sceneText2.setPosition(Common::Point(123, _position.y + 10));
+ break;
+ }
+ } else {
+ hideIcon();
+ }
+}
+
+void Scene125::Icon::showIcon() {
+ _sceneText1.show();
+ _sceneText2.show();
+ _object1.show();
+ _object2.show();
+ show();
+}
+
+void Scene125::Icon::hideIcon() {
+ _sceneText1.hide();
+ _sceneText2.hide();
+ _object1.hide();
+ _object2.hide();
+ hide();
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool Scene125::Item4::startAction(CursorType action, Event &event) {
+ Scene125 *scene = (Scene125 *)R2_GLOBALS._sceneManager._scene;
+ switch (action) {
+ case CURSOR_USE:
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._diskScene) {
+ R2_GLOBALS._player.disableControl();
+ scene->_sceneMode = 126;
+ scene->setAction(&scene->_sequenceManager, scene, 126, &scene->_object7, NULL);
+ return true;
+ }
+ break;
+ case R2_OPTO_DISK:
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == 1) {
+ R2_GLOBALS._player.disableControl();
+ scene->_object7.postInit();
+ scene->_sceneMode = 125;
+ scene->setAction(&scene->_sequenceManager, scene, 125, &scene->_object7, NULL);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return SceneHotspot::startAction(action, event);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene125::Scene125(): SceneExt() {
+ _soundCount = _soundIndex = 0;
+ _iconFontNumber = 50;
+ _field412 = 5;
+}
+
+void Scene125::postInit(SceneObjectList *OwnerList) {
+ SceneExt::postInit();
+ loadScene(160);
+ _palette.loadPalette(0);
+
+ if (R2_GLOBALS._v5657C == 125)
+ R2_GLOBALS._diskScene = R2_GLOBALS._sceneManager._previousScene;
+
+ R2_GLOBALS._player.postInit();
+ R2_GLOBALS._player.hide();
+ R2_GLOBALS._player.disableControl();
+
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) == R2_GLOBALS._diskScene) {
+ _object7.postInit();
+ _object7.setup(160, 3, 5);
+ _object7.setPosition(Common::Point(47, 167));
+ }
+
+ _object6.postInit();
+ _object6.setup(162, 1, 1);
+ _object6.setPosition(Common::Point(214, 168));
+
+ _item4.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);
+ _item2.setDetails(1, 126, 3, 4, 5);
+ _background.setDetails(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 126, 0, 1, -1, 1, NULL);
+
+ _sceneMode = 1;
+ signal();
+}
+
+void Scene125::signal() {
+ switch (_sceneMode) {
+ case 1:
+ _icon1.postInit();
+ _icon1._sceneRegionId = 2;
+ _icon2.postInit();
+ _icon2._sceneRegionId = 3;
+ _icon3.postInit();
+ _icon3._sceneRegionId = 4;
+ _icon4.postInit();
+ _icon4._sceneRegionId = 5;
+
+ setAction(&_sequenceManager, this, 127, &_icon1, &_icon2, &_icon3, &_icon4, &R2_GLOBALS._player, NULL);
+ break;
+ case 2:
+ _icon1.setup(160, 1, 1);
+ _icon1.setPosition(Common::Point(65, 17));
+ _icon1._object2.postInit();
+ _icon1._object2.setup(160, 7, 1);
+ _icon1._object2.setPosition(Common::Point(106, 41));
+
+ _icon2.setup(160, 1, 1);
+ _icon2.setPosition(Common::Point(80, 32));
+ _icon2._object2.postInit();
+ _icon2._object2.setup(160, 7, 2);
+ _icon2._object2.setPosition(Common::Point(106, 56));
+
+ _icon3.setup(160, 1, 1);
+ _icon3.setPosition(Common::Point(65, 47));
+ _icon3._object2.postInit();
+ _icon3._object2.setup(160, 7, 1);
+ _icon3._object2.setPosition(Common::Point(106, 71));
+
+ _icon4.setup(160, 1, 1);
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4._object2.postInit();
+ _icon4._object2.setup(160, 7, 2);
+ _icon4._object2.setPosition(Common::Point(106, 86));
+
+ _icon5.postInit();
+ _icon5.setup(160, 1, 1);
+ _icon5.setPosition(Common::Point(37, 92));
+ _icon5.setIcon(6);
+ _icon5._sceneRegionId = 7;
+
+ _icon6.postInit();
+ _icon6.setPosition(Common::Point(106, 110));
+ _icon6.setIcon(5);
+ _icon6._sceneRegionId = 8;
+
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 10:
+ switch (_field412) {
+ case 12:
+ _sceneMode = 129;
+
+ _object1.postInit();
+ _object2.postInit();
+ _object3.postInit();
+
+ if (R2_GLOBALS.getFlag(13)) {
+ _object4.postInit();
+ setAction(&_sequenceManager, this, 130, &R2_GLOBALS._player, &_object1, &_object2,
+ &_object3, &_object4, NULL);
+ } else {
+ setAction(&_sequenceManager, this, 129, &R2_GLOBALS._player, &_object1, &_object2, &_object3, NULL);
+ }
+ break;
+ case 13:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field41A = 0;
+ setDetails(129, 0);
+ break;
+ case 23:
+ R2_GLOBALS._sceneManager.changeScene(1330);
+ break;
+ case 27:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field418 = 0;
+ setDetails(128, 0);
+ break;
+ case 28:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field418 = 37;
+ setDetails(128, 37);
+ break;
+ case 29:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field418 = 68;
+ setDetails(128, 68);
+ break;
+ case 30:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field418 = 105;
+ setDetails(128, 105);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ _field416 = 0;
+ setDetails(127, 0);
+ break;
+ }
+ break;
+ case 11:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+
+ if ((_field412 >= 27) && (_field412 <= 30)) {
+ consoleAction(11);
+ }
+ consoleAction(2);
+ _icon6.setIcon(5);
+ break;
+ case 12:
+ if (_soundCount > 0)
+ --_soundCount;
+ if (!_soundCount || (R2_GLOBALS._v57C2C == 2)) {
+ _soundIndex = 0;
+ R2_GLOBALS._playStream.stop();
+ } else {
+ _sceneMode = 12;
+ R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex++], this);
+ }
+ break;
+ case 125:
+ warning("TODO: Scene125::signal #125");
+ break;
+ case 126:
+ R2_INVENTORY.setObjectScene(R2_OPTO_DISK, 1);
+ _object7.remove();
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ case 128:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ SceneItem::display2(126, 12);
+ break;
+ default:
+ R2_GLOBALS._player.enableControl();
+ R2_GLOBALS._player._canWalk = false;
+ break;
+ }
+}
+
+void Scene125::synchronize(Serializer &s) {
+ error("TODO");
+}
+
+void Scene125::process(Event &event) {
+ SceneExt::process(event);
+
+ if (R2_GLOBALS._player._uiEnabled) {
+ _icon1.process(event);
+ _icon2.process(event);
+ _icon3.process(event);
+ _icon4.process(event);
+ _icon5.process(event);
+ _icon6.process(event);
+ }
+}
+
+void Scene125::dispatch() {
+ if (_soundCount)
+ R2_GLOBALS._playStream.proc1();
+
+ Scene::dispatch();
+}
+
+void Scene125::consoleAction(int id) {
+ _icon3.setIcon(0);
+ _icon4.setIcon(0);
+
+ if (id == 5)
+ _icon5.setIcon(5);
+ else {
+ switch (_field412) {
+ case 10:
+ case 12:
+ case 13:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ break;
+ default:
+ _icon5.setIcon(7);
+ break;
+ }
+ }
+
+ switch (id) {
+ case 0:
+ _icon1.setIcon(8);
+ _icon2.setIcon(9);
+ break;
+ case 1:
+ _icon1.setIcon(10);
+ _icon2.setIcon(11);
+ _icon3.setIcon(12);
+ _icon4.setIcon(13);
+ break;
+ case 2:
+ _icon1.setIcon(15);
+ _icon2.setIcon(16);
+ _icon3.setIcon(17);
+ break;
+ case 3:
+ _icon1.setIcon(22);
+ _icon2.setIcon(23);
+ break;
+ case 5:
+ R2_GLOBALS._sceneManager.changeScene(R2_GLOBALS._player._oldSceneNumber);
+ break;
+ case 6:
+ if (_field412 == 11)
+ consoleAction(2);
+ else if (_field412 == 22)
+ consoleAction(4);
+ else
+ consoleAction(5);
+ break;
+ case 7:
+ _iconFontNumber = 50;
+ stop();
+ _icon6.setIcon(5);
+ consoleAction(1);
+ break;
+ case 8:
+ _iconFontNumber = 52;
+ stop();
+ _icon6.setIcon(5);
+ consoleAction(1);
+ break;
+ case 9:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(2);
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon5.setIcon(24);
+
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ _icon6.setIcon(26);
+ _sceneMode = 10;
+
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 10:
+ _icon1.setIcon(27);
+ _icon2.setIcon(28);
+ _icon3.setIcon(29);
+ _icon4.setIcon(30);
+ break;
+ case 11:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(2);
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon4.hideIcon();
+ _icon5.hideIcon();
+
+ _icon6.setIcon(26);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 12:
+ consoleAction(2);
+ if (R2_INVENTORY.getObjectScene(R2_OPTO_DISK) != R2_GLOBALS._player._oldSceneNumber) {
+ SceneItem::display2(126, 17);
+ } else {
+ R2_GLOBALS._player.disableControl();
+
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon5.setIcon(24);
+
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ _icon6.setIcon(26);
+ _sceneMode = 10;
+
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ }
+ break;
+ case 14:
+ consoleAction(3);
+
+ if (R2_GLOBALS._v565F5 < 3) {
+ R2_GLOBALS._player.disableControl();
+ _object5.postInit();
+ _object5.setup(162, 2, 2);
+ _object5.setPosition(Common::Point(216, UI_INTERFACE_Y));
+
+ R2_GLOBALS._v565F5 += 2;
+ } else if (R2_GLOBALS._v565F5 == 3) {
+ SceneItem::display2(126, 13);
+ } else {
+ SceneItem::display2(126, 14);
+ }
+ break;
+ case 15:
+ consoleAction(3);
+
+ if (R2_GLOBALS._v565F5 < 4) {
+ R2_GLOBALS._player.disableControl();
+ _object5.postInit();
+ _object5.setup(162, 2, 3);
+ _object5.setPosition(Common::Point(218, UI_INTERFACE_Y));
+
+ ++R2_GLOBALS._v565F5;
+ } else {
+ SceneItem::display2(126, 15);
+ }
+ break;
+ case 16:
+ consoleAction(3);
+
+ if (R2_GLOBALS._v565F5 < 4) {
+ R2_GLOBALS._player.disableControl();
+ _object5.postInit();
+ _object5.setup(162, 2, 1);
+ _object5.setPosition(Common::Point(215, UI_INTERFACE_Y));
+
+ ++R2_GLOBALS._v565F5;
+ } else {
+ SceneItem::display2(126, 16);
+ }
+ break;
+ case 21:
+ _icon1.setIcon(31);
+ _icon2.setIcon(32);
+ _icon3.setIcon(33);
+ _icon4.setIcon(34);
+ break;
+ case 22:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(4);
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon4.hideIcon();
+ _icon5.hideIcon();
+ _icon6.hideIcon();
+
+ _sceneMode = 10;
+ _palette.loadPalette(161);
+ break;
+ case 23:
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ if (_field412 == 10) {
+ setDetails(127, --_field416);
+ } else if (_field412 == 13) {
+ setDetails(129, --_field41A);
+ } else {
+ setDetails(128, --_field418);
+ }
+ break;
+ case 24:
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ if (_field412 == 10) {
+ setDetails(127, ++_field416);
+ } else if (_field412 == 13) {
+ setDetails(129, ++_field41A);
+ } else {
+ setDetails(128, ++_field418);
+ }
+ break;
+ case 25:
+ R2_GLOBALS._player.disableControl();
+ stop();
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4.hideIcon();
+
+ R2_GLOBALS._player.hide();
+ _object1.hide();
+ _object2.hide();
+ _object3.hide();
+ _object4.hide();
+
+ _sceneMode = 11;
+ _palette.loadPalette(160);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ R2_GLOBALS._player.disableControl();
+ consoleAction(11);
+ _field412 = id;
+
+ _icon1.hideIcon();
+ _icon2.hideIcon();
+ _icon3.hideIcon();
+ _icon4.hideIcon();
+ _icon5.setIcon(24);
+
+ _icon4.setPosition(Common::Point(52, 107));
+ _icon4._sceneRegionId = 9;
+ _icon4.setIcon(25);
+ _icon4._object2.hide();
+
+ _icon6.setIcon(26);
+ _sceneMode = 10;
+
+ _palette.loadPalette(161);
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ break;
+ case 30:
+ consoleAction(22);
+ R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 63 : 10);
+ break;
+ case 31:
+ consoleAction(22);
+ R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 64 : 10);
+ break;
+ case 32:
+ consoleAction(22);
+ R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 65 : 10);
+ break;
+ case 33:
+ consoleAction(22);
+ R2_GLOBALS._sound1.play((R2_GLOBALS._sound1.getSoundNum() == 10) ? 66 : 10);
+ break;
+ default:
+ _icon1.setIcon(1);
+ _icon2.setIcon(2);
+ _icon3.setIcon(3);
+ _icon4.setIcon(4);
+ break;
+ }
+
+ if ((id != 6) && (id != 7) && (id != 23) && (id != 24))
+ _field412 = id;
+}
+
+void Scene125::setDetails(int resNum, int lineNum) {
+ stop();
+
+ Common::String msg = g_resourceManager->getMessage(resNum, lineNum);
+
+ if (msg.empty()) {
+ // Check for any specified sound numbers embedded in the message
+ Common::String msg = parseMessage(msg);
+
+ _sceneText._fontNumber = _iconFontNumber;
+ _sceneText._color1 = 92;
+ _sceneText._color2 = 0;
+ _sceneText._width = 221;
+ _sceneText.fixPriority(20);
+ _sceneText.setup(msg);
+ _sceneText.setPosition(Common::Point(49, 19));
+
+ R2_GLOBALS._sceneObjects->draw();
+
+ if ((_soundCount > 0) && (R2_GLOBALS._v57C2C != 2)) {
+ _sceneMode = 12;
+ R2_GLOBALS._playStream.play(_soundIndexes[_soundIndex], this);
+ }
+ } else {
+ R2_GLOBALS._player.disableControl();
+ R2_GLOBALS._player.hide();
+
+ _icon4.setPosition(Common::Point(80, 62));
+ _icon4._sceneRegionId = 5;
+ _icon4.hideIcon();
+
+ _field412 = 0;
+ _palette.loadPalette(160);
+ _sceneMode = 11;
+ R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 5, this);
+ }
+}
+
+void Scene125::stop() {
+ _sceneText.remove();
+ _soundIndex = 0;
+ _soundCount = 0;
+
+ R2_GLOBALS._playStream.stop();
+}
+
+Common::String Scene125::parseMessage(const Common::String &msg) {
+ _soundIndex = 0;
+ _soundCount = 0;
+
+ const char *msgP = msg.c_str();
+ while (*msgP == '!') {
+ // Get the sound number
+ _soundIndexes[_soundCount++] = atoi(++msgP);
+
+ while (!((*msgP == '\0') || (*msgP < '0') || (*msgP > '9')))
+ ++msgP;
+ }
+
+ return Common::String(msgP);
+}
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.h b/engines/tsage/ringworld2/ringworld2_scenes0.h
index a80bda0726..9ffe10f132 100644
--- a/engines/tsage/ringworld2/ringworld2_scenes0.h
+++ b/engines/tsage/ringworld2/ringworld2_scenes0.h
@@ -85,6 +85,62 @@ public:
virtual void dispatch();
};
+class Scene125: public SceneExt {
+ /* Objects */
+ class Object5: public SceneActor {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+ class Icon: public SceneActor {
+ public:
+ int _lookLineNum, _field98;
+ bool _pressed;
+ SceneObject _object1, _object2;
+ SceneText _sceneText1, _sceneText2;
+
+ virtual Common::String getClassName() { return "Scene125_Icon"; }
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void process(Event &event);
+
+ void setIcon(int id);
+ void showIcon();
+ void hideIcon();
+ };
+
+ /* Items */
+ class Item4: public NamedHotspot {
+ public:
+ virtual bool startAction(CursorType action, Event &event);
+ };
+
+public:
+ ScenePalette _palette;
+ ASoundExt _sound1;
+ NamedHotspot _background, _item2, _item3;
+ Item4 _item4;
+ SceneActor _object1, _object2, _object3, _object4, _object5, _object6, _object7;
+ Icon _icon1, _icon2, _icon3, _icon4, _icon5, _icon6;
+ SequenceManager _sequenceManager;
+ SceneText _sceneText;
+ int _field412, _iconFontNumber, _field416, _field418, _field41A;
+ int _soundCount, _soundIndex;
+ int _soundIndexes[10];
+
+ Scene125();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void synchronize(Serializer &s);
+ virtual void signal();
+ virtual void process(Event &event);
+ virtual void dispatch();
+
+ void consoleAction(int id);
+ void setDetails(int resNum, int lineNum);
+ void stop();
+ Common::String parseMessage(const Common::String &msg);
+};
+
} // End of namespace Ringworld2
} // End of namespace TsAGE
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 2c5d2ac951..3eb2432563 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -414,6 +414,15 @@ public:
virtual void signal();
};
+class PlayStream {
+public:
+ Sound _sound;
+
+ void setFile(const Common::String &filename) {}
+ void play(int soundNum, EventHandler *endAction) {}
+ void stop() {}
+ void proc1() {}
+};
#define ADLIB_CHANNEL_COUNT 9
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index c98d9d2e53..a6e6eae84e 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -180,4 +180,17 @@ const char *THE_NEXT_DAY = "The Next Day";
} // End of namespace BlueForce
+namespace Ringworld2 {
+
+const char *CONSOLE_MESSAGES[] = {
+ NULL, "Select Language", "Computer Services", "Food Services", "Entertainment Services",
+ "Main Menu", "Exit Menu", "Previous Menu", "Interworld", "Hero's Tongue", "Personal Log",
+ "Database", "Starchart", "Iso-Opto Disk Reader", "Eject Disk", "Meals", "Snacks",
+ "Beverages", "Human Basic Snacks", "Kzin Basic Snacks", "Hot Beverages", "Cold Beverages",
+ "Music", "Outpost Alpha", " ", " ", "Done", "A-G", "H-O", "P-S", "T-Z", "Tchaikovsky",
+ "Mozart", "Bach", "Rossini"
+};
+
+} // End of namespace Ringworld2
+
} // End of namespace TsAGE
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index 203fa1481d..b2c0b0f262 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -143,6 +143,13 @@ extern const char *THE_NEXT_DAY;
} // End of namespace BlueForce
+namespace Ringworld2 {
+
+// Scene 125 - Console messages
+extern const char *CONSOLE_MESSAGES[];
+
+} // End of namespace Ringworld2
+
} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp
index 7e7198fc2b..20b2eeac8f 100644
--- a/engines/tsage/tsage.cpp
+++ b/engines/tsage/tsage.cpp
@@ -97,7 +97,13 @@ void TSageEngine::initialize() {
// Reset all global variables
R2_GLOBALS.reset();
- }
+ } else if (g_vm->getGameID() == GType_Geekwad) {
+ g_resourceManager->addLib("GEEKWAD.RLB");
+ g_globals = new Geekwad::GeekwadGlobals();
+
+ // Reset all global variables
+ GW_GLOBALS.reset();
+ }
g_globals->gfxManager().setDefaults();
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
index eb36cf0790..e57823ecbc 100644
--- a/engines/tsage/tsage.h
+++ b/engines/tsage/tsage.h
@@ -41,7 +41,8 @@ namespace TsAGE {
enum {
GType_Ringworld = 0,
GType_BlueForce = 1,
- GType_Ringworld2 = 2
+ GType_Ringworld2 = 2,
+ GType_Geekwad = 3
};
enum {
diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp
index f6eae80d9c..9657d25875 100644
--- a/engines/tsage/user_interface.cpp
+++ b/engines/tsage/user_interface.cpp
@@ -266,7 +266,10 @@ void UICollection::draw() {
/*--------------------------------------------------------------------------*/
UIElements::UIElements(): UICollection() {
- _cursorVisage.setVisage(1, 5);
+ if (g_vm->getGameID() == GType_Ringworld2)
+ _cursorVisage.setVisage(5, 1);
+ else
+ _cursorVisage.setVisage(1, 5);
g_saver->addLoadNotifier(&UIElements::loadNotifierProc);
_characterIndex = 0;
}
@@ -302,7 +305,8 @@ void UIElements::synchronize(Serializer &s) {
}
void UIElements::process(Event &event) {
- if (_clearScreen && GLOBALS._player._enabled && (GLOBALS._sceneManager._sceneNumber != 50)) {
+ if (_clearScreen && GLOBALS._player._enabled &&
+ ((g_vm->getGameID() != GType_BlueForce) || (GLOBALS._sceneManager._sceneNumber != 50))) {
if (_bounds.contains(event.mousePos)) {
// Cursor inside UI area
if (!_cursorChanged) {
@@ -310,7 +314,8 @@ void UIElements::process(Event &event) {
// Inventory icon being displayed, so leave alone
} else {
// Change to the inventory use cursor
- GfxSurface surface = _cursorVisage.getFrame(6);
+ int cursorId = (g_vm->getGameID() == GType_Ringworld2) ? 11 : 6;
+ GfxSurface surface = _cursorVisage.getFrame(cursorId);
GLOBALS._events.setCursor(surface);
}
_cursorChanged = true;
diff --git a/gui/console.cpp b/gui/console.cpp
index dc2c5c4f33..49e2fccd98 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -245,6 +245,8 @@ void ConsoleDialog::handleTickle() {
} else
draw();
}
+
+ _scrollBar->handleTickle();
}
void ConsoleDialog::handleMouseWheel(int x, int y, int direction) {
diff --git a/gui/widgets/list.cpp b/gui/widgets/list.cpp
index 2a0d4afff0..13784ddf7f 100644
--- a/gui/widgets/list.cpp
+++ b/gui/widgets/list.cpp
@@ -220,6 +220,7 @@ void ListWidget::scrollBarRecalc() {
void ListWidget::handleTickle() {
if (_editMode)
EditableWidget::handleTickle();
+ _scrollBar->handleTickle();
}
void ListWidget::handleMouseDown(int x, int y, int button, int clickCount) {
diff --git a/gui/widgets/scrollbar.cpp b/gui/widgets/scrollbar.cpp
index e0dbcec59c..c7c17bc908 100644
--- a/gui/widgets/scrollbar.cpp
+++ b/gui/widgets/scrollbar.cpp
@@ -45,28 +45,8 @@ ScrollBarWidget::ScrollBarWidget(GuiObject *boss, int x, int y, int w, int h)
_numEntries = 0;
_entriesPerPage = 0;
_currentPos = 0;
-}
-
-static void upArrowRepeater(void *ref) {
- ScrollBarWidget *sb = (ScrollBarWidget *)ref;
- int old_pos = sb->_currentPos;
-
- sb->_currentPos -= 3;
- sb->checkBounds(old_pos);
-
- g_system->getTimerManager()->removeTimerProc(&upArrowRepeater);
- g_system->getTimerManager()->installTimerProc(&upArrowRepeater, 1000000/10, ref, "guiScrollBarUp");
-}
-
-static void downArrowRepeater(void *ref) {
- ScrollBarWidget *sb = (ScrollBarWidget *)ref;
- int old_pos = sb->_currentPos;
- sb->_currentPos += 3;
- sb->checkBounds(old_pos);
-
- g_system->getTimerManager()->removeTimerProc(&downArrowRepeater);
- g_system->getTimerManager()->installTimerProc(&downArrowRepeater, 1000000/10, ref, "guiScrollBarDown");
+ _repeatTimer = 0;
}
void ScrollBarWidget::handleMouseDown(int x, int y, int button, int clickCount) {
@@ -79,13 +59,13 @@ void ScrollBarWidget::handleMouseDown(int x, int y, int button, int clickCount)
if (y <= UP_DOWN_BOX_HEIGHT) {
// Up arrow
_currentPos--;
+ _repeatTimer = g_system->getMillis() + kRepeatInitialDelay;
_draggingPart = kUpArrowPart;
- g_system->getTimerManager()->installTimerProc(&upArrowRepeater, 1000000/2, this, "guiScrollBarUp");
} else if (y >= _h - UP_DOWN_BOX_HEIGHT) {
// Down arrow
_currentPos++;
+ _repeatTimer = g_system->getMillis() + kRepeatInitialDelay;
_draggingPart = kDownArrowPart;
- g_system->getTimerManager()->installTimerProc(&downArrowRepeater, 1000000/2, this, "guiScrollBarDown");
} else if (y < _sliderPos) {
_currentPos -= _entriesPerPage - 1;
} else if (y >= _sliderPos + _sliderHeight) {
@@ -101,9 +81,7 @@ void ScrollBarWidget::handleMouseDown(int x, int y, int button, int clickCount)
void ScrollBarWidget::handleMouseUp(int x, int y, int button, int clickCount) {
_draggingPart = kNoPart;
-
- g_system->getTimerManager()->removeTimerProc(&upArrowRepeater);
- g_system->getTimerManager()->removeTimerProc(&downArrowRepeater);
+ _repeatTimer = 0;
}
void ScrollBarWidget::handleMouseWheel(int x, int y, int direction) {
@@ -160,23 +138,21 @@ void ScrollBarWidget::handleMouseMoved(int x, int y, int button) {
}
void ScrollBarWidget::handleTickle() {
-/*
- // FIXME/TODO - this code is supposed to allow for "click-repeat" (like key repeat),
- // i.e. if you click on one of the arrows and keep clicked, it will scroll
- // continuously. However, just like key repeat, this requires two delays:
- // First an "initial" delay that has to pass before repeating starts (otherwise
- // it is near to impossible to achieve single clicks). Secondly, a repeat delay
- // that determines how often per second a click is simulated.
- int old_pos = _currentPos;
+ if (_repeatTimer) {
+ const uint32 curTime = g_system->getMillis();
+ if (curTime >= _repeatTimer) {
+ const int old_pos = _currentPos;
- if (_draggingPart == kUpArrowPart)
- _currentPos--;
- else if (_draggingPart == kDownArrowPart)
- _currentPos++;
+ if (_part == kUpArrowPart)
+ _currentPos -= 3;
+ else if (_part == kDownArrowPart)
+ _currentPos += 3;
- // Make sure that _currentPos is still inside the bounds
- checkBounds(old_pos);
-*/
+ checkBounds(old_pos);
+
+ _repeatTimer = curTime + kRepeatDelay;
+ }
+ }
}
void ScrollBarWidget::checkBounds(int old_pos) {
diff --git a/gui/widgets/scrollbar.h b/gui/widgets/scrollbar.h
index 3b248ce8a4..1c9f371cbc 100644
--- a/gui/widgets/scrollbar.h
+++ b/gui/widgets/scrollbar.h
@@ -49,6 +49,12 @@ protected:
Part _draggingPart;
int _sliderDeltaMouseDownPos;
+ enum {
+ kRepeatInitialDelay = 500,
+ kRepeatDelay = 100
+ };
+ uint32 _repeatTimer;
+
public:
int _numEntries;
int _entriesPerPage;