aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--NEWS20
-rw-r--r--README9
-rw-r--r--audio/fmopl.cpp31
-rw-r--r--audio/module.mk12
-rw-r--r--audio/opl2lpt.cpp154
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_midi.cpp2
-rw-r--r--audio/softsynth/opl/mame.cpp8
-rw-r--r--audio/softsynth/opl/nuked.cpp1488
-rw-r--r--audio/softsynth/opl/nuked.h188
-rw-r--r--backends/events/sdl/sdl-events.cpp44
-rw-r--r--backends/events/sdl/sdl-events.h5
-rw-r--r--backends/fs/amigaos4/amigaos4-fs.cpp2
-rw-r--r--backends/fs/ds/ds-fs-factory.cpp2
-rw-r--r--backends/fs/ds/ds-fs.cpp2
-rw-r--r--backends/platform/dc/dc-fs.cpp2
-rw-r--r--backends/platform/ds/arm7/source/main.cpp694
-rw-r--r--backends/platform/ds/arm9/source/cdaudio.cpp2
-rw-r--r--backends/platform/ds/arm9/source/dsmain.cpp39
-rw-r--r--backends/platform/ds/arm9/source/dsmain.h2
-rw-r--r--backends/platform/ds/arm9/source/dsoptions.cpp2
-rw-r--r--backends/platform/ds/arm9/source/fat/disc_io.c2
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.cpp3
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.h4
-rw-r--r--backends/platform/ds/arm9/source/wordcompletion.cpp2
-rw-r--r--backends/platform/ds/arm9/source/zipreader.cpp3
-rw-r--r--backends/platform/ds/ds.mk23
-rw-r--r--backends/platform/n64/portdefs.h15
-rw-r--r--backends/platform/sdl/riscos/riscos.mk3
-rw-r--r--backends/plugins/ds/ds-provider.cpp4
-rw-r--r--backends/plugins/elf/version.cpp2
-rw-r--r--base/commandLine.cpp32
-rw-r--r--base/main.cpp20
-rw-r--r--base/plugins.cpp4
-rw-r--r--base/plugins.h6
-rw-r--r--base/version.h8
-rw-r--r--common/archive.cpp2
-rw-r--r--common/config-manager.cpp4
-rw-r--r--common/config-manager.h4
-rw-r--r--common/fs.h2
-rw-r--r--common/hash-str.h8
-rw-r--r--common/hashmap.cpp8
-rw-r--r--common/hashmap.h12
-rw-r--r--common/language.cpp2
-rw-r--r--common/list.h2
-rw-r--r--common/memorypool.cpp2
-rw-r--r--common/memstream.h4
-rw-r--r--common/recorderfile.cpp9
-rw-r--r--common/rect.h8
-rw-r--r--common/scummsys.h12
-rw-r--r--common/serializer.h10
-rw-r--r--common/str.cpp8
-rw-r--r--common/str.h2
-rw-r--r--common/stream.cpp6
-rw-r--r--common/unzip.cpp32
-rw-r--r--common/updates.cpp2
-rw-r--r--common/updates.h2
-rw-r--r--common/ustr.cpp4
-rw-r--r--common/xmlparser.cpp2
-rw-r--r--common/zlib.cpp4
-rwxr-xr-xconfigure80
-rw-r--r--devtools/create_supernova/po_parser.cpp2
-rw-r--r--devtools/create_supernova/strings-en.po11
-rw-r--r--devtools/create_xeen/constants.cpp28
-rw-r--r--dists/engine-data/supernova.datbin77779 -> 116261 bytes
-rw-r--r--dists/engine-data/xeen.ccsbin54659 -> 54869 bytes
-rw-r--r--doc/cz/PrectiMe2
-rw-r--r--doc/de/LIESMICH2
-rw-r--r--doc/de/NEUES2
-rw-r--r--doc/se/LasMig2
-rw-r--r--engines/access/access.cpp12
-rw-r--r--engines/access/access.h2
-rw-r--r--engines/access/detection.cpp12
-rw-r--r--engines/access/scripts.cpp2
-rw-r--r--engines/adl/detection.cpp6
-rw-r--r--engines/agi/detection.cpp6
-rw-r--r--engines/avalanche/detection.cpp7
-rw-r--r--engines/bbvs/bbvs.h2
-rw-r--r--engines/bbvs/detection.cpp4
-rw-r--r--engines/bbvs/saveload.cpp10
-rw-r--r--engines/bladerunner/audio_speech.cpp2
-rw-r--r--engines/bladerunner/bladerunner.cpp20
-rw-r--r--engines/bladerunner/debugger.cpp13
-rw-r--r--engines/bladerunner/debugger.h1
-rw-r--r--engines/bladerunner/obstacles.cpp2
-rw-r--r--engines/bladerunner/screen_effects.h14
-rw-r--r--engines/bladerunner/ui/end_credits.cpp3
-rw-r--r--engines/cge/cge.h2
-rw-r--r--engines/cge/cge_main.cpp12
-rw-r--r--engines/cge/detection.cpp6
-rw-r--r--engines/cge/vga13h.cpp2
-rw-r--r--engines/cge2/cge2.h2
-rw-r--r--engines/cge2/detection.cpp6
-rw-r--r--engines/cge2/saveload.cpp12
-rw-r--r--engines/cge2/vga13h.cpp4
-rw-r--r--engines/cruise/detection.cpp11
-rw-r--r--engines/cruise/saveload.cpp13
-rw-r--r--engines/cruise/saveload.h2
-rw-r--r--engines/cryo/eden.cpp4
-rw-r--r--engines/dm/dm.h2
-rw-r--r--engines/dm/loadsave.cpp13
-rw-r--r--engines/draci/detection.cpp10
-rw-r--r--engines/draci/saveload.cpp11
-rw-r--r--engines/draci/saveload.h2
-rw-r--r--engines/drascula/detection.cpp6
-rw-r--r--engines/dreamweb/detection.cpp7
-rw-r--r--engines/fullpipe/detection.cpp8
-rw-r--r--engines/fullpipe/gameloader.h4
-rw-r--r--engines/fullpipe/modal.cpp3
-rw-r--r--engines/fullpipe/stateloader.cpp10
-rw-r--r--engines/gnap/detection.cpp15
-rw-r--r--engines/gnap/gnap.cpp2
-rw-r--r--engines/gnap/gnap.h2
-rw-r--r--engines/gnap/menu.cpp7
-rw-r--r--engines/hopkins/detection.cpp9
-rw-r--r--engines/hopkins/dialogs.cpp2
-rw-r--r--engines/hopkins/saveload.cpp19
-rw-r--r--engines/hopkins/saveload.h4
-rw-r--r--engines/hugo/detection.cpp7
-rw-r--r--engines/kyra/detection.cpp4
-rw-r--r--engines/kyra/eobcommon.h2
-rw-r--r--engines/kyra/kyra_v1.h2
-rw-r--r--engines/kyra/saveload.cpp11
-rw-r--r--engines/kyra/screen_eob.cpp4
-rw-r--r--engines/kyra/sequences_darkmoon.cpp2
-rw-r--r--engines/kyra/sequences_hof.cpp2
-rw-r--r--engines/lab/lab.h2
-rw-r--r--engines/lab/savegame.cpp14
-rw-r--r--engines/lilliput/detection.cpp6
-rw-r--r--engines/lilliput/lilliput.cpp727
-rw-r--r--engines/lilliput/lilliput.h99
-rw-r--r--engines/lilliput/script.cpp352
-rw-r--r--engines/lilliput/script.h43
-rw-r--r--engines/lilliput/sound.cpp108
-rw-r--r--engines/lilliput/sound.h23
-rw-r--r--engines/macventure/detection.cpp4
-rw-r--r--engines/macventure/saveload.cpp9
-rw-r--r--engines/mads/detection.cpp12
-rw-r--r--engines/mads/game.cpp12
-rw-r--r--engines/mads/game.h2
-rw-r--r--engines/mads/nebular/game_nebular.cpp5
-rw-r--r--engines/mads/nebular/nebular_scenes4.cpp4
-rw-r--r--engines/mohawk/myst.cpp85
-rw-r--r--engines/mohawk/myst.h2
-rw-r--r--engines/mohawk/myst_scripts.cpp10
-rw-r--r--engines/mohawk/myst_scripts.h1
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp44
-rw-r--r--engines/mohawk/myst_state.cpp7
-rw-r--r--engines/mohawk/riven_saveload.cpp6
-rw-r--r--engines/mortevielle/saveload.cpp20
-rw-r--r--engines/mortevielle/saveload.h2
-rw-r--r--engines/neverhood/detection.cpp4
-rw-r--r--engines/neverhood/menumodule.cpp2
-rw-r--r--engines/neverhood/neverhood.h2
-rw-r--r--engines/neverhood/saveload.cpp10
-rw-r--r--engines/plumbers/plumbers.cpp14
-rw-r--r--engines/prince/detection.cpp6
-rw-r--r--engines/prince/prince.h2
-rw-r--r--engines/prince/saveload.cpp12
-rw-r--r--engines/saga/detection.cpp6
-rw-r--r--engines/saga/interface.cpp4
-rw-r--r--engines/sci/detection.cpp9
-rw-r--r--engines/scumm/he/moonbase/ai_main.cpp12
-rw-r--r--engines/scumm/saveload.cpp4
-rw-r--r--engines/sherlock/detection.cpp5
-rw-r--r--engines/sherlock/image_file.cpp20
-rw-r--r--engines/sherlock/music.cpp4
-rw-r--r--engines/sherlock/objects.h2
-rw-r--r--engines/sherlock/saveload.cpp20
-rw-r--r--engines/sherlock/saveload.h2
-rw-r--r--engines/sherlock/scalpel/scalpel.cpp4
-rw-r--r--engines/sherlock/tattoo/tattoo_people.cpp2
-rw-r--r--engines/sludge/builtin.cpp105
-rw-r--r--engines/sludge/cursors.cpp23
-rw-r--r--engines/sludge/cursors.h2
-rw-r--r--engines/sludge/event.cpp15
-rw-r--r--engines/sludge/event.h2
-rw-r--r--engines/sludge/freeze.cpp22
-rw-r--r--engines/sludge/freeze.h7
-rw-r--r--engines/sludge/loadsave.cpp28
-rw-r--r--engines/sludge/main_loop.cpp2
-rw-r--r--engines/sludge/people.cpp487
-rw-r--r--engines/sludge/people.h162
-rw-r--r--engines/sludge/region.cpp167
-rw-r--r--engines/sludge/region.h50
-rw-r--r--engines/sludge/sludge.cpp8
-rw-r--r--engines/sludge/sludge.h4
-rw-r--r--engines/sludge/sludger.cpp11
-rw-r--r--engines/sludge/speech.cpp12
-rw-r--r--engines/sludge/statusba.cpp6
-rw-r--r--engines/sludge/variable.cpp15
-rw-r--r--engines/sludge/variable.h6
-rw-r--r--engines/supernova/detection.cpp25
-rw-r--r--engines/supernova/graphics.cpp25
-rw-r--r--engines/supernova/graphics.h6
-rw-r--r--engines/supernova/imageid.h654
-rw-r--r--engines/supernova/module.mk7
-rw-r--r--engines/supernova/msn_def.h292
-rw-r--r--engines/supernova/resman.cpp395
-rw-r--r--engines/supernova/resman.h77
-rw-r--r--engines/supernova/rooms.cpp404
-rw-r--r--engines/supernova/rooms.h45
-rw-r--r--engines/supernova/screen.cpp636
-rw-r--r--engines/supernova/screen.h197
-rw-r--r--engines/supernova/screenstatic.cpp328
-rw-r--r--engines/supernova/sound.cpp65
-rw-r--r--engines/supernova/sound.h80
-rw-r--r--engines/supernova/state.cpp363
-rw-r--r--engines/supernova/state.h37
-rw-r--r--engines/supernova/supernova.cpp858
-rw-r--r--engines/supernova/supernova.h174
-rw-r--r--engines/sword1/detection.cpp6
-rw-r--r--engines/sword25/gfx/graphicengine.cpp10
-rw-r--r--engines/teenagent/detection.cpp7
-rw-r--r--engines/testbed/graphics.cpp41
-rw-r--r--engines/tinsel/cursor.cpp4
-rw-r--r--engines/tinsel/pcode.cpp4
-rw-r--r--engines/titanic/core/project_item.cpp17
-rw-r--r--engines/titanic/core/project_item.h2
-rw-r--r--engines/titanic/detection.cpp10
-rw-r--r--engines/titanic/pet_control/pet_load_save.cpp5
-rw-r--r--engines/titanic/titanic.cpp6
-rw-r--r--engines/toltecs/detection.cpp4
-rw-r--r--engines/toltecs/menu.cpp2
-rw-r--r--engines/toltecs/saveload.cpp10
-rw-r--r--engines/toltecs/toltecs.h2
-rw-r--r--engines/tony/loc.cpp2
-rw-r--r--engines/toon/detection.cpp6
-rw-r--r--engines/tsage/detection.cpp9
-rw-r--r--engines/tsage/saveload.cpp15
-rw-r--r--engines/tsage/saveload.h2
-rw-r--r--engines/tucker/detection.cpp4
-rw-r--r--engines/tucker/saveload.cpp12
-rw-r--r--engines/tucker/tucker.h4
-rw-r--r--engines/voyeur/detection.cpp3
-rw-r--r--engines/voyeur/files_threads.cpp2
-rw-r--r--engines/voyeur/voyeur.cpp11
-rw-r--r--engines/voyeur/voyeur.h2
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp2
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.h2
-rw-r--r--engines/xeen/character.cpp15
-rw-r--r--engines/xeen/character.h6
-rw-r--r--engines/xeen/combat.cpp204
-rw-r--r--engines/xeen/combat.h29
-rw-r--r--engines/xeen/debugger.cpp9
-rw-r--r--engines/xeen/debugger.h6
-rw-r--r--engines/xeen/detection.cpp24
-rw-r--r--engines/xeen/detection_tables.h12
-rw-r--r--engines/xeen/dialogs/dialogs.cpp75
-rw-r--r--engines/xeen/dialogs/dialogs_char_info.cpp14
-rw-r--r--engines/xeen/dialogs/dialogs_control_panel.cpp3
-rw-r--r--engines/xeen/dialogs/dialogs_input.cpp55
-rw-r--r--engines/xeen/dialogs/dialogs_input.h6
-rw-r--r--engines/xeen/dialogs/dialogs_items.cpp7
-rw-r--r--engines/xeen/dialogs/dialogs_message.cpp2
-rw-r--r--engines/xeen/dialogs/dialogs_party.cpp2
-rw-r--r--engines/xeen/dialogs/dialogs_quests.cpp52
-rw-r--r--engines/xeen/dialogs/dialogs_spells.cpp66
-rw-r--r--engines/xeen/events.cpp56
-rw-r--r--engines/xeen/events.h63
-rw-r--r--engines/xeen/files.cpp1
-rw-r--r--engines/xeen/interface.cpp75
-rw-r--r--engines/xeen/interface.h1
-rw-r--r--engines/xeen/interface_minimap.cpp6
-rw-r--r--engines/xeen/interface_scene.cpp93
-rw-r--r--engines/xeen/interface_scene.h25
-rw-r--r--engines/xeen/item.cpp17
-rw-r--r--engines/xeen/locations.cpp186
-rw-r--r--engines/xeen/locations.h4
-rw-r--r--engines/xeen/map.cpp19
-rw-r--r--engines/xeen/map.h20
-rw-r--r--engines/xeen/module.mk1
-rw-r--r--engines/xeen/party.cpp190
-rw-r--r--engines/xeen/party.h11
-rw-r--r--engines/xeen/patcher.cpp86
-rw-r--r--engines/xeen/patcher.h48
-rw-r--r--engines/xeen/resources.cpp5
-rw-r--r--engines/xeen/resources.h5
-rw-r--r--engines/xeen/saves.cpp45
-rw-r--r--engines/xeen/saves.h2
-rw-r--r--engines/xeen/scripts.cpp138
-rw-r--r--engines/xeen/scripts.h2
-rw-r--r--engines/xeen/sound.cpp44
-rw-r--r--engines/xeen/spells.cpp15
-rw-r--r--engines/xeen/sprites.cpp6
-rw-r--r--engines/xeen/worldofxeen/worldofxeen_menu.cpp8
-rw-r--r--engines/xeen/xeen.cpp18
-rw-r--r--engines/xeen/xeen.h18
-rw-r--r--engines/zvision/detection.cpp2
-rw-r--r--engines/zvision/detection_tables.h2
-rw-r--r--engines/zvision/file/save_manager.cpp24
-rw-r--r--engines/zvision/file/save_manager.h2
-rw-r--r--graphics/VectorRenderer.cpp2
-rw-r--r--graphics/VectorRenderer.h2
-rw-r--r--graphics/VectorRendererSpec.cpp26
-rw-r--r--graphics/fonts/bdf.h4
-rw-r--r--graphics/nine_patch.cpp2
-rw-r--r--graphics/primitives.cpp62
-rw-r--r--graphics/scaler.cpp14
-rw-r--r--graphics/scaler/intern.h12
-rw-r--r--graphics/scaler/scalebit.cpp42
-rw-r--r--graphics/sjis.cpp22
-rw-r--r--graphics/thumbnail.cpp28
-rw-r--r--graphics/thumbnail.h2
-rw-r--r--gui/predictivedialog.cpp6
-rw-r--r--gui/themes/translations.datbin747035 -> 746774 bytes
-rw-r--r--image/codecs/cinepak.cpp20
-rw-r--r--image/codecs/cinepak.h1
-rw-r--r--image/codecs/indeo/indeo.cpp36
-rw-r--r--image/codecs/indeo3.cpp36
-rw-r--r--po/be_BY.po62
-rw-r--r--po/ca_ES.po61
-rw-r--r--po/cs_CZ.po58
-rw-r--r--po/da_DK.po60
-rw-r--r--po/de_DE.po187
-rw-r--r--po/el.po59
-rw-r--r--po/es_ES.po60
-rw-r--r--po/eu.po59
-rw-r--r--po/fi_FI.po63
-rw-r--r--po/fr_FR.po62
-rw-r--r--po/gl_ES.po60
-rw-r--r--po/hu_HU.po60
-rw-r--r--po/it_IT.po66
-rw-r--r--po/nb_NO.po62
-rw-r--r--po/nl_NL.po68
-rw-r--r--po/nn_NO.po66
-rw-r--r--po/pl_PL.po58
-rw-r--r--po/pt_BR.po57
-rw-r--r--po/pt_PT.po61
-rw-r--r--po/ru_RU.po62
-rw-r--r--po/scummvm.pot49
-rw-r--r--po/sv_SE.po111
-rw-r--r--po/uk_UA.po60
-rw-r--r--po/zh-Latn_CN.po60
-rw-r--r--video/bink_decoder.cpp2
335 files changed, 9738 insertions, 5277 deletions
diff --git a/.gitignore b/.gitignore
index c19710fd13..d2ad011369 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,9 @@ lib*.a
/*,e1f
/scummvm-ps3.pkg
/*.ipk
+/map.txt
+*.elf
+/*.nds
/.project
/.cproject
/.settings
@@ -53,6 +56,7 @@ lib*.a
/backends/platform/ds/arm7/build
/backends/platform/ds/arm7/source/libcartreset/*.bak
/backends/platform/ds/arm7/source/libcartreset/*.d
+/backends/platform/ds/arm9/data/*.h
/backends/platform/ds/arm9/scummvm-?
/backends/platform/maemo/scummvm
diff --git a/NEWS b/NEWS
index 783e336581..222d57c4bb 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,10 @@ For a more comprehensive changelog of the latest experimental code, see:
- Improved Audio quality in Humongous Entertainment games by using the Miles AdLib driver.
- Fixed possible stack overflows in The Dig and Full Throttle.
+ Tinsel:
+ - Fix loading Discworld 1 savegames from the launcher where Rincewind had a held item
+ - Script patch for hang in Discworld 1 GRA using items on Temple big hammer
+
Tucker:
- Fixed multiple graphic issues in Bud Tucker in Double Trouble.
- Fixed multiple issues with font and subtitle rendering.
@@ -601,16 +605,16 @@ For a more comprehensive changelog of the latest experimental code, see:
- Added FluidSynth settings dialog, mainly for reverb and chorus settings.
- Fixed crash on certain Smacker movies.
- Cine:
+ Cine:
- Improved audio support for Amiga and AtariST versions of Future Wars.
Now music fades out slowly instead of stopping immediately. Sound
effects are now properly panned, when requested by the game.
- CGE:
+ CGE:
- Soltys contains a puzzle requiring the ALT key to be pressed while clicking
on an object. This puzzle has been disabled on devices not using this key.
- Drascula:
+ Drascula:
- Resolved multiple UI issues with the original save/load screen.
- Added advanced savegame functionality, including savegame timestamps and
thumbnails and the ability to load and delete savegames from the launcher.
@@ -620,7 +624,7 @@ For a more comprehensive changelog of the latest experimental code, see:
save screen, if the user has selected to use the ScummVM save/load
dialogs.
- Dreamweb:
+ Dreamweb:
- Now that the game is freeware, there is a small extra help text showing
the available commands in the in-game terminals when the player uses the
'help' command. Previously, players needed to consult the manual for the
@@ -628,18 +632,18 @@ For a more comprehensive changelog of the latest experimental code, see:
protection, this extra line can be toggled by the ScummVM copy protection
command line option.
- Groovie:
+ Groovie:
- Simplified the movie speed options, and added a custom option for The 7th
Guest. Movie options are now "normal" and "fast", with the latter changing
the movie speed in T7G to match the faster movie speed of the iOS version.
The game entry might need to be readded in the launcher for the new setting
to appear.
- SAGA:
+ SAGA:
- Added music support for the Macintosh version of I Have No Mouth and, I
Must Scream.
- SCUMM:
+ SCUMM:
- Implemented Monkey Island 2 Macintosh's audio driver. Now we properly
support its sample based audio output. The same output is also used for
the m68k Macintosh version of Indiana Jones and the Fate of Atlantis.
@@ -983,7 +987,7 @@ For a more comprehensive changelog of the latest experimental code, see:
- Fixed 16bit mouse cursors on HE games.
1.2.1 (2010-12-19)
- General
+ General:
- Added Hungarian translation.
- Added Brazilian Portuguese translation.
diff --git a/README b/README
index c777c64933..beddb22b1c 100644
--- a/README
+++ b/README
@@ -544,13 +544,16 @@ ScummVM will skip copy protection in the following games:
-- bypassed with kind permission from Wyrmkeep Entertainment,
since it was bypassed in all CD releases of the game.
* Loom (EGA DOS)
+ * Lure of the Temptress
* Maniac Mansion
+ * Might and Magic: World of Xeen
* Monkey Island 2: LeChuck's Revenge
* Simon the Sorcerer 1 (Floppy version)
* Simon the Sorcerer 2 (Floppy version)
-- bypassed with kind permission from Adventure Soft,
since it was bypassed in all CD releases of the game.
* The Secret of Monkey Island (VGA)
+ * Voyeur
* Waxworks
* Zak McKracken and the Alien Mindbenders
@@ -1520,7 +1523,7 @@ arguments -- see the next section.
--native-mt32 True Roland MT-32 (disable GM emulation)
--enable-gs Enable Roland GS mode for MIDI playback
--output-rate=RATE Select output sample rate in Hz (e.g. 22050)
- --opl-driver=DRIVER Select AdLib (OPL) emulator (db, mame)
+ --opl-driver=DRIVER Select AdLib (OPL) emulator (db, mame, nuked)
--aspect-ratio Enable aspect ratio correction
--render-mode=MODE Enable additional render modes (hercGreen, hercAmber,
cga, ega, vga, amiga, fmtowns, pc9821, pc9801, 2gs,
@@ -2630,6 +2633,10 @@ The following keywords are recognized:
cdrom number Number of CD-ROM unit to use for audio. If
negative, don't even try to access the CD-ROM.
joystick_num number Number of joystick device to use for input
+ controller_map_db string A custom controller mapping file to load to
+ complete default database (SDL backend only).
+ Otherwise, file gamecontrollerdb.txt will be
+ loaded from extrapath.
music_driver string The music engine to use.
opl_driver string The AdLib (OPL) emulator to use.
output_rate number The output sample rate to use, in Hz. Sensible
diff --git a/audio/fmopl.cpp b/audio/fmopl.cpp
index a43b08c422..3a003c80d9 100644
--- a/audio/fmopl.cpp
+++ b/audio/fmopl.cpp
@@ -25,6 +25,7 @@
#include "audio/mixer.h"
#include "audio/softsynth/opl/dosbox.h"
#include "audio/softsynth/opl/mame.h"
+#include "audio/softsynth/opl/nuked.h"
#include "common/config-manager.h"
#include "common/system.h"
@@ -42,13 +43,21 @@ namespace ALSA {
} // End of namespace ALSA
#endif // USE_ALSA
+#ifdef ENABLE_OPL2LPT
+namespace OPL2LPT {
+ OPL *create();
+} // End of namespace OPL2LPT
+#endif // ENABLE_OPL2LPT
+
// Config implementation
enum OplEmulator {
kAuto = 0,
kMame = 1,
kDOSBox = 2,
- kALSA = 3
+ kALSA = 3,
+ kNuked = 4,
+ kOPL2LPT = 5
};
OPL::OPL() {
@@ -63,9 +72,15 @@ const Config::EmulatorDescription Config::_drivers[] = {
#ifndef DISABLE_DOSBOX_OPL
{ "db", _s("DOSBox OPL emulator"), kDOSBox, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
#endif
+#ifndef DISABLE_NUKED_OPL
+ { "nuked", _s("Nuked OPL emulator"), kNuked, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
+#endif
#ifdef USE_ALSA
{ "alsa", _s("ALSA Direct FM"), kALSA, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
#endif
+#ifdef ENABLE_OPL2LPT
+ { "opl2lpt", _s("OPL2LPT"), kOPL2LPT, kFlagOpl2 },
+#endif
{ 0, 0, 0, 0 }
};
@@ -178,11 +193,25 @@ OPL *Config::create(DriverId driver, OplType type) {
return new DOSBox::OPL(type);
#endif
+#ifndef DISABLE_NUKED_OPL
+ case kNuked:
+ return new NUKED::OPL(type);
+#endif
+
#ifdef USE_ALSA
case kALSA:
return ALSA::create(type);
#endif
+#ifdef ENABLE_OPL2LPT
+ case kOPL2LPT:
+ if (type == kOpl2)
+ return OPL2LPT::create();
+ else
+ warning("OPL2LPT only supports OPL2");
+ return 0;
+#endif
+
default:
warning("Unsupported OPL emulator %d", driver);
// TODO: Maybe we should add some dummy emulator too, which just outputs
diff --git a/audio/module.mk b/audio/module.mk
index 0d95ecc6f1..49584aba90 100644
--- a/audio/module.mk
+++ b/audio/module.mk
@@ -60,11 +60,23 @@ MODULE_OBJS := \
softsynth/sid.o \
softsynth/wave6581.o
+ifndef DISABLE_NUKED_OPL
+MODULE_OBJS += \
+ softsynth/opl/nuked.o
+endif
+
+
+
ifdef USE_ALSA
MODULE_OBJS += \
alsa_opl.o
endif
+ifdef ENABLE_OPL2LPT
+MODULE_OBJS += \
+ opl2lpt.o
+endif
+
ifndef USE_ARM_SOUND_ASM
MODULE_OBJS += \
rate.o
diff --git a/audio/opl2lpt.cpp b/audio/opl2lpt.cpp
new file mode 100644
index 0000000000..fc5a4ef465
--- /dev/null
+++ b/audio/opl2lpt.cpp
@@ -0,0 +1,154 @@
+/* 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.
+ *
+ */
+
+/* OPL implementation for OPL2LPT through libieee1284.
+ */
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+#include "common/scummsys.h"
+
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/str.h"
+#include "common/textconsole.h"
+#include "audio/fmopl.h"
+
+#include <unistd.h>
+#include <ieee1284.h>
+
+namespace OPL {
+namespace OPL2LPT {
+
+class OPL : public ::OPL::RealOPL {
+private:
+ struct parport *_pport;
+ int index;
+ static const uint8 ctrlBytes[];
+
+public:
+ OPL();
+ ~OPL();
+
+ bool init();
+ void reset();
+
+ void write(int a, int v);
+ byte read(int a);
+
+ void writeReg(int r, int v);
+};
+
+const uint8 OPL::ctrlBytes[] = {
+ (C1284_NSELECTIN | C1284_NSTROBE | C1284_NINIT) ^ C1284_INVERTED,
+ (C1284_NSELECTIN | C1284_NSTROBE) ^ C1284_INVERTED,
+ (C1284_NSELECTIN | C1284_NSTROBE | C1284_NINIT) ^ C1284_INVERTED,
+
+ (C1284_NSELECTIN | C1284_NINIT) ^ C1284_INVERTED,
+ C1284_NSELECTIN ^ C1284_INVERTED,
+ (C1284_NSELECTIN | C1284_NINIT) ^ C1284_INVERTED
+};
+
+OPL::OPL() : _pport(nullptr) {
+}
+
+OPL::~OPL() {
+ if (_pport) {
+ stop();
+ reset();
+ ieee1284_close(_pport);
+ }
+}
+
+bool OPL::init() {
+ struct parport_list parports = {};
+ const Common::String parportName = ConfMan.get("opl2lpt_parport");
+
+ // Look for available parallel ports
+ if (ieee1284_find_ports(&parports, 0) != E1284_OK) {
+ return false;
+ }
+ for (int i = 0; i < parports.portc; i++) {
+ if (parportName == "null" ||
+ parportName == parports.portv[i]->name) {
+ int caps = CAP1284_RAW;
+ _pport = parports.portv[i];
+ if (ieee1284_open(_pport, F1284_EXCL, &caps) != E1284_OK) {
+ warning("cannot open parallel port %s", _pport->name);
+ }
+ if (ieee1284_claim(_pport) != E1284_OK) {
+ warning("cannot claim parallel port %s", _pport->name);
+ ieee1284_close(_pport);
+ continue;
+ }
+ reset();
+ // Safe to free ports here, opened ports are refcounted.
+ ieee1284_free_ports(&parports);
+ return true;
+ }
+ }
+ _pport = nullptr;
+ ieee1284_free_ports(&parports);
+ return false;
+}
+
+void OPL::reset() {
+ for(int i = 0; i < 256; i ++) {
+ writeReg(i, 0);
+ }
+ index = 0;
+}
+
+void OPL::write(int port, int val) {
+ if (port & 1) {
+ writeReg(index, val);
+ } else {
+ index = val;
+ }
+}
+
+byte OPL::read(int port) {
+ // No read support for the OPL2LPT
+ return 0;
+}
+
+void OPL::writeReg(int r, int v) {
+ r &= 0xff;
+ v &= 0xff;
+ ieee1284_write_data(_pport, r);
+ ieee1284_write_control(_pport, ctrlBytes[0]);
+ ieee1284_write_control(_pport, ctrlBytes[1]);
+ ieee1284_write_control(_pport, ctrlBytes[2]);
+ usleep(4); // 3.3 us
+
+ ieee1284_write_data(_pport, v);
+ ieee1284_write_control(_pport, ctrlBytes[3]);
+ ieee1284_write_control(_pport, ctrlBytes[4]);
+ ieee1284_write_control(_pport, ctrlBytes[5]);
+ usleep(23);
+}
+
+OPL *create() {
+ return new OPL();
+}
+
+} // End of namespace OPL2LPT
+} // End of namespace OPL
diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp
index 46b1a6406d..c02b047153 100644
--- a/audio/softsynth/fmtowns_pc98/towns_midi.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp
@@ -572,7 +572,7 @@ void TownsMidiOutputChannel::keyOff() {
void TownsMidiOutputChannel::keyOnSetFreq(uint16 frq) {
uint16 note = (frq << 1) >> 8;
- frq = (_freqMSB[note] << 11) | _freqLSB[note] ;
+ frq = (_freqMSB[note] << 11) | _freqLSB[note];
out(0xa4, frq >> 8);
out(0xa0, frq & 0xff);
//out(0x28, 0x00);
diff --git a/audio/softsynth/opl/mame.cpp b/audio/softsynth/opl/mame.cpp
index eb08582da0..cba95422fc 100644
--- a/audio/softsynth/opl/mame.cpp
+++ b/audio/softsynth/opl/mame.cpp
@@ -29,6 +29,10 @@
#include <stdarg.h>
#include <math.h>
+#if defined(__DS__)
+#include "dsmain.h"
+#endif
+
#include "mame.h"
#include "audio/mixer.h"
@@ -40,10 +44,6 @@
#include "common/config-manager.h"
#endif
-#if defined(__DS__)
-#include "dsmain.h"
-#endif
-
namespace OPL {
namespace MAME {
diff --git a/audio/softsynth/opl/nuked.cpp b/audio/softsynth/opl/nuked.cpp
new file mode 100644
index 0000000000..9ee3ad39f0
--- /dev/null
+++ b/audio/softsynth/opl/nuked.cpp
@@ -0,0 +1,1488 @@
+//
+// Copyright (C) 2013-2018 Alexey Khokholov (Nuke.YKT)
+//
+// 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.
+//
+//
+// Nuked OPL3 emulator.
+// Thanks:
+// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh):
+// Feedback and Rhythm part calculation information.
+// forums.submarine.org.uk(carbon14, opl3):
+// Tremolo and phase generator calculation information.
+// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
+// OPL2 ROMs.
+// siliconpr0n.org(John McMaster, digshadow):
+// YMF262 and VRC VII decaps and die shots.
+//
+// version: 1.8
+//
+
+#include <stdlib.h>
+#include <string.h>
+#include "audio/mixer.h"
+#include "common/system.h"
+#include "common/scummsys.h"
+#include "nuked.h"
+
+#ifndef DISABLE_NUKED_OPL
+
+namespace OPL {
+namespace NUKED {
+
+#define RSM_FRAC 10
+
+// Channel types
+
+enum {
+ ch_2op = 0,
+ ch_4op = 1,
+ ch_4op2 = 2,
+ ch_drum = 3
+};
+
+// Envelope key types
+
+enum {
+ egk_norm = 0x01,
+ egk_drum = 0x02
+};
+
+
+//
+// logsin table
+//
+
+static const Bit16u logsinrom[256] = {
+ 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471,
+ 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365,
+ 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd,
+ 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261,
+ 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f,
+ 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd,
+ 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195,
+ 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166,
+ 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c,
+ 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118,
+ 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8,
+ 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db,
+ 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1,
+ 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9,
+ 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094,
+ 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081,
+ 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070,
+ 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060,
+ 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052,
+ 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045,
+ 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039,
+ 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f,
+ 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026,
+ 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e,
+ 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017,
+ 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011,
+ 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c,
+ 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007,
+ 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004,
+ 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002,
+ 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001,
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
+};
+
+//
+// exp table
+//
+
+static const Bit16u exprom[256] = {
+ 0x7fa, 0x7f5, 0x7ef, 0x7ea, 0x7e4, 0x7df, 0x7da, 0x7d4,
+ 0x7cf, 0x7c9, 0x7c4, 0x7bf, 0x7b9, 0x7b4, 0x7ae, 0x7a9,
+ 0x7a4, 0x79f, 0x799, 0x794, 0x78f, 0x78a, 0x784, 0x77f,
+ 0x77a, 0x775, 0x770, 0x76a, 0x765, 0x760, 0x75b, 0x756,
+ 0x751, 0x74c, 0x747, 0x742, 0x73d, 0x738, 0x733, 0x72e,
+ 0x729, 0x724, 0x71f, 0x71a, 0x715, 0x710, 0x70b, 0x706,
+ 0x702, 0x6fd, 0x6f8, 0x6f3, 0x6ee, 0x6e9, 0x6e5, 0x6e0,
+ 0x6db, 0x6d6, 0x6d2, 0x6cd, 0x6c8, 0x6c4, 0x6bf, 0x6ba,
+ 0x6b5, 0x6b1, 0x6ac, 0x6a8, 0x6a3, 0x69e, 0x69a, 0x695,
+ 0x691, 0x68c, 0x688, 0x683, 0x67f, 0x67a, 0x676, 0x671,
+ 0x66d, 0x668, 0x664, 0x65f, 0x65b, 0x657, 0x652, 0x64e,
+ 0x649, 0x645, 0x641, 0x63c, 0x638, 0x634, 0x630, 0x62b,
+ 0x627, 0x623, 0x61e, 0x61a, 0x616, 0x612, 0x60e, 0x609,
+ 0x605, 0x601, 0x5fd, 0x5f9, 0x5f5, 0x5f0, 0x5ec, 0x5e8,
+ 0x5e4, 0x5e0, 0x5dc, 0x5d8, 0x5d4, 0x5d0, 0x5cc, 0x5c8,
+ 0x5c4, 0x5c0, 0x5bc, 0x5b8, 0x5b4, 0x5b0, 0x5ac, 0x5a8,
+ 0x5a4, 0x5a0, 0x59c, 0x599, 0x595, 0x591, 0x58d, 0x589,
+ 0x585, 0x581, 0x57e, 0x57a, 0x576, 0x572, 0x56f, 0x56b,
+ 0x567, 0x563, 0x560, 0x55c, 0x558, 0x554, 0x551, 0x54d,
+ 0x549, 0x546, 0x542, 0x53e, 0x53b, 0x537, 0x534, 0x530,
+ 0x52c, 0x529, 0x525, 0x522, 0x51e, 0x51b, 0x517, 0x514,
+ 0x510, 0x50c, 0x509, 0x506, 0x502, 0x4ff, 0x4fb, 0x4f8,
+ 0x4f4, 0x4f1, 0x4ed, 0x4ea, 0x4e7, 0x4e3, 0x4e0, 0x4dc,
+ 0x4d9, 0x4d6, 0x4d2, 0x4cf, 0x4cc, 0x4c8, 0x4c5, 0x4c2,
+ 0x4be, 0x4bb, 0x4b8, 0x4b5, 0x4b1, 0x4ae, 0x4ab, 0x4a8,
+ 0x4a4, 0x4a1, 0x49e, 0x49b, 0x498, 0x494, 0x491, 0x48e,
+ 0x48b, 0x488, 0x485, 0x482, 0x47e, 0x47b, 0x478, 0x475,
+ 0x472, 0x46f, 0x46c, 0x469, 0x466, 0x463, 0x460, 0x45d,
+ 0x45a, 0x457, 0x454, 0x451, 0x44e, 0x44b, 0x448, 0x445,
+ 0x442, 0x43f, 0x43c, 0x439, 0x436, 0x433, 0x430, 0x42d,
+ 0x42a, 0x428, 0x425, 0x422, 0x41f, 0x41c, 0x419, 0x416,
+ 0x414, 0x411, 0x40e, 0x40b, 0x408, 0x406, 0x403, 0x400
+};
+
+//
+// freq mult table multiplied by 2
+//
+// 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15
+//
+
+static const Bit8u mt[16] = {
+ 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30
+};
+
+//
+// ksl table
+//
+
+static const Bit8u kslrom[16] = {
+ 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64
+};
+
+static const Bit8u kslshift[4] = {
+ 8, 1, 2, 0
+};
+
+//
+// envelope generator constants
+//
+
+static const Bit8u eg_incstep[4][4] = {
+ { 0, 0, 0, 0 },
+ { 1, 0, 0, 0 },
+ { 1, 0, 1, 0 },
+ { 1, 1, 1, 0 }
+};
+
+//
+// address decoding
+//
+
+static const Bit8s ad_slot[0x20] = {
+ 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1,
+ 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+static const Bit8u ch_slot[18] = {
+ 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32
+};
+
+//
+// Envelope generator
+//
+
+typedef Bit16s(*envelope_sinfunc)(Bit16u phase, Bit16u envelope);
+typedef void(*envelope_genfunc)(opl3_slot *slott);
+
+static Bit16s OPL3_EnvelopeCalcExp(Bit32u level)
+{
+ if (level > 0x1fff)
+ {
+ level = 0x1fff;
+ }
+ return (exprom[level & 0xff] << 1) >> (level >> 8);
+}
+
+static Bit16s OPL3_EnvelopeCalcSin0(Bit16u phase, Bit16u envelope)
+{
+ Bit16u out = 0;
+ Bit16u neg = 0;
+ phase &= 0x3ff;
+ if (phase & 0x200)
+ {
+ neg = 0xffff;
+ }
+ if (phase & 0x100)
+ {
+ out = logsinrom[(phase & 0xff) ^ 0xff];
+ }
+ else
+ {
+ out = logsinrom[phase & 0xff];
+ }
+ return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
+}
+
+static Bit16s OPL3_EnvelopeCalcSin1(Bit16u phase, Bit16u envelope)
+{
+ Bit16u out = 0;
+ phase &= 0x3ff;
+ if (phase & 0x200)
+ {
+ out = 0x1000;
+ }
+ else if (phase & 0x100)
+ {
+ out = logsinrom[(phase & 0xff) ^ 0xff];
+ }
+ else
+ {
+ out = logsinrom[phase & 0xff];
+ }
+ return OPL3_EnvelopeCalcExp(out + (envelope << 3));
+}
+
+static Bit16s OPL3_EnvelopeCalcSin2(Bit16u phase, Bit16u envelope)
+{
+ Bit16u out = 0;
+ phase &= 0x3ff;
+ if (phase & 0x100)
+ {
+ out = logsinrom[(phase & 0xff) ^ 0xff];
+ }
+ else
+ {
+ out = logsinrom[phase & 0xff];
+ }
+ return OPL3_EnvelopeCalcExp(out + (envelope << 3));
+}
+
+static Bit16s OPL3_EnvelopeCalcSin3(Bit16u phase, Bit16u envelope)
+{
+ Bit16u out = 0;
+ phase &= 0x3ff;
+ if (phase & 0x100)
+ {
+ out = 0x1000;
+ }
+ else
+ {
+ out = logsinrom[phase & 0xff];
+ }
+ return OPL3_EnvelopeCalcExp(out + (envelope << 3));
+}
+
+static Bit16s OPL3_EnvelopeCalcSin4(Bit16u phase, Bit16u envelope)
+{
+ Bit16u out = 0;
+ Bit16u neg = 0;
+ phase &= 0x3ff;
+ if ((phase & 0x300) == 0x100)
+ {
+ neg = 0xffff;
+ }
+ if (phase & 0x200)
+ {
+ out = 0x1000;
+ }
+ else if (phase & 0x80)
+ {
+ out = logsinrom[((phase ^ 0xff) << 1) & 0xff];
+ }
+ else
+ {
+ out = logsinrom[(phase << 1) & 0xff];
+ }
+ return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
+}
+
+static Bit16s OPL3_EnvelopeCalcSin5(Bit16u phase, Bit16u envelope)
+{
+ Bit16u out = 0;
+ phase &= 0x3ff;
+ if (phase & 0x200)
+ {
+ out = 0x1000;
+ }
+ else if (phase & 0x80)
+ {
+ out = logsinrom[((phase ^ 0xff) << 1) & 0xff];
+ }
+ else
+ {
+ out = logsinrom[(phase << 1) & 0xff];
+ }
+ return OPL3_EnvelopeCalcExp(out + (envelope << 3));
+}
+
+static Bit16s OPL3_EnvelopeCalcSin6(Bit16u phase, Bit16u envelope)
+{
+ Bit16u neg = 0;
+ phase &= 0x3ff;
+ if (phase & 0x200)
+ {
+ neg = 0xffff;
+ }
+ return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg;
+}
+
+static Bit16s OPL3_EnvelopeCalcSin7(Bit16u phase, Bit16u envelope)
+{
+ Bit16u out = 0;
+ Bit16u neg = 0;
+ phase &= 0x3ff;
+ if (phase & 0x200)
+ {
+ neg = 0xffff;
+ phase = (phase & 0x1ff) ^ 0x1ff;
+ }
+ out = phase << 3;
+ return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg;
+}
+
+static const envelope_sinfunc envelope_sin[8] = {
+ OPL3_EnvelopeCalcSin0,
+ OPL3_EnvelopeCalcSin1,
+ OPL3_EnvelopeCalcSin2,
+ OPL3_EnvelopeCalcSin3,
+ OPL3_EnvelopeCalcSin4,
+ OPL3_EnvelopeCalcSin5,
+ OPL3_EnvelopeCalcSin6,
+ OPL3_EnvelopeCalcSin7
+};
+
+enum envelope_gen_num
+{
+ envelope_gen_num_attack = 0,
+ envelope_gen_num_decay = 1,
+ envelope_gen_num_sustain = 2,
+ envelope_gen_num_release = 3
+};
+
+static void OPL3_EnvelopeUpdateKSL(opl3_slot *slot)
+{
+ Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2)
+ - ((0x08 - slot->channel->block) << 5);
+ if (ksl < 0)
+ {
+ ksl = 0;
+ }
+ slot->eg_ksl = (Bit8u)ksl;
+}
+
+static void OPL3_EnvelopeCalc(opl3_slot *slot)
+{
+ Bit8u nonzero;
+ Bit8u rate;
+ Bit8u rate_hi;
+ Bit8u rate_lo;
+ Bit8u reg_rate = 0;
+ Bit8u ks;
+ Bit8u eg_shift, shift;
+ Bit16u eg_rout;
+ Bit16s eg_inc;
+ Bit8u eg_off;
+ Bit8u reset = 0;
+ slot->eg_out = slot->eg_rout + (slot->reg_tl << 2)
+ + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem;
+ if (slot->key && slot->eg_gen == envelope_gen_num_release)
+ {
+ reset = 1;
+ reg_rate = slot->reg_ar;
+ }
+ else
+ {
+ switch (slot->eg_gen)
+ {
+ case envelope_gen_num_attack:
+ reg_rate = slot->reg_ar;
+ break;
+ case envelope_gen_num_decay:
+ reg_rate = slot->reg_dr;
+ break;
+ case envelope_gen_num_sustain:
+ if (!slot->reg_type)
+ {
+ reg_rate = slot->reg_rr;
+ }
+ break;
+ case envelope_gen_num_release:
+ reg_rate = slot->reg_rr;
+ break;
+ }
+ }
+ slot->pg_reset = reset;
+ ks = slot->channel->ksv >> ((slot->reg_ksr ^ 1) << 1);
+ nonzero = (reg_rate != 0);
+ rate = ks + (reg_rate << 2);
+ rate_hi = rate >> 2;
+ rate_lo = rate & 0x03;
+ if (rate_hi & 0x10)
+ {
+ rate_hi = 0x0f;
+ }
+ eg_shift = rate_hi + slot->chip->eg_add;
+ shift = 0;
+ if (nonzero)
+ {
+ if (rate_hi < 12)
+ {
+ if (slot->chip->eg_state)
+ {
+ switch (eg_shift)
+ {
+ case 12:
+ shift = 1;
+ break;
+ case 13:
+ shift = (rate_lo >> 1) & 0x01;
+ break;
+ case 14:
+ shift = rate_lo & 0x01;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ shift = (rate_hi & 0x03) + eg_incstep[rate_lo][slot->chip->timer & 0x03];
+ if (shift & 0x04)
+ {
+ shift = 0x03;
+ }
+ if (!shift)
+ {
+ shift = slot->chip->eg_state;
+ }
+ }
+ }
+ eg_rout = slot->eg_rout;
+ eg_inc = 0;
+ eg_off = 0;
+ // Instant attack
+ if (reset && rate_hi == 0x0f)
+ {
+ eg_rout = 0x00;
+ }
+ // Envelope off
+ if ((slot->eg_rout & 0x1f8) == 0x1f8)
+ {
+ eg_off = 1;
+ }
+ if (slot->eg_gen != envelope_gen_num_attack && !reset && eg_off)
+ {
+ eg_rout = 0x1ff;
+ }
+ switch (slot->eg_gen)
+ {
+ case envelope_gen_num_attack:
+ if (!slot->eg_rout)
+ {
+ slot->eg_gen = envelope_gen_num_decay;
+ }
+ else if (slot->key && shift > 0 && rate_hi != 0x0f)
+ {
+ eg_inc = ((~slot->eg_rout) << shift) >> 4;
+ }
+ break;
+ case envelope_gen_num_decay:
+ if ((slot->eg_rout >> 4) == slot->reg_sl)
+ {
+ slot->eg_gen = envelope_gen_num_sustain;
+ }
+ else if (!eg_off && !reset && shift > 0)
+ {
+ eg_inc = 1 << (shift - 1);
+ }
+ break;
+ case envelope_gen_num_sustain:
+ case envelope_gen_num_release:
+ if (!eg_off && !reset && shift > 0)
+ {
+ eg_inc = 1 << (shift - 1);
+ }
+ break;
+ }
+ slot->eg_rout = (eg_rout + eg_inc) & 0x1ff;
+ // Key off
+ if (reset)
+ {
+ slot->eg_gen = envelope_gen_num_attack;
+ }
+ if (!slot->key)
+ {
+ slot->eg_gen = envelope_gen_num_release;
+ }
+}
+
+static void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type)
+{
+ slot->key |= type;
+}
+
+static void OPL3_EnvelopeKeyOff(opl3_slot *slot, Bit8u type)
+{
+ slot->key &= ~type;
+}
+
+//
+// Phase Generator
+//
+
+static void OPL3_PhaseGenerate(opl3_slot *slot)
+{
+ opl3_chip *chip;
+ Bit16u f_num;
+ Bit32u basefreq;
+ Bit8u rm_xor, n_bit;
+ Bit32u noise;
+ Bit16u phase;
+
+ chip = slot->chip;
+ f_num = slot->channel->f_num;
+ if (slot->reg_vib)
+ {
+ Bit8s range;
+ Bit8u vibpos;
+
+ range = (f_num >> 7) & 7;
+ vibpos = slot->chip->vibpos;
+
+ if (!(vibpos & 3))
+ {
+ range = 0;
+ }
+ else if (vibpos & 1)
+ {
+ range >>= 1;
+ }
+ range >>= slot->chip->vibshift;
+
+ if (vibpos & 4)
+ {
+ range = -range;
+ }
+ f_num += range;
+ }
+ basefreq = (f_num << slot->channel->block) >> 1;
+ phase = (Bit16u)(slot->pg_phase >> 9);
+ if (slot->pg_reset)
+ {
+ slot->pg_phase = 0;
+ }
+ slot->pg_phase += (basefreq * mt[slot->reg_mult]) >> 1;
+ // Rhythm mode
+ noise = chip->noise;
+ slot->pg_phase_out = phase;
+ if (slot->slot_num == 13) // hh
+ {
+ chip->rm_hh_bit2 = (phase >> 2) & 1;
+ chip->rm_hh_bit3 = (phase >> 3) & 1;
+ chip->rm_hh_bit7 = (phase >> 7) & 1;
+ chip->rm_hh_bit8 = (phase >> 8) & 1;
+ }
+ if (slot->slot_num == 17 && (chip->rhy & 0x20)) // tc
+ {
+ chip->rm_tc_bit3 = (phase >> 3) & 1;
+ chip->rm_tc_bit5 = (phase >> 5) & 1;
+ }
+ if (chip->rhy & 0x20)
+ {
+ rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7)
+ | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5)
+ | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5);
+ switch (slot->slot_num)
+ {
+ case 13: // hh
+ slot->pg_phase_out = rm_xor << 9;
+ if (rm_xor ^ (noise & 1))
+ {
+ slot->pg_phase_out |= 0xd0;
+ }
+ else
+ {
+ slot->pg_phase_out |= 0x34;
+ }
+ break;
+ case 16: // sd
+ slot->pg_phase_out = (chip->rm_hh_bit8 << 9)
+ | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8);
+ break;
+ case 17: // tc
+ slot->pg_phase_out = (rm_xor << 9) | 0x80;
+ break;
+ default:
+ break;
+ }
+ }
+ n_bit = ((noise >> 14) ^ noise) & 0x01;
+ chip->noise = (noise >> 1) | (n_bit << 22);
+}
+
+//
+// Slot
+//
+
+static void OPL3_SlotWrite20(opl3_slot *slot, Bit8u data)
+{
+ if ((data >> 7) & 0x01)
+ {
+ slot->trem = &slot->chip->tremolo;
+ }
+ else
+ {
+ slot->trem = (Bit8u*)&slot->chip->zeromod;
+ }
+ slot->reg_vib = (data >> 6) & 0x01;
+ slot->reg_type = (data >> 5) & 0x01;
+ slot->reg_ksr = (data >> 4) & 0x01;
+ slot->reg_mult = data & 0x0f;
+}
+
+static void OPL3_SlotWrite40(opl3_slot *slot, Bit8u data)
+{
+ slot->reg_ksl = (data >> 6) & 0x03;
+ slot->reg_tl = data & 0x3f;
+ OPL3_EnvelopeUpdateKSL(slot);
+}
+
+static void OPL3_SlotWrite60(opl3_slot *slot, Bit8u data)
+{
+ slot->reg_ar = (data >> 4) & 0x0f;
+ slot->reg_dr = data & 0x0f;
+}
+
+static void OPL3_SlotWrite80(opl3_slot *slot, Bit8u data)
+{
+ slot->reg_sl = (data >> 4) & 0x0f;
+ if (slot->reg_sl == 0x0f)
+ {
+ slot->reg_sl = 0x1f;
+ }
+ slot->reg_rr = data & 0x0f;
+}
+
+static void OPL3_SlotWriteE0(opl3_slot *slot, Bit8u data)
+{
+ slot->reg_wf = data & 0x07;
+ if (slot->chip->newm == 0x00)
+ {
+ slot->reg_wf &= 0x03;
+ }
+}
+
+static void OPL3_SlotGenerate(opl3_slot *slot)
+{
+ slot->out = envelope_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod, slot->eg_out);
+}
+
+static void OPL3_SlotCalcFB(opl3_slot *slot)
+{
+ if (slot->channel->fb != 0x00)
+ {
+ slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb);
+ }
+ else
+ {
+ slot->fbmod = 0;
+ }
+ slot->prout = slot->out;
+}
+
+//
+// Channel
+//
+
+static void OPL3_ChannelSetupAlg(opl3_channel *channel);
+
+static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data)
+{
+ opl3_channel *channel6;
+ opl3_channel *channel7;
+ opl3_channel *channel8;
+ Bit8u chnum;
+
+ chip->rhy = data & 0x3f;
+ if (chip->rhy & 0x20)
+ {
+ channel6 = &chip->channel[6];
+ channel7 = &chip->channel[7];
+ channel8 = &chip->channel[8];
+ channel6->out[0] = &channel6->slots[1]->out;
+ channel6->out[1] = &channel6->slots[1]->out;
+ channel6->out[2] = &chip->zeromod;
+ channel6->out[3] = &chip->zeromod;
+ channel7->out[0] = &channel7->slots[0]->out;
+ channel7->out[1] = &channel7->slots[0]->out;
+ channel7->out[2] = &channel7->slots[1]->out;
+ channel7->out[3] = &channel7->slots[1]->out;
+ channel8->out[0] = &channel8->slots[0]->out;
+ channel8->out[1] = &channel8->slots[0]->out;
+ channel8->out[2] = &channel8->slots[1]->out;
+ channel8->out[3] = &channel8->slots[1]->out;
+ for (chnum = 6; chnum < 9; chnum++)
+ {
+ chip->channel[chnum].chtype = ch_drum;
+ }
+ OPL3_ChannelSetupAlg(channel6);
+ OPL3_ChannelSetupAlg(channel7);
+ OPL3_ChannelSetupAlg(channel8);
+ //hh
+ if (chip->rhy & 0x01)
+ {
+ OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum);
+ }
+ else
+ {
+ OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum);
+ }
+ //tc
+ if (chip->rhy & 0x02)
+ {
+ OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum);
+ }
+ else
+ {
+ OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum);
+ }
+ //tom
+ if (chip->rhy & 0x04)
+ {
+ OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum);
+ }
+ else
+ {
+ OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum);
+ }
+ //sd
+ if (chip->rhy & 0x08)
+ {
+ OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum);
+ }
+ else
+ {
+ OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum);
+ }
+ //bd
+ if (chip->rhy & 0x10)
+ {
+ OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum);
+ }
+ else
+ {
+ OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum);
+ OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum);
+ }
+ }
+ else
+ {
+ for (chnum = 6; chnum < 9; chnum++)
+ {
+ chip->channel[chnum].chtype = ch_2op;
+ OPL3_ChannelSetupAlg(&chip->channel[chnum]);
+ OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum);
+ OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum);
+ }
+ }
+}
+
+static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data)
+{
+ if (channel->chip->newm && channel->chtype == ch_4op2)
+ {
+ return;
+ }
+ channel->f_num = (channel->f_num & 0x300) | data;
+ channel->ksv = (channel->block << 1)
+ | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
+ OPL3_EnvelopeUpdateKSL(channel->slots[0]);
+ OPL3_EnvelopeUpdateKSL(channel->slots[1]);
+ if (channel->chip->newm && channel->chtype == ch_4op)
+ {
+ channel->pair->f_num = channel->f_num;
+ channel->pair->ksv = channel->ksv;
+ OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]);
+ }
+}
+
+static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data)
+{
+ if (channel->chip->newm && channel->chtype == ch_4op2)
+ {
+ return;
+ }
+ channel->f_num = (channel->f_num & 0xff) | ((data & 0x03) << 8);
+ channel->block = (data >> 2) & 0x07;
+ channel->ksv = (channel->block << 1)
+ | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01);
+ OPL3_EnvelopeUpdateKSL(channel->slots[0]);
+ OPL3_EnvelopeUpdateKSL(channel->slots[1]);
+ if (channel->chip->newm && channel->chtype == ch_4op)
+ {
+ channel->pair->f_num = channel->f_num;
+ channel->pair->block = channel->block;
+ channel->pair->ksv = channel->ksv;
+ OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]);
+ OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]);
+ }
+}
+
+static void OPL3_ChannelSetupAlg(opl3_channel *channel)
+{
+ if (channel->chtype == ch_drum)
+ {
+ if (channel->ch_num == 7 || channel->ch_num == 8)
+ {
+ channel->slots[0]->mod = &channel->chip->zeromod;
+ channel->slots[1]->mod = &channel->chip->zeromod;
+ return;
+ }
+ switch (channel->alg & 0x01)
+ {
+ case 0x00:
+ channel->slots[0]->mod = &channel->slots[0]->fbmod;
+ channel->slots[1]->mod = &channel->slots[0]->out;
+ break;
+ case 0x01:
+ channel->slots[0]->mod = &channel->slots[0]->fbmod;
+ channel->slots[1]->mod = &channel->chip->zeromod;
+ break;
+ }
+ return;
+ }
+ if (channel->alg & 0x08)
+ {
+ return;
+ }
+ if (channel->alg & 0x04)
+ {
+ channel->pair->out[0] = &channel->chip->zeromod;
+ channel->pair->out[1] = &channel->chip->zeromod;
+ channel->pair->out[2] = &channel->chip->zeromod;
+ channel->pair->out[3] = &channel->chip->zeromod;
+ switch (channel->alg & 0x03)
+ {
+ case 0x00:
+ channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
+ channel->pair->slots[1]->mod = &channel->pair->slots[0]->out;
+ channel->slots[0]->mod = &channel->pair->slots[1]->out;
+ channel->slots[1]->mod = &channel->slots[0]->out;
+ channel->out[0] = &channel->slots[1]->out;
+ channel->out[1] = &channel->chip->zeromod;
+ channel->out[2] = &channel->chip->zeromod;
+ channel->out[3] = &channel->chip->zeromod;
+ break;
+ case 0x01:
+ channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
+ channel->pair->slots[1]->mod = &channel->pair->slots[0]->out;
+ channel->slots[0]->mod = &channel->chip->zeromod;
+ channel->slots[1]->mod = &channel->slots[0]->out;
+ channel->out[0] = &channel->pair->slots[1]->out;
+ channel->out[1] = &channel->slots[1]->out;
+ channel->out[2] = &channel->chip->zeromod;
+ channel->out[3] = &channel->chip->zeromod;
+ break;
+ case 0x02:
+ channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
+ channel->pair->slots[1]->mod = &channel->chip->zeromod;
+ channel->slots[0]->mod = &channel->pair->slots[1]->out;
+ channel->slots[1]->mod = &channel->slots[0]->out;
+ channel->out[0] = &channel->pair->slots[0]->out;
+ channel->out[1] = &channel->slots[1]->out;
+ channel->out[2] = &channel->chip->zeromod;
+ channel->out[3] = &channel->chip->zeromod;
+ break;
+ case 0x03:
+ channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod;
+ channel->pair->slots[1]->mod = &channel->chip->zeromod;
+ channel->slots[0]->mod = &channel->pair->slots[1]->out;
+ channel->slots[1]->mod = &channel->chip->zeromod;
+ channel->out[0] = &channel->pair->slots[0]->out;
+ channel->out[1] = &channel->slots[0]->out;
+ channel->out[2] = &channel->slots[1]->out;
+ channel->out[3] = &channel->chip->zeromod;
+ break;
+ }
+ }
+ else
+ {
+ switch (channel->alg & 0x01)
+ {
+ case 0x00:
+ channel->slots[0]->mod = &channel->slots[0]->fbmod;
+ channel->slots[1]->mod = &channel->slots[0]->out;
+ channel->out[0] = &channel->slots[1]->out;
+ channel->out[1] = &channel->chip->zeromod;
+ channel->out[2] = &channel->chip->zeromod;
+ channel->out[3] = &channel->chip->zeromod;
+ break;
+ case 0x01:
+ channel->slots[0]->mod = &channel->slots[0]->fbmod;
+ channel->slots[1]->mod = &channel->chip->zeromod;
+ channel->out[0] = &channel->slots[0]->out;
+ channel->out[1] = &channel->slots[1]->out;
+ channel->out[2] = &channel->chip->zeromod;
+ channel->out[3] = &channel->chip->zeromod;
+ break;
+ }
+ }
+}
+
+static void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data)
+{
+ channel->fb = (data & 0x0e) >> 1;
+ channel->con = data & 0x01;
+ channel->alg = channel->con;
+ if (channel->chip->newm)
+ {
+ if (channel->chtype == ch_4op)
+ {
+ channel->pair->alg = 0x04 | (channel->con << 1) | (channel->pair->con);
+ channel->alg = 0x08;
+ OPL3_ChannelSetupAlg(channel->pair);
+ }
+ else if (channel->chtype == ch_4op2)
+ {
+ channel->alg = 0x04 | (channel->pair->con << 1) | (channel->con);
+ channel->pair->alg = 0x08;
+ OPL3_ChannelSetupAlg(channel);
+ }
+ else
+ {
+ OPL3_ChannelSetupAlg(channel);
+ }
+ }
+ else
+ {
+ OPL3_ChannelSetupAlg(channel);
+ }
+ if (channel->chip->newm)
+ {
+ channel->cha = ((data >> 4) & 0x01) ? ~0 : 0;
+ channel->chb = ((data >> 5) & 0x01) ? ~0 : 0;
+ }
+ else
+ {
+ channel->cha = channel->chb = (Bit16u)~0;
+ }
+}
+
+static void OPL3_ChannelKeyOn(opl3_channel *channel)
+{
+ if (channel->chip->newm)
+ {
+ if (channel->chtype == ch_4op)
+ {
+ OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm);
+ }
+ else if (channel->chtype == ch_2op || channel->chtype == ch_drum)
+ {
+ OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
+ }
+ }
+ else
+ {
+ OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm);
+ OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm);
+ }
+}
+
+static void OPL3_ChannelKeyOff(opl3_channel *channel)
+{
+ if (channel->chip->newm)
+ {
+ if (channel->chtype == ch_4op)
+ {
+ OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm);
+ }
+ else if (channel->chtype == ch_2op || channel->chtype == ch_drum)
+ {
+ OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
+ }
+ }
+ else
+ {
+ OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm);
+ OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm);
+ }
+}
+
+static void OPL3_ChannelSet4Op(opl3_chip *chip, Bit8u data)
+{
+ Bit8u bit;
+ Bit8u chnum;
+ for (bit = 0; bit < 6; bit++)
+ {
+ chnum = bit;
+ if (bit >= 3)
+ {
+ chnum += 9 - 3;
+ }
+ if ((data >> bit) & 0x01)
+ {
+ chip->channel[chnum].chtype = ch_4op;
+ chip->channel[chnum + 3].chtype = ch_4op2;
+ }
+ else
+ {
+ chip->channel[chnum].chtype = ch_2op;
+ chip->channel[chnum + 3].chtype = ch_2op;
+ }
+ }
+}
+
+static Bit16s OPL3_ClipSample(Bit32s sample)
+{
+ if (sample > 32767)
+ {
+ sample = 32767;
+ }
+ else if (sample < -32768)
+ {
+ sample = -32768;
+ }
+ return (Bit16s)sample;
+}
+
+void OPL3_Generate(opl3_chip *chip, Bit16s *buf)
+{
+ Bit8u ii;
+ Bit8u jj;
+ Bit16s accm;
+ Bit8u shift = 0;
+
+ buf[1] = OPL3_ClipSample(chip->mixbuff[1]);
+
+ for (ii = 0; ii < 15; ii++)
+ {
+ OPL3_SlotCalcFB(&chip->slot[ii]);
+ OPL3_EnvelopeCalc(&chip->slot[ii]);
+ OPL3_PhaseGenerate(&chip->slot[ii]);
+ OPL3_SlotGenerate(&chip->slot[ii]);
+ }
+
+ chip->mixbuff[0] = 0;
+ for (ii = 0; ii < 18; ii++)
+ {
+ accm = 0;
+ for (jj = 0; jj < 4; jj++)
+ {
+ accm += *chip->channel[ii].out[jj];
+ }
+ chip->mixbuff[0] += (Bit16s)(accm & chip->channel[ii].cha);
+ }
+
+ for (ii = 15; ii < 18; ii++)
+ {
+ OPL3_SlotCalcFB(&chip->slot[ii]);
+ OPL3_EnvelopeCalc(&chip->slot[ii]);
+ OPL3_PhaseGenerate(&chip->slot[ii]);
+ OPL3_SlotGenerate(&chip->slot[ii]);
+ }
+
+ buf[0] = OPL3_ClipSample(chip->mixbuff[0]);
+
+ for (ii = 18; ii < 33; ii++)
+ {
+ OPL3_SlotCalcFB(&chip->slot[ii]);
+ OPL3_EnvelopeCalc(&chip->slot[ii]);
+ OPL3_PhaseGenerate(&chip->slot[ii]);
+ OPL3_SlotGenerate(&chip->slot[ii]);
+ }
+
+ chip->mixbuff[1] = 0;
+ for (ii = 0; ii < 18; ii++)
+ {
+ accm = 0;
+ for (jj = 0; jj < 4; jj++)
+ {
+ accm += *chip->channel[ii].out[jj];
+ }
+ chip->mixbuff[1] += (Bit16s)(accm & chip->channel[ii].chb);
+ }
+
+ for (ii = 33; ii < 36; ii++)
+ {
+ OPL3_SlotCalcFB(&chip->slot[ii]);
+ OPL3_EnvelopeCalc(&chip->slot[ii]);
+ OPL3_PhaseGenerate(&chip->slot[ii]);
+ OPL3_SlotGenerate(&chip->slot[ii]);
+ }
+
+ if ((chip->timer & 0x3f) == 0x3f)
+ {
+ chip->tremolopos = (chip->tremolopos + 1) % 210;
+ }
+ if (chip->tremolopos < 105)
+ {
+ chip->tremolo = chip->tremolopos >> chip->tremoloshift;
+ }
+ else
+ {
+ chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift;
+ }
+
+ if ((chip->timer & 0x3ff) == 0x3ff)
+ {
+ chip->vibpos = (chip->vibpos + 1) & 7;
+ }
+
+ chip->timer++;
+
+ chip->eg_add = 0;
+ if (chip->eg_timer)
+ {
+ while (shift < 36 && ((chip->eg_timer >> shift) & 1) == 0)
+ {
+ shift++;
+ }
+ if (shift > 12)
+ {
+ chip->eg_add = 0;
+ }
+ else
+ {
+ chip->eg_add = shift + 1;
+ }
+ }
+
+ if (chip->eg_timerrem || chip->eg_state)
+ {
+ if (chip->eg_timer == 0xfffffffffULL)
+ {
+ chip->eg_timer = 0;
+ chip->eg_timerrem = 1;
+ }
+ else
+ {
+ chip->eg_timer++;
+ chip->eg_timerrem = 0;
+ }
+ }
+
+ chip->eg_state ^= 1;
+
+ while (chip->writebuf[chip->writebuf_cur].time <= chip->writebuf_samplecnt)
+ {
+ if (!(chip->writebuf[chip->writebuf_cur].reg & 0x200))
+ {
+ break;
+ }
+ chip->writebuf[chip->writebuf_cur].reg &= 0x1ff;
+ OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_cur].reg,
+ chip->writebuf[chip->writebuf_cur].data);
+ chip->writebuf_cur = (chip->writebuf_cur + 1) % OPL_WRITEBUF_SIZE;
+ }
+ chip->writebuf_samplecnt++;
+}
+
+void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf)
+{
+ while (chip->samplecnt >= chip->rateratio)
+ {
+ chip->oldsamples[0] = chip->samples[0];
+ chip->oldsamples[1] = chip->samples[1];
+ OPL3_Generate(chip, chip->samples);
+ chip->samplecnt -= chip->rateratio;
+ }
+ buf[0] = (Bit16s)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt)
+ + chip->samples[0] * chip->samplecnt) / chip->rateratio);
+ buf[1] = (Bit16s)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt)
+ + chip->samples[1] * chip->samplecnt) / chip->rateratio);
+ chip->samplecnt += 1 << RSM_FRAC;
+}
+
+void OPL3_Reset(opl3_chip *chip, Bit32u samplerate)
+{
+ Bit8u slotnum;
+ Bit8u channum;
+
+ memset(chip, 0, sizeof(opl3_chip));
+ for (slotnum = 0; slotnum < 36; slotnum++)
+ {
+ chip->slot[slotnum].chip = chip;
+ chip->slot[slotnum].mod = &chip->zeromod;
+ chip->slot[slotnum].eg_rout = 0x1ff;
+ chip->slot[slotnum].eg_out = 0x1ff;
+ chip->slot[slotnum].eg_gen = envelope_gen_num_release;
+ chip->slot[slotnum].trem = (Bit8u*)&chip->zeromod;
+ chip->slot[slotnum].slot_num = slotnum;
+ }
+ for (channum = 0; channum < 18; channum++)
+ {
+ chip->channel[channum].slots[0] = &chip->slot[ch_slot[channum]];
+ chip->channel[channum].slots[1] = &chip->slot[ch_slot[channum] + 3];
+ chip->slot[ch_slot[channum]].channel = &chip->channel[channum];
+ chip->slot[ch_slot[channum] + 3].channel = &chip->channel[channum];
+ if ((channum % 9) < 3)
+ {
+ chip->channel[channum].pair = &chip->channel[channum + 3];
+ }
+ else if ((channum % 9) < 6)
+ {
+ chip->channel[channum].pair = &chip->channel[channum - 3];
+ }
+ chip->channel[channum].chip = chip;
+ chip->channel[channum].out[0] = &chip->zeromod;
+ chip->channel[channum].out[1] = &chip->zeromod;
+ chip->channel[channum].out[2] = &chip->zeromod;
+ chip->channel[channum].out[3] = &chip->zeromod;
+ chip->channel[channum].chtype = ch_2op;
+ chip->channel[channum].cha = 0xffff;
+ chip->channel[channum].chb = 0xffff;
+ chip->channel[channum].ch_num = channum;
+ OPL3_ChannelSetupAlg(&chip->channel[channum]);
+ }
+ chip->noise = 1;
+ chip->rateratio = (samplerate << RSM_FRAC) / 49716;
+ chip->tremoloshift = 4;
+ chip->vibshift = 1;
+}
+
+void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v)
+{
+ Bit8u high = (reg >> 8) & 0x01;
+ Bit8u regm = reg & 0xff;
+ switch (regm & 0xf0)
+ {
+ case 0x00:
+ if (high)
+ {
+ switch (regm & 0x0f)
+ {
+ case 0x04:
+ OPL3_ChannelSet4Op(chip, v);
+ break;
+ case 0x05:
+ chip->newm = v & 0x01;
+ break;
+ }
+ }
+ else
+ {
+ switch (regm & 0x0f)
+ {
+ case 0x08:
+ chip->nts = (v >> 6) & 0x01;
+ break;
+ }
+ }
+ break;
+ case 0x20:
+ case 0x30:
+ if (ad_slot[regm & 0x1f] >= 0)
+ {
+ OPL3_SlotWrite20(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v);
+ }
+ break;
+ case 0x40:
+ case 0x50:
+ if (ad_slot[regm & 0x1f] >= 0)
+ {
+ OPL3_SlotWrite40(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v);
+ }
+ break;
+ case 0x60:
+ case 0x70:
+ if (ad_slot[regm & 0x1f] >= 0)
+ {
+ OPL3_SlotWrite60(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v);
+ }
+ break;
+ case 0x80:
+ case 0x90:
+ if (ad_slot[regm & 0x1f] >= 0)
+ {
+ OPL3_SlotWrite80(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v);
+ }
+ break;
+ case 0xe0:
+ case 0xf0:
+ if (ad_slot[regm & 0x1f] >= 0)
+ {
+ OPL3_SlotWriteE0(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v);
+ }
+ break;
+ case 0xa0:
+ if ((regm & 0x0f) < 9)
+ {
+ OPL3_ChannelWriteA0(&chip->channel[9 * high + (regm & 0x0f)], v);
+ }
+ break;
+ case 0xb0:
+ if (regm == 0xbd && !high)
+ {
+ chip->tremoloshift = (((v >> 7) ^ 1) << 1) + 2;
+ chip->vibshift = ((v >> 6) & 0x01) ^ 1;
+ OPL3_ChannelUpdateRhythm(chip, v);
+ }
+ else if ((regm & 0x0f) < 9)
+ {
+ OPL3_ChannelWriteB0(&chip->channel[9 * high + (regm & 0x0f)], v);
+ if (v & 0x20)
+ {
+ OPL3_ChannelKeyOn(&chip->channel[9 * high + (regm & 0x0f)]);
+ }
+ else
+ {
+ OPL3_ChannelKeyOff(&chip->channel[9 * high + (regm & 0x0f)]);
+ }
+ }
+ break;
+ case 0xc0:
+ if ((regm & 0x0f) < 9)
+ {
+ OPL3_ChannelWriteC0(&chip->channel[9 * high + (regm & 0x0f)], v);
+ }
+ break;
+ }
+}
+
+void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v)
+{
+ Bit64u time1, time2;
+
+ if (chip->writebuf[chip->writebuf_last].reg & 0x200)
+ {
+ OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_last].reg & 0x1ff,
+ chip->writebuf[chip->writebuf_last].data);
+
+ chip->writebuf_cur = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE;
+ chip->writebuf_samplecnt = chip->writebuf[chip->writebuf_last].time;
+ }
+
+ chip->writebuf[chip->writebuf_last].reg = reg | 0x200;
+ chip->writebuf[chip->writebuf_last].data = v;
+ time1 = chip->writebuf_lasttime + OPL_WRITEBUF_DELAY;
+ time2 = chip->writebuf_samplecnt;
+
+ if (time1 < time2)
+ {
+ time1 = time2;
+ }
+
+ chip->writebuf[chip->writebuf_last].time = time1;
+ chip->writebuf_lasttime = time1;
+ chip->writebuf_last = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE;
+}
+
+void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples)
+{
+ Bit32u i;
+
+ for(i = 0; i < numsamples; i++)
+ {
+ OPL3_GenerateResampled(chip, sndptr);
+ sndptr += 2;
+ }
+}
+
+OPL::OPL(Config::OplType type) : _type(type), _rate(0) {
+}
+
+OPL::~OPL() {
+ stop();
+}
+
+bool OPL::init() {
+ _rate = g_system->getMixer()->getOutputRate();
+ OPL3_Reset(&chip, _rate);
+
+ if (_type == Config::kDualOpl2) {
+ OPL3_WriteReg(&chip, 0x105, 0x01);
+ }
+
+ return true;
+}
+
+void OPL::reset() {
+ OPL3_Reset(&chip, _rate);
+}
+
+void OPL::write(int port, int val) {
+ if (port & 1) {
+ switch (_type) {
+ case Config::kOpl2:
+ case Config::kOpl3:
+ OPL3_WriteRegBuffered(&chip, (Bit16u)address[0], (Bit8u)val);
+ break;
+ case Config::kDualOpl2:
+ // Not a 0x??8 port, then write to a specific port
+ if (!(port & 0x8)) {
+ byte index = (port & 2) >> 1;
+ dualWrite(index, address[index], val);
+ }
+ else {
+ //Write to both ports
+ dualWrite(0, address[0], val);
+ dualWrite(1, address[1], val);
+ }
+ break;
+ }
+ } else {
+ switch (_type) {
+ case Config::kOpl2:
+ address[0] = val & 0xff;
+ break;
+ case Config::kDualOpl2:
+ // Not a 0x?88 port, when write to a specific side
+ if (!(port & 0x8)) {
+ byte index = (port & 2) >> 1;
+ address[index] = val & 0xff;
+ }
+ else {
+ address[0] = val & 0xff;
+ address[1] = val & 0xff;
+ }
+ break;
+ case Config::kOpl3:
+ address[0] = (val & 0xff) | ((port << 7) & 0x100);
+ break;
+ }
+ }
+}
+
+
+void OPL::writeReg(int r, int v) {
+ OPL3_WriteRegBuffered(&chip, (Bit16u)r, (Bit8u)v);
+}
+
+void OPL::dualWrite(uint8 index, uint8 reg, uint8 val) {
+ // Make sure you don't use opl3 features
+ // Don't allow write to disable opl3
+ if (reg == 5)
+ return;
+
+ // Only allow 4 waveforms
+ if (reg >= 0xE0 && reg <= 0xE8)
+ val &= 3;
+
+ // Enabling panning
+ if (reg >= 0xC0 && reg <= 0xC8) {
+ val &= 15;
+ val |= index ? 0xA0 : 0x50;
+ }
+
+ uint32 fullReg = reg + (index ? 0x100 : 0);
+ OPL3_WriteRegBuffered(&chip, (Bit16u)fullReg, (Bit8u)val);
+}
+
+byte OPL::read(int port) {
+ port = 0;
+ return 0;
+}
+
+void OPL::generateSamples(int16*buffer, int length) {
+ OPL3_GenerateStream(&chip, (Bit16s*)buffer, (Bit16u)length / 2);
+}
+
+}
+}
+
+#endif // !DISABLE_NUKED_OPL
diff --git a/audio/softsynth/opl/nuked.h b/audio/softsynth/opl/nuked.h
new file mode 100644
index 0000000000..3326add7bf
--- /dev/null
+++ b/audio/softsynth/opl/nuked.h
@@ -0,0 +1,188 @@
+//
+// Copyright (C) 2013-2018 Alexey Khokholov (Nuke.YKT)
+//
+// 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.
+//
+//
+// Nuked OPL3 emulator.
+// Thanks:
+// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh):
+// Feedback and Rhythm part calculation information.
+// forums.submarine.org.uk(carbon14, opl3):
+// Tremolo and phase generator calculation information.
+// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
+// OPL2 ROMs.
+// siliconpr0n.org(John McMaster, digshadow):
+// YMF262 and VRC VII decaps and die shots.
+//
+// version: 1.8
+//
+
+#ifndef AUDIO_SOFTSYNTH_OPL_NUKED_H
+#define AUDIO_SOFTSYNTH_OPL_NUKED_H
+
+#include "common/scummsys.h"
+#include "audio/fmopl.h"
+
+#ifndef DISABLE_NUKED_OPL
+
+#define OPL_WRITEBUF_SIZE 1024
+#define OPL_WRITEBUF_DELAY 2
+
+namespace OPL {
+namespace NUKED {
+
+typedef uint Bitu;
+typedef int Bits;
+typedef uint64 Bit64u;
+typedef int64 Bit64s;
+typedef uint32 Bit32u;
+typedef int32 Bit32s;
+typedef uint16 Bit16u;
+typedef int16 Bit16s;
+typedef uint8 Bit8u;
+typedef int8 Bit8s;
+
+typedef struct _opl3_slot opl3_slot;
+typedef struct _opl3_channel opl3_channel;
+typedef struct _opl3_chip opl3_chip;
+
+struct _opl3_slot {
+ opl3_channel *channel;
+ opl3_chip *chip;
+ Bit16s out;
+ Bit16s fbmod;
+ Bit16s *mod;
+ Bit16s prout;
+ Bit16s eg_rout;
+ Bit16s eg_out;
+ Bit8u eg_inc;
+ Bit8u eg_gen;
+ Bit8u eg_rate;
+ Bit8u eg_ksl;
+ Bit8u *trem;
+ Bit8u reg_vib;
+ Bit8u reg_type;
+ Bit8u reg_ksr;
+ Bit8u reg_mult;
+ Bit8u reg_ksl;
+ Bit8u reg_tl;
+ Bit8u reg_ar;
+ Bit8u reg_dr;
+ Bit8u reg_sl;
+ Bit8u reg_rr;
+ Bit8u reg_wf;
+ Bit8u key;
+ Bit32u pg_reset;
+ Bit32u pg_phase;
+ Bit16u pg_phase_out;
+ Bit8u slot_num;
+};
+
+struct _opl3_channel {
+ opl3_slot *slots[2];
+ opl3_channel *pair;
+ opl3_chip *chip;
+ Bit16s *out[4];
+ Bit8u chtype;
+ Bit16u f_num;
+ Bit8u block;
+ Bit8u fb;
+ Bit8u con;
+ Bit8u alg;
+ Bit8u ksv;
+ Bit16u cha, chb;
+ Bit8u ch_num;
+};
+
+typedef struct _opl3_writebuf {
+ Bit64u time;
+ Bit16u reg;
+ Bit8u data;
+} opl3_writebuf;
+
+struct _opl3_chip {
+ opl3_channel channel[18];
+ opl3_slot slot[36];
+ Bit16u timer;
+ Bit64u eg_timer;
+ Bit8u eg_timerrem;
+ Bit8u eg_state;
+ Bit8u eg_add;
+ Bit8u newm;
+ Bit8u nts;
+ Bit8u rhy;
+ Bit8u vibpos;
+ Bit8u vibshift;
+ Bit8u tremolo;
+ Bit8u tremolopos;
+ Bit8u tremoloshift;
+ Bit32u noise;
+ Bit16s zeromod;
+ Bit32s mixbuff[2];
+ Bit8u rm_hh_bit2;
+ Bit8u rm_hh_bit3;
+ Bit8u rm_hh_bit7;
+ Bit8u rm_hh_bit8;
+ Bit8u rm_tc_bit3;
+ Bit8u rm_tc_bit5;
+ //OPL3L
+ Bit32s rateratio;
+ Bit32s samplecnt;
+ Bit16s oldsamples[2];
+ Bit16s samples[2];
+
+ Bit64u writebuf_samplecnt;
+ Bit32u writebuf_cur;
+ Bit32u writebuf_last;
+ Bit64u writebuf_lasttime;
+ opl3_writebuf writebuf[OPL_WRITEBUF_SIZE];
+};
+
+void OPL3_Generate(opl3_chip *chip, Bit16s *buf);
+void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf);
+void OPL3_Reset(opl3_chip *chip, Bit32u samplerate);
+void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v);
+void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v);
+void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples);
+
+class OPL : public ::OPL::EmulatedOPL {
+private:
+ Config::OplType _type;
+ uint _rate;
+ opl3_chip chip;
+ uint address[2];
+ void dualWrite(uint8 index, uint8 reg, uint8 val);
+
+public:
+ OPL(Config::OplType type);
+ ~OPL();
+
+ bool init();
+ void reset();
+
+ void write(int a, int v);
+ byte read(int a);
+
+ void writeReg(int r, int v);
+
+ bool isStereo() const { return true; }
+
+protected:
+ void generateSamples(int16 *buffer, int length);
+};
+
+}
+}
+
+#endif // !DISABLE_NUKED_OPL
+
+#endif
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 1ea97a6350..6c4774554c 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -29,6 +29,7 @@
#include "backends/graphics/graphics.h"
#include "common/config-manager.h"
#include "common/textconsole.h"
+#include "common/fs.h"
// FIXME move joystick defines out and replace with confile file options
// we should really allow users to map any key to a joystick button
@@ -43,8 +44,14 @@
#define JOY_BUT_PERIOD 1
#define JOY_BUT_SPACE 4
#define JOY_BUT_F5 5
+#ifdef ENABLE_VKEYBD
+#define JOY_BUT_VKEYBOARD 7
+#endif
+
#if SDL_VERSION_ATLEAST(2, 0, 0)
+#define GAMECONTROLLERDB_FILE "gamecontrollerdb.txt"
+
static uint32 convUTF8ToUTF32(const char *src) {
uint32 utf32 = 0;
@@ -63,6 +70,32 @@ static uint32 convUTF8ToUTF32(const char *src) {
return utf32;
}
+
+void SdlEventSource::loadGameControllerMappingFile() {
+ bool loaded = false;
+ if (ConfMan.hasKey("controller_map_db")) {
+ Common::FSNode file = Common::FSNode(ConfMan.get("controller_map_db"));
+ if (file.exists()) {
+ if (SDL_GameControllerAddMappingsFromFile(file.getPath().c_str()) < 0)
+ error("File %s not valid: %s", file.getPath().c_str(), SDL_GetError());
+ else {
+ loaded = true;
+ debug("Game controller DB file loaded: %s", file.getPath().c_str());
+ }
+ } else
+ warning("Game controller DB file not found: %s", file.getPath().c_str());
+ }
+ if (!loaded && ConfMan.hasKey("extrapath")) {
+ Common::FSNode dir = Common::FSNode(ConfMan.get("extrapath"));
+ Common::FSNode file = dir.getChild(GAMECONTROLLERDB_FILE);
+ if (file.exists()) {
+ if (SDL_GameControllerAddMappingsFromFile(file.getPath().c_str()) < 0)
+ error("File %s not valid: %s", file.getPath().c_str(), SDL_GetError());
+ else
+ debug("Game controller DB file loaded: %s", file.getPath().c_str());
+ }
+ }
+}
#endif
SdlEventSource::SdlEventSource()
@@ -85,6 +118,7 @@ SdlEventSource::SdlEventSource()
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == -1) {
error("Could not initialize SDL: %s", SDL_GetError());
}
+ loadGameControllerMappingFile();
#endif
openJoystick(joystick_num);
@@ -876,6 +910,11 @@ bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
event.kbd.keycode = Common::KEYCODE_F5;
event.kbd.ascii = mapKey(SDLK_F5, (SDLMod)ev.key.keysym.mod, 0);
break;
+#ifdef ENABLE_VKEYBD
+ case JOY_BUT_VKEYBOARD: // Toggles virtual keyboard
+ event.type = Common::EVENT_VIRTUAL_KEYBOARD;
+ break;
+#endif
}
return true;
}
@@ -907,6 +946,11 @@ bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
event.kbd.keycode = Common::KEYCODE_F5;
event.kbd.ascii = mapKey(SDLK_F5, (SDLMod)ev.key.keysym.mod, 0);
break;
+#ifdef ENABLE_VKEYBD
+ case JOY_BUT_VKEYBOARD: // Toggles virtual keyboard
+ // Handled in key down
+ break;
+#endif
}
return true;
}
diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h
index 2899b584af..b26d4cc6bd 100644
--- a/backends/events/sdl/sdl-events.h
+++ b/backends/events/sdl/sdl-events.h
@@ -94,6 +94,11 @@ protected:
SdlGraphicsManager *_graphicsManager;
/**
+ * Search for a game controller db file and load it.
+ */
+ void loadGameControllerMappingFile();
+
+ /**
* Open the SDL joystick with the specified index
*
* After this function completes successfully, SDL sends events for the device.
diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp
index 09ba3a1c83..134193a65b 100644
--- a/backends/fs/amigaos4/amigaos4-fs.cpp
+++ b/backends/fs/amigaos4/amigaos4-fs.cpp
@@ -266,7 +266,7 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
if (context) {
struct ExamineData * pExd = NULL; // NB: No need to free the value after usage, everything will be dealt with by the DirContext release
- AmigaOSFilesystemNode *entry ;
+ AmigaOSFilesystemNode *entry;
while ( (pExd = IDOS->ExamineDir(context)) ) {
if ( (EXD_IS_FILE(pExd) && ( Common::FSNode::kListFilesOnly == mode ))
|| (EXD_IS_DIRECTORY(pExd) && ( Common::FSNode::kListDirectoriesOnly == mode ))
diff --git a/backends/fs/ds/ds-fs-factory.cpp b/backends/fs/ds/ds-fs-factory.cpp
index 98c522f1d6..3ec4a40bd8 100644
--- a/backends/fs/ds/ds-fs-factory.cpp
+++ b/backends/fs/ds/ds-fs-factory.cpp
@@ -24,9 +24,9 @@
#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
#if defined(__DS__)
+#include "dsmain.h" //for the isGBAMPAvailable() function
#include "backends/fs/ds/ds-fs-factory.h"
#include "backends/fs/ds/ds-fs.h"
-#include "dsmain.h" //for the isGBAMPAvailable() function
namespace Common {
DECLARE_SINGLETON(DSFilesystemFactory);
diff --git a/backends/fs/ds/ds-fs.cpp b/backends/fs/ds/ds-fs.cpp
index 035178dbb4..1df54a983d 100644
--- a/backends/fs/ds/ds-fs.cpp
+++ b/backends/fs/ds/ds-fs.cpp
@@ -23,12 +23,12 @@
// Disable symbol overrides for FILE as that is used in FLAC headers
#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
+#include "dsmain.h"
#include "common/str.h"
#include "common/util.h"
//#include <NDS/ARM9/console.h> //basic print funcionality
#include "backends/fs/ds/ds-fs.h"
#include "backends/fs/stdiostream.h"
-#include "dsmain.h"
#include "fat/gba_nds_fat.h"
#include "common/bufferedstream.h"
diff --git a/backends/platform/dc/dc-fs.cpp b/backends/platform/dc/dc-fs.cpp
index 1cc7b56710..a4d2675080 100644
--- a/backends/platform/dc/dc-fs.cpp
+++ b/backends/platform/dc/dc-fs.cpp
@@ -167,5 +167,5 @@ AbstractFSNode *OSystem_Dreamcast::makeCurrentDirectoryFileNode() const {
AbstractFSNode *OSystem_Dreamcast::makeFileNodePath(const Common::String &path) const {
AbstractFSNode *node = RoninCDFileNode::makeFileNodePath(path);
- return (node? node : new RoninCDNonexistingNode(path));
+ return (node ? node : new RoninCDNonexistingNode(path));
}
diff --git a/backends/platform/ds/arm7/source/main.cpp b/backends/platform/ds/arm7/source/main.cpp
index c4a22b8f68..617a1edc87 100644
--- a/backends/platform/ds/arm7/source/main.cpp
+++ b/backends/platform/ds/arm7/source/main.cpp
@@ -26,7 +26,7 @@
// -- modified by Darkain and others
//////////////////////////////////////////////////////////////////////
-//#define USE_LIBCARTRESET
+// #define USE_LIBCARTRESET
#include <nds.h>
@@ -37,7 +37,7 @@
#include <system.h>
#include <stdlib.h>
#include <string.h>
-#include <registers_alt.h> // Needed for SOUND_CR
+#include <registers_alt.h> // Needed for SOUND_CR
#include <NDS/scummvm_ipc.h>
//////////////////////////////////////////////////////////////////////
#ifdef USE_DEBUGGER
@@ -54,8 +54,8 @@
#define SCREEN_HEIGHT 192
s32 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
s32 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
-s32 TOUCH_OFFSET_X = ( ((SCREEN_WIDTH -60) * TOUCH_CAL_X1) / TOUCH_WIDTH ) - 28;
-s32 TOUCH_OFFSET_Y = ( ((SCREEN_HEIGHT-60) * TOUCH_CAL_Y1) / TOUCH_HEIGHT ) - 28;
+s32 TOUCH_OFFSET_X = ( ((SCREEN_WIDTH - 60) * TOUCH_CAL_X1) / TOUCH_WIDTH ) - 28;
+s32 TOUCH_OFFSET_Y = ( ((SCREEN_HEIGHT - 60) * TOUCH_CAL_Y1) / TOUCH_HEIGHT ) - 28;
vu8 *soundData;
@@ -71,163 +71,157 @@ int temp;
int adpcmBufferNum = 0;
// those are pixel positions of the two points you click when calibrating
-#define TOUCH_CNTRL_X1 (*(vu8 *)0x027FFCDC)
-#define TOUCH_CNTRL_Y1 (*(vu8 *)0x027FFCDD)
-#define TOUCH_CNTRL_X2 (*(vu8 *)0x027FFCE2)
-#define TOUCH_CNTRL_Y2 (*(vu8 *)0x027FFCE3)
-
-
-//////////////////////////////////////////////////////////////////////
+#define TOUCH_CNTRL_X1 (*(vu8 *)0x027FFCDC)
+#define TOUCH_CNTRL_Y1 (*(vu8 *)0x027FFCDD)
+#define TOUCH_CNTRL_X2 (*(vu8 *)0x027FFCE2)
+#define TOUCH_CNTRL_Y2 (*(vu8 *)0x027FFCE3)
/*
-void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel=0, u8 vol=0x7F, u8 pan=63, u8 format=0) {
- SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
- SCHANNEL_SOURCE(channel) = (uint32)data;
- SCHANNEL_LENGTH(channel) = bytes;
- SCHANNEL_CR(channel) = SOUND_ENABLE | SOUND_ONE_SHOT | SOUND_VOL(vol) | SOUND_PAN(pan) | (format==1?SOUND_8BIT:SOUND_16BIT);
+void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0, u8 vol = 0x7F, u8 pan = 63, u8 format = 0) {
+ SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel) = (uint32)data;
+ SCHANNEL_LENGTH(channel) = bytes;
+ SCHANNEL_CR(channel) = SOUND_ENABLE | SOUND_ONE_SHOT | SOUND_VOL(vol) | SOUND_PAN(pan) | (format==1?SOUND_8BIT:SOUND_16BIT);
}
-
s8 getFreeSoundChannel() {
- for (int i=0; i<16; i++) {
- if ( (SCHANNEL_CR(i) & SOUND_ENABLE) == 0 ) return i;
- }
- return -1;
+ for (int i = 0; i < 16; i++) {
+ if ( (SCHANNEL_CR(i) & SOUND_ENABLE) == 0 )
+ return i;
+ }
+ return -1;
}
*/
-
s8 getFreeSoundChannel() {
-// return 0;
- for (int i=0; i<16; i++) {
- if ( (SCHANNEL_CR(i) & SCHANNEL_ENABLE) == 0 ) return i;
- }
- return -1;
+ // return 0;
+ for (int i = 0; i < 16; i++) {
+ if ( (SCHANNEL_CR(i) & SCHANNEL_ENABLE) == 0 )
+ return i;
+ }
+ return -1;
}
-void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel=0, u8 vol=0x7F, u8 pan=63, u8 format=0) {
-// REG_IME = IME_DISABLE;
+void startSound(int sampleRate, const void *data, uint32 bytes, u8 channel = 0, u8 vol = 0x7F, u8 pan = 63, u8 format = 0) {
+ // REG_IME = IME_DISABLE;
- channel = getFreeSoundChannel();
-/* if (format == 2) {
- channel = 1;
- } else {
- channel = 0;
- }*/
+ channel = getFreeSoundChannel();
+ /*
+ if (format == 2) {
+ channel = 1;
+ } else {
+ channel = 0;
+ }
+ */
- if (channel > 1) channel = 1;
+ if (channel > 1)
+ channel = 1;
- bytes &= ~7; // Multiple of 4 bytes!
-// bytes += 4;
+ bytes &= ~7; // Multiple of 4 bytes!
+ // bytes += 4;
- SCHANNEL_CR(channel) = 0;
- SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
- SCHANNEL_SOURCE(channel) = ((uint32) (data));
- SCHANNEL_LENGTH(channel) = ((bytes & 0x7FFFFFFF) >> 2);
- SCHANNEL_REPEAT_POINT(channel) = 0;
+ SCHANNEL_CR(channel) = 0;
+ SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel) = (uint32)data;
+ SCHANNEL_LENGTH(channel) = (bytes & 0x7FFFFFFF) >> 2;
+ SCHANNEL_REPEAT_POINT(channel) = 0;
- SCHANNEL_CR(channel + 2) = 0;
- SCHANNEL_TIMER(channel + 2) = SOUND_FREQ(sampleRate);
- SCHANNEL_SOURCE(channel + 2) = ((uint32) (data));
- SCHANNEL_LENGTH(channel + 2) = ((bytes & 0x7FFFFFFF) >> 2);
- SCHANNEL_REPEAT_POINT(channel + 2) = 0;
+ SCHANNEL_CR(channel + 2) = 0;
+ SCHANNEL_TIMER(channel + 2) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel + 2) = (uint32)data;
+ SCHANNEL_LENGTH(channel + 2) = (bytes & 0x7FFFFFFF) >> 2;
+ SCHANNEL_REPEAT_POINT(channel + 2) = 0;
- uint32 flags = SCHANNEL_ENABLE | SOUND_VOL(vol) | SOUND_PAN(pan);
+ uint32 flags = SCHANNEL_ENABLE | SOUND_VOL(vol) | SOUND_PAN(pan);
- switch (format) {
+ switch (format) {
case 1: {
flags |= SOUND_FORMAT_8BIT;
- flags |= SOUND_REPEAT;// | (1 << 15);
+ flags |= SOUND_REPEAT; // | (1 << 15);
break;
}
case 0: {
flags |= SOUND_FORMAT_16BIT;
- flags |= SOUND_REPEAT;// | (1 << 15);
+ flags |= SOUND_REPEAT; // | (1 << 15);
break;
}
case 2: {
flags |= SOUND_FORMAT_ADPCM;
- flags |= SOUND_ONE_SHOT;// | (1 << 15);
+ flags |= SOUND_ONE_SHOT; // | (1 << 15);
- SCHANNEL_SOURCE(channel) = (unsigned int) IPC->adpcm.buffer[0];
- //bytes += 32;
- SCHANNEL_LENGTH(channel) = (((bytes + 4) & 0x7FFFFFFF) >> 2);
+ SCHANNEL_SOURCE(channel) = (unsigned int)IPC->adpcm.buffer[0];
+ // bytes += 32;
+ SCHANNEL_LENGTH(channel) = ((bytes + 4) & 0x7FFFFFFF) >> 2;
SCHANNEL_CR(channel + 1) = 0;
- SCHANNEL_SOURCE(channel + 1) = (unsigned int) IPC->adpcm.buffer[0];
- SCHANNEL_LENGTH(channel + 1) = (((bytes + 4) & 0x7FFFFFFF) >> 2);
- SCHANNEL_TIMER(channel + 1) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel + 1) = (unsigned int)IPC->adpcm.buffer[0];
+ SCHANNEL_LENGTH(channel + 1) = ((bytes + 4) & 0x7FFFFFFF) >> 2;
+ SCHANNEL_TIMER(channel + 1) = SOUND_FREQ(sampleRate);
SCHANNEL_REPEAT_POINT(channel + 1) = 0;
SCHANNEL_CR(channel + 1) = flags;
temp = bytes;
adpcmBufferNum = 0;
break;
}
- }
-
-
-// if (bytes & 0x80000000) {
-// flags |= SOUND_REPEAT;
-// } else {
-// }
-
-
-
+ }
- soundData = (vu8 *) data;
+ /*
+ if (bytes & 0x80000000) {
+ flags |= SOUND_REPEAT;
+ } else {
+ }
+ */
- SCHANNEL_CR(channel) = flags;
- SCHANNEL_CR(channel + 2) = flags;
+ soundData = (vu8 *)data;
+ SCHANNEL_CR(channel) = flags;
+ SCHANNEL_CR(channel + 2) = flags;
+ if (channel == 0) {
+ for (volatile int i = 0; i < 16384 * 2; i++) {
+ // Delay loop - this makes everything stay in sync!
+ }
- if (channel == 0) {
- for (volatile int i = 0; i < 16384 * 2; i++) {
- // Delay loop - this makes everything stay in sync!
- }
+ TIMER0_CR = 0;
+ TIMER0_DATA = SOUND_FREQ(sampleRate) * 2;
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1;
- TIMER0_CR = 0;
- TIMER0_DATA = SOUND_FREQ(sampleRate) * 2;
- TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1;
+ TIMER1_CR = 0;
+ TIMER1_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
+ TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
- TIMER1_CR = 0;
- TIMER1_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
- TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+ playingSection = 0;
+ } else {
+ for (volatile int i = 0; i < 16384 * 2; i++) {
+ // Delay loop - this makes everything stay in sync!
+ }
- playingSection = 0;
- } else {
- for (volatile int i = 0; i < 16384 * 2; i++) {
- // Delay loop - this makes everything stay in sync!
- }
+ TIMER2_CR = 0;
+ TIMER2_DATA = SOUND_FREQ(sampleRate) * 2;
+ TIMER2_CR = TIMER_ENABLE | TIMER_DIV_1;
- TIMER2_CR = 0;
- TIMER2_DATA = SOUND_FREQ(sampleRate) * 2;
- TIMER2_CR = TIMER_ENABLE | TIMER_DIV_1;
+ TIMER3_CR = 0;
+ TIMER3_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
+ TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
- TIMER3_CR = 0;
- TIMER3_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
- TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+ for (int r = 0; r < 4; r++) {
+ // IPC->streamFillNeeded[r] = true;
+ }
- for (int r = 0; r < 4; r++) {
-// IPC->streamFillNeeded[r] = true;
+ IPC->streamPlayingSection = 0;
}
- IPC->streamPlayingSection = 0;
- }
-
-
-
-// IPC->fillSoundFirstHalf = true;
-// IPC->fillSoundSecondHalf = true;
-// soundFirstHalf = true;
+ // IPC->fillSoundFirstHalf = true;
+ // IPC->fillSoundSecondHalf = true;
+ // soundFirstHalf = true;
-// REG_IME = IME_ENABLE;
+ // REG_IME = IME_ENABLE;
}
void stopSound(int chan) {
- SCHANNEL_CR(chan) = 0;
+ SCHANNEL_CR(chan) = 0;
}
void DummyHandler() {
@@ -235,146 +229,132 @@ void DummyHandler() {
}
void powerManagerWrite(uint32 command, u32 data, bool enable) {
-
- uint16 result;
- SerialWaitBusy();
-
- // Write the command and wait for it to complete
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
- REG_SPIDATA = command | 0x80;
- SerialWaitBusy();
-
- // Write the second command and clock in the data
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
- REG_SPIDATA = 0;
- SerialWaitBusy();
-
- result = REG_SPIDATA & 0xFF;
-
-
-
- // Write the command and wait for it to complete
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
- REG_SPIDATA = command;
- SerialWaitBusy();
-
- // Write the second command and clock in the data
- REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
- REG_SPIDATA = enable? (result | data): (result & ~data);
- SerialWaitBusy();
+ uint16 result;
+ SerialWaitBusy();
+
+ // Write the command and wait for it to complete
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
+ REG_SPIDATA = command | 0x80;
+ SerialWaitBusy();
+
+ // Write the second command and clock in the data
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
+ REG_SPIDATA = 0;
+ SerialWaitBusy();
+
+ result = REG_SPIDATA & 0xFF;
+
+ // Write the command and wait for it to complete
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
+ REG_SPIDATA = command;
+ SerialWaitBusy();
+
+ // Write the second command and clock in the data
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
+ REG_SPIDATA = enable ? (result | data) : (result & ~data);
+ SerialWaitBusy();
}
/*
void performSleep() {
+ powerManagerWrite(0, 0x30, true);
- powerManagerWrite(0, 0x30, true);
-
- // Here, I set up a dummy interrupt handler, then trigger all interrupts.
- // These are just aknowledged by the handler without doing anything else.
- // Why? Because without it the sleep mode will only happen once, and then
- // never again. I got the idea from reading the MoonShell source.
- IME = 0;
- u32 irq = (u32) IRQ_HANDLER;
- IRQ_HANDLER = DummyHandler;
- IF = ~0;
- IME = 1;
+ // Here, I set up a dummy interrupt handler, then trigger all interrupts.
+ // These are just aknowledged by the handler without doing anything else.
+ // Why? Because without it the sleep mode will only happen once, and then
+ // never again. I got the idea from reading the MoonShell source.
+ IME = 0;
+ u32 irq = (u32)IRQ_HANDLER;
+ IRQ_HANDLER = DummyHandler;
+ IF = ~0;
+ IME = 1;
+ // Now save which interrupts are enabled, then set only the screens unfolding
+ // interrupt to be enabled, so that the first interrupt that happens is the
+ // one I want.
+ int saveInts = IE;
- // Now save which interrupts are enabled, then set only the screens unfolding
- // interrupt to be enabled, so that the first interrupt that happens is the
- // one I want.
- int saveInts = IE;
+ IE = IRQ_TIMER0; // Screens unfolding interrupt
+ // Now call the sleep function in the bios
+ bool b;
+ do {
+ TIMER0_CR = 0;
+ TIMER0_DATA = TIMER_FREQ(20);
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_64;
+ swiDelay(100);
- IE = IRQ_TIMER0; // Screens unfolding interrupt
+ swiSleep();
- // Now call the sleep function in the bios
- bool b;
- do {
- TIMER0_CR = 0;
- TIMER0_DATA = TIMER_FREQ(20);
- TIMER0_CR = TIMER_ENABLE | TIMER_DIV_64;
+ swiDelay(100);
- swiDelay(100);
-
- swiSleep();
-
- swiDelay(100);
-
- powerManagerWrite(0, 0x30, b = !b);
- } while (!(TIMER0_CR & TIMER_ENABLE));
-
- TIMER0_CR = 0;
-
- // We're back from sleep, now restore the interrupt state and IRQ handler
- IRQ_HANDLER = (void (*)()) irq;
- IE = saveInts;
- IF = ~0;
- IME = 1;
+ powerManagerWrite(0, 0x30, b = !b);
+ } while (!(TIMER0_CR & TIMER_ENABLE));
+ TIMER0_CR = 0;
+ // We're back from sleep, now restore the interrupt state and IRQ handler
+ IRQ_HANDLER = (void (*)())irq;
+ IE = saveInts;
+ IF = ~0;
+ IME = 1;
- powerManagerWrite(0, 0x30, false);
+ powerManagerWrite(0, 0x30, false);
}
-
*/
-void performSleep() {
- powerManagerWrite(0, 0x30, true);
- IPC->performArm9SleepMode = true; // Tell ARM9 to sleep
+void performSleep() {
+ powerManagerWrite(0, 0x30, true);
-// u32 irq = (u32) IRQ_HANDLER;
-// IRQ_HANDLER = DummyHandler;
-// POWER_CR &= ~POWER_SOUND;
+ IPC->performArm9SleepMode = true; // Tell ARM9 to sleep
-// int saveInts = REG_IE;
-// REG_IE = (1 << 22) | IRQ_VBLANK; // Lid open
-// *((u32 *) (0x0380FFF8)) = *((u32 *) (0x0380FFF8)) | (REG_IE & REG_IF);
-// VBLANK_INTR_WAIT_FLAGS = IRQ_VBLANK;
+ // u32 irq = (u32)IRQ_HANDLER;
+ // IRQ_HANDLER = DummyHandler;
+ // POWER_CR &= ~POWER_SOUND;
+ // int saveInts = REG_IE;
+ // REG_IE = (1 << 22) | IRQ_VBLANK; // Lid open
+ // *((u32 *)(0x0380FFF8)) = *((u32 *)(0x0380FFF8)) | (REG_IE & REG_IF);
+ // VBLANK_INTR_WAIT_FLAGS = IRQ_VBLANK;
- int r = 0;
- while ((REG_KEYXY & (1 << 7))) { // Wait for lid to open
- swiDelay(1000000);
- r++;
- }
+ int r = 0;
+ while ((REG_KEYXY & (1 << 7))) { // Wait for lid to open
+ swiDelay(1000000);
+ r++;
+ }
-// IRQ_HANDLER = (void (*)()) irq;
- IPC->performArm9SleepMode = false; // Tell ARM9 to wake up
-// REG_IE = saveInts;
+ // IRQ_HANDLER = (void (*)())irq;
+ IPC->performArm9SleepMode = false; // Tell ARM9 to wake up
+ // REG_IE = saveInts;
-// POWER_CR |= POWER_SOUND;
+ // POWER_CR |= POWER_SOUND;
- powerManagerWrite(0, 0x30, false);
+ powerManagerWrite(0, 0x30, false);
}
void powerOff() {
powerManagerWrite(0, 0x40, true);
}
-//////////////////////////////////////////////////////////////////////
-
-
void InterruptTimer1() {
-
IPC->fillNeeded[playingSection] = true;
soundFilled[playingSection] = false;
if (playingSection == 3) {
-// IME = IME_DISABLED;
+ // IME = IME_DISABLED;
- // while (SCHANNEL_CR(0) & SCHANNEL_ENABLE) {
- // }
-// SCHANNEL_CR(0) &= ~SCHANNEL_ENABLE;
+ // while (SCHANNEL_CR(0) & SCHANNEL_ENABLE) {
+ // }
+ // SCHANNEL_CR(0) &= ~SCHANNEL_ENABLE;
-// SCHANNEL_CR(0) |= SCHANNEL_ENABLE;
-// TIMER1_CR = 0;
-// TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+ // SCHANNEL_CR(0) |= SCHANNEL_ENABLE;
+ // TIMER1_CR = 0;
+ // TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
playingSection = 0;
-// IME = IME_ENABLED;
+ // IME = IME_ENABLED;
} else {
playingSection++;
}
@@ -395,8 +375,8 @@ void InterruptTimer1() {
}
void InterruptTimer3() {
- while (IPC->adpcm.semaphore); // Wait for buffer to become free if needed
- IPC->adpcm.semaphore = true; // Lock the buffer structure to prevent clashing with the ARM7
+ while (IPC->adpcm.semaphore); // Wait for buffer to become free if needed
+ IPC->adpcm.semaphore = true; // Lock the buffer structure to prevent clashing with the ARM7
IPC->streamFillNeeded[IPC->streamPlayingSection] = true;
@@ -406,153 +386,145 @@ void InterruptTimer3() {
IPC->streamPlayingSection++;
}
-
IPC->adpcm.semaphore = false;
}
-// IPC->performArm9SleepMode = false;
-
- // precalculate some values
-// static int16 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
-// static int16 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
-// static int16 CNTRL_WIDTH = TOUCH_CNTRL_X2 - (TOUCH_CNTRL_X1 - 8);
-// static int16 CNTRL_HEIGHT = TOUCH_CNTRL_Y2 - (TOUCH_CNTRL_Y1 - 8);
-
-
+// IPC->performArm9SleepMode = false;
+// precalculate some values
+// static int16 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
+// static int16 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
+// static int16 CNTRL_WIDTH = TOUCH_CNTRL_X2 - (TOUCH_CNTRL_X1 - 8);
+// static int16 CNTRL_HEIGHT = TOUCH_CNTRL_Y2 - (TOUCH_CNTRL_Y1 - 8);
void InterruptVBlank() {
- uint16 but=0, x=0, y=0, xpx=0, ypx=0, z1=0, z2=0, batt=0, aux=0;
- int t1=0, t2=0;
- uint32 temp=0;
- uint8 ct[sizeof(IPC->curtime)];
+ uint16 but = 0, x = 0, y = 0, xpx = 0, ypx = 0, z1 = 0, z2 = 0, batt = 0, aux = 0;
+ int t1 = 0, t2 = 0;
+ uint32 temp = 0;
+ uint8 ct[sizeof(IPC->curtime)];
static int heartbeat = 0;
- // Update the heartbeat
- heartbeat++;
-
- // Read the X/Y buttons and the /PENIRQ line
- but = REG_KEYXY;
- if (!(but & 0x40)) {
- // Read the touch screen
- touchPosition p;
- touchReadXY(&p);
-
-// x = touchRead(TSC_MEASURE_X);
- // y = touchRead(TSC_MEASURE_Y);
+ // Update the heartbeat
+ heartbeat++;
- x = p.rawx;
- y = p.rawy;
+ // Read the X/Y buttons and the /PENIRQ line
+ but = REG_KEYXY;
+ if (!(but & 0x40)) {
+ // Read the touch screen
+ touchPosition p;
+ touchReadXY(&p);
- xpx = p.px;
- ypx = p.py;
+ // x = touchRead(TSC_MEASURE_X);
+ // y = touchRead(TSC_MEASURE_Y);
-// xpx = ( ((SCREEN_WIDTH -60) * x) / TOUCH_WIDTH ) - TOUCH_OFFSET_X;
- // ypx = ( ((SCREEN_HEIGHT-60) * y) / TOUCH_HEIGHT ) - TOUCH_OFFSET_Y;
+ x = p.rawx;
+ y = p.rawy;
-// xpx = (IPC->touchX - (int16) TOUCH_CAL_X1) * CNTRL_WIDTH / TOUCH_WIDTH + (int16) (TOUCH_CNTRL_X1 - 8);
- // ypx = (IPC->touchY - (int16) TOUCH_CAL_Y1) * CNTRL_HEIGHT / TOUCH_HEIGHT + (int16) (TOUCH_CNTRL_Y1 - 8);
+ // xpx = p.px;
+ // ypx = p.py;
+ xpx = ( ((SCREEN_WIDTH - 60) * x) / TOUCH_WIDTH ) - TOUCH_OFFSET_X;
+ ypx = ( ((SCREEN_HEIGHT - 60) * y) / TOUCH_HEIGHT ) - TOUCH_OFFSET_Y;
- z1 = touchRead(TSC_MEASURE_Z1);
- z2 = touchRead(TSC_MEASURE_Z2);
- }
+ // xpx = (IPC->touchX - (int16) TOUCH_CAL_X1) * CNTRL_WIDTH / TOUCH_WIDTH + (int16) (TOUCH_CNTRL_X1 - 8);
+ // ypx = (IPC->touchY - (int16) TOUCH_CAL_Y1) * CNTRL_HEIGHT / TOUCH_HEIGHT + (int16) (TOUCH_CNTRL_Y1 - 8);
- if (but & (1 << 7)) { // Check if screen is folded
- needSleep = true;
+ z1 = touchRead(TSC_MEASURE_Z1);
+ z2 = touchRead(TSC_MEASURE_Z2);
}
+ // Check if screen is folded
+ if (but & (1 << 7)) {
+ needSleep = true;
+ }
- batt = touchRead(TSC_MEASURE_BATTERY);
- aux = touchRead(TSC_MEASURE_AUX);
-
- // Read the time
- rtcGetTime((uint8 *)ct);
- BCDToInteger((uint8 *)&(ct[1]), 7);
-
- // Read the temperature
- temp = touchReadTemperature(&t1, &t2);
-
-
- // Update the IPC struct
- IPC->heartbeat = heartbeat;
- IPC->buttons = but;
- IPC->touchX = x;
- IPC->touchY = y;
- IPC->touchXpx = xpx;
- IPC->touchYpx = ypx;
- IPC->touchZ1 = z1;
- IPC->touchZ2 = z2;
- IPC->battery = batt;
- IPC->aux = aux;
-
- for (u32 i=0; i<sizeof(ct); i++) {
- IPC->curtime[i] = ct[i];
- }
-
- IPC->temperature = temp;
- IPC->tdiode1 = t1;
- IPC->tdiode2 = t2;
-
-
+ batt = touchRead(TSC_MEASURE_BATTERY);
+ aux = touchRead(TSC_MEASURE_AUX);
+
+ // Read the time
+ rtcGetTime((uint8 *)ct);
+ BCDToInteger((uint8 *)&(ct[1]), 7);
+
+ // Read the temperature
+ temp = touchReadTemperature(&t1, &t2);
+
+ // Update the IPC struct
+ IPC->heartbeat = heartbeat;
+ IPC->buttons = but;
+ IPC->touchX = x;
+ IPC->touchY = y;
+ IPC->touchXpx = xpx;
+ IPC->touchYpx = ypx;
+ IPC->touchZ1 = z1;
+ IPC->touchZ2 = z2;
+ IPC->battery = batt;
+ IPC->aux = aux;
+
+ for (u32 i = 0; i < sizeof(ct); i++) {
+ IPC->curtime[i] = ct[i];
+ }
- //sound code :)
- TransferSound *snd = IPC->soundData;
- IPC->soundData = 0;
- if (snd) {
- for (int i=0; i<snd->count; i++) {
- s8 chan = getFreeSoundChannel();
- if (snd->data[i].rate > 0) {
- if (chan >= 0) {
- startSound(snd->data[i].rate, snd->data[i].data, snd->data[i].len, chan, snd->data[i].vol, snd->data[i].pan, snd->data[i].format);
+ IPC->temperature = temp;
+ IPC->tdiode1 = t1;
+ IPC->tdiode2 = t2;
+
+ // sound code :)
+ TransferSound *snd = IPC->soundData;
+ IPC->soundData = 0;
+ if (snd) {
+ for (int i = 0; i < snd->count; i++) {
+ s8 chan = getFreeSoundChannel();
+ if (snd->data[i].rate > 0) {
+ if (chan >= 0) {
+ startSound(snd->data[i].rate, snd->data[i].data, snd->data[i].len, chan, snd->data[i].vol, snd->data[i].pan, snd->data[i].format);
+ }
+ } else {
+ stopSound(-snd->data[i].rate);
}
- } else {
- stopSound(-snd->data[i].rate);
}
- }
- }
-
+ }
- #ifdef USE_DEBUGGER
- Wifi_Update(); // update wireless in vblank
- #endif
+#ifdef USE_DEBUGGER
+ Wifi_Update(); // update wireless in vblank
+#endif
}
-//////////////////////////////////////////////////////////////////////
-
-
#ifdef USE_DEBUGGER
-
// callback to allow wifi library to notify arm9
void arm7_synctoarm9() { // send fifo message
- REG_IPC_FIFO_TX = 0x87654321;
+ REG_IPC_FIFO_TX = 0x87654321;
}
+
// interrupt handler to allow incoming notifications from arm9
void arm7_fifo() { // check incoming fifo messages
- u32 msg = REG_IPC_FIFO_RX;
- if (msg==0x87654321) Wifi_Sync();
+ u32 msg = REG_IPC_FIFO_RX;
+ if (msg == 0x87654321)
+ Wifi_Sync();
}
-
-
void initDebugger() {
-
// set up the wifi irq
irqSet(IRQ_WIFI, Wifi_Interrupt); // set up wifi interrupt
irqEnable(IRQ_WIFI);
- //get them talking together
+ // get them talking together
// sync with arm9 and init wifi
u32 fifo_temp;
while (1) { // wait for magic number
- while (REG_IPC_FIFO_CR&IPC_FIFO_RECV_EMPTY) swiWaitForVBlank();
- fifo_temp=REG_IPC_FIFO_RX;
- if (fifo_temp==0x12345678) break;
+ while (REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY)
+ swiWaitForVBlank();
+
+ fifo_temp = REG_IPC_FIFO_RX;
+
+ if (fifo_temp == 0x12345678)
+ break;
}
- while (REG_IPC_FIFO_CR&IPC_FIFO_RECV_EMPTY) swiWaitForVBlank();
- fifo_temp=REG_IPC_FIFO_RX; // give next value to wifi_init
+ while (REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY)
+ swiWaitForVBlank();
+
+ fifo_temp = REG_IPC_FIFO_RX; // give next value to wifi_init
Wifi_Init(fifo_temp);
irqSet(IRQ_FIFO_NOT_EMPTY,arm7_fifo); // set up fifo irq
@@ -561,7 +533,6 @@ void initDebugger() {
Wifi_SetSyncHandler(arm7_synctoarm9); // allow wifi lib to notify arm9
// arm7 wifi init complete
-
}
#endif
@@ -571,82 +542,75 @@ void reboot() {
}
#endif
-
int main(int argc, char ** argv) {
-
-
#ifdef USE_DEBUGGER
- REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR;
+ REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR;
#endif
- // Reset the clock if needed
- rtcReset();
-
- //enable sound
-// powerOn(POWER_SOUND);
- SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
- IPC->soundData = 0;
- IPC->reset = false;
-
-
- //fifoInit();
+ // Reset the clock if needed
+ rtcReset();
- for (int r = 0; r < 8; r++) {
- IPC->adpcm.arm7Buffer[r] = (u8 *) malloc(512);
- }
+ // enable sound
+ // powerOn(POWER_SOUND);
+ SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
+ IPC->soundData = 0;
+ IPC->reset = false;
- for (int r = 0; r < 4; r++) {
- soundFilled[r] = false;
- }
+ // fifoInit();
+ for (int r = 0; r < 8; r++) {
+ IPC->adpcm.arm7Buffer[r] = (u8 *)malloc(512);
+ }
- // Set up the interrupt handler
+ for (int r = 0; r < 4; r++) {
+ soundFilled[r] = false;
+ }
- irqInit();
+ // Set up the interrupt handler
- irqSet(IRQ_VBLANK, InterruptVBlank);
- irqEnable(IRQ_VBLANK);
+ irqInit();
- irqSet(IRQ_TIMER1, InterruptTimer1);
- irqEnable(IRQ_TIMER1);
+ irqSet(IRQ_VBLANK, InterruptVBlank);
+ irqEnable(IRQ_VBLANK);
- irqSet(IRQ_TIMER3, InterruptTimer3);
- irqEnable(IRQ_TIMER3);
+ irqSet(IRQ_TIMER1, InterruptTimer1);
+ irqEnable(IRQ_TIMER1);
-/* REG_IME = 0;
- IRQ_HANDLER = &InterruptHandler;
- REG_IE = IRQ_VBLANK | IRQ_TIMER1 | IRQ_TIMER3;
- REG_IF = ~0;
- DISP_SR = DISP_VBLANK_IRQ;
- REG_IME = 1;
- */
+ irqSet(IRQ_TIMER3, InterruptTimer3);
+ irqEnable(IRQ_TIMER3);
+ /*
+ REG_IME = 0;
+ IRQ_HANDLER = &InterruptHandler;
+ REG_IE = IRQ_VBLANK | IRQ_TIMER1 | IRQ_TIMER3;
+ REG_IF = ~0;
+ DISP_SR = DISP_VBLANK_IRQ;
+ REG_IME = 1;
+ */
#ifdef USE_DEBUGGER
- initDebugger();
+ initDebugger();
#endif
- // Keep the ARM7 out of main RAM
- while ((1)) {
- if (needSleep) {
- performSleep();
- needSleep = false;
- }
+ // Keep the ARM7 out of main RAM
+ while ((1)) {
+ if (needSleep) {
+ performSleep();
+ needSleep = false;
+ }
#ifdef USE_LIBCARTRESET
- if (passmeloopQuery()) {
- reboot();
- }
+ if (passmeloopQuery()) {
+ reboot();
+ }
#endif
- if (IPC->reset) {
- powerOff();
+ if (IPC->reset) {
+ powerOff();
+ }
+
+ swiWaitForVBlank();
}
- swiWaitForVBlank();
- }
- return 0;
+ return 0;
}
-
-
-//////////////////////////////////////////////////////////////////////
diff --git a/backends/platform/ds/arm9/source/cdaudio.cpp b/backends/platform/ds/arm9/source/cdaudio.cpp
index c963f4d8bd..3952eeb6ab 100644
--- a/backends/platform/ds/arm9/source/cdaudio.cpp
+++ b/backends/platform/ds/arm9/source/cdaudio.cpp
@@ -23,10 +23,10 @@
// Disable symbol overrides for FILE as that is used in FLAC headers
#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
+#include "dsmain.h"
#include "cdaudio.h"
#include "backends/fs/ds/ds-fs.h"
#include "common/config-manager.h"
-#include "dsmain.h"
#include "NDS/scummvm_ipc.h"
#define WAV_FORMAT_IMA_ADPCM 0x14
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index b7c9c108a6..c6d7d62f22 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -68,8 +68,9 @@
// - Try discworld?
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
+// Allow use of stuff in <nds.h>
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
#include <nds.h>
@@ -439,12 +440,12 @@ void playSound(const void *data, u32 length, bool loop, bool adpcm, int rate) {
soundControl.count = 0;
}
- soundControl.data[soundControl.count].data = data;
- soundControl.data[soundControl.count].len = length | (loop? 0x80000000: 0x00000000);
- soundControl.data[soundControl.count].rate = rate; // 367 samples per frame
- soundControl.data[soundControl.count].pan = 64;
- soundControl.data[soundControl.count].vol = 127;
- soundControl.data[soundControl.count].format = adpcm? 2: 0;
+ soundControl.data[soundControl.count].data = data;
+ soundControl.data[soundControl.count].len = length | (loop ? 0x80000000 : 0x00000000);
+ soundControl.data[soundControl.count].rate = rate; // 367 samples per frame
+ soundControl.data[soundControl.count].pan = 64;
+ soundControl.data[soundControl.count].vol = 127;
+ soundControl.data[soundControl.count].format = adpcm ? 2 : 0;
soundControl.count++;
@@ -573,7 +574,7 @@ void initGame() {
s_currentGame = &gameList[0]; // Default game
for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) {
- if (!stricmp(gameName, gameList[r].gameId)) {
+ if (!scumm_stricmp(gameName, gameList[r].gameId)) {
s_currentGame = &gameList[r];
// consolePrintf("Game list num: %d\n", r);
}
@@ -640,7 +641,7 @@ void displayMode8Bit() {
displayModeIs8Bit = true;
if (isCpuScalerEnabled()) {
- videoSetMode(MODE_5_2D | (consoleEnable? DISPLAY_BG0_ACTIVE: 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+ videoSetMode(MODE_5_2D | (consoleEnable ? DISPLAY_BG0_ACTIVE : 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
videoSetModeSub(MODE_3_2D /*| DISPLAY_BG0_ACTIVE*/ | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
@@ -659,7 +660,7 @@ void displayMode8Bit() {
BG3_YDY = (int) ((200.0f / 192.0f) * 256);
} else {
- videoSetMode(MODE_5_2D | (consoleEnable? DISPLAY_BG0_ACTIVE: 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+ videoSetMode(MODE_5_2D | (consoleEnable ? DISPLAY_BG0_ACTIVE : 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
videoSetModeSub(MODE_3_2D /*| DISPLAY_BG0_ACTIVE*/ | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
@@ -690,7 +691,7 @@ void displayMode8Bit() {
consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 2, 0, true, true);
// Set this again because consoleinit resets it
- videoSetMode(MODE_5_2D | (consoleEnable? DISPLAY_BG0_ACTIVE: 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+ videoSetMode(MODE_5_2D | (consoleEnable ? DISPLAY_BG0_ACTIVE : 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
// Move the cursor to the bottom of the screen using ANSI escape code
consolePrintf("\033[23;0f");
@@ -970,7 +971,7 @@ void displayMode16BitFlipBuffer() {
u16 *back = get16BitBackBuffer();
// highBuffer = !highBuffer;
-// BG3_CR = BG_BMP16_512x256 | BG_BMP_RAM(highBuffer? 1: 0);
+// BG3_CR = BG_BMP16_512x256 | BG_BMP_RAM(highBuffer ? 1 : 0);
if (isCpuScalerEnabled()) {
Rescale_320x256x1555_To_256x256x1555(BG_GFX, back, 512, 512);
@@ -1805,13 +1806,13 @@ void triggerIcon(int imageNum) {
void setIcon(int num, int x, int y, int imageNum, int flags, bool enable) {
- sprites[num].attribute[0] = ATTR0_BMP | (enable? (y & 0xFF): 192) | (!enable? ATTR0_DISABLED: 0);
+ sprites[num].attribute[0] = ATTR0_BMP | (enable ? (y & 0xFF) : 192) | (!enable ? ATTR0_DISABLED : 0);
sprites[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
sprites[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
}
void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable) {
- spritesMain[num].attribute[0] = ATTR0_BMP | (y & 0xFF) | (!enable? ATTR0_DISABLED: 0);
+ spritesMain[num].attribute[0] = ATTR0_BMP | (y & 0xFF) | (!enable ? ATTR0_DISABLED : 0);
spritesMain[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
spritesMain[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
}
@@ -1841,7 +1842,7 @@ void updateStatus() {
}
if (indyFightState) {
- setIcon(1, (190 - 32), 150, 3, (indyFightRight? 0: ATTR1_FLIP_X), true);
+ setIcon(1, (190 - 32), 150, 3, (indyFightRight ? 0 : ATTR1_FLIP_X), true);
// consolePrintf("%d\n", indyFightRight);
} else {
// setIcon(1, 0, 0, 0, 0, false);
@@ -2499,7 +2500,7 @@ void penUpdate() {
// if (getKeysHeld() & KEY_L) consolePrintf("%d, %d penX=%d, penY=%d tz=%d\n", IPC->touchXpx, IPC->touchYpx, penX, penY, IPC->touchZ1);
- bool penDownThisFrame = (IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0);
+ bool penDownThisFrame = (!(IPC->buttons & 0x40)) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0);
static bool moved = false;
if (( (tapScreenClicks) || getKeyboardEnable() ) && (getIsDisplayMode8Bit())) {
@@ -2626,7 +2627,7 @@ void penUpdate() {
penDownSaved = true;
}
- if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
+ if ((!(IPC->buttons & 0x40)) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
penX = IPC->touchXpx + touchXOffset;
penY = IPC->touchYpx + touchYOffset;
moved = true;
@@ -2648,7 +2649,7 @@ void penUpdate() {
- if ((IPC->touchZ1 > 0) || ((penDownFrames == 2)) ) {
+ if ((!(IPC->buttons & 0x40)) || ((penDownFrames == 2)) ) {
penDownLastFrame = true;
penDownFrames++;
} else {
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index fec97d878e..7345fc2ceb 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -23,6 +23,8 @@
#ifndef _DSMAIN_H
#define _DSMAIN_H
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
#include <nds.h>
#include "osystem_ds.h"
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp
index 733592e958..562038166b 100644
--- a/backends/platform/ds/arm9/source/dsoptions.cpp
+++ b/backends/platform/ds/arm9/source/dsoptions.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "dsoptions.h"
#include "dsmain.h"
+#include "dsoptions.h"
#include "gui/dialog.h"
#include "gui/gui-manager.h"
#include "gui/widgets/list.h"
diff --git a/backends/platform/ds/arm9/source/fat/disc_io.c b/backends/platform/ds/arm9/source/fat/disc_io.c
index 5896cbb750..74fc8fb09b 100644
--- a/backends/platform/ds/arm9/source/fat/disc_io.c
+++ b/backends/platform/ds/arm9/source/fat/disc_io.c
@@ -367,7 +367,7 @@ bool disc_setDsSlotInterface (void)
active_interface = DLDI_GetInterface();
- if (stricmp((char *)(&_dldi_driver_name), "Default (No interface)")) {
+ if (strcasecmp((char *)(&_dldi_driver_name), "Default (No interface)")) {
char name[48];
memcpy(name, &_dldi_driver_name, 48);
name[47] = '\0';
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 861ee2e0c5..c35433d3fc 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -23,6 +23,9 @@
// Allow use of stuff in <time.h>
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
+// Allow use of stuff in <nds.h>
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
#include "common/scummsys.h"
#include "common/system.h"
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index f883bd14d1..c8698ca418 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -24,6 +24,10 @@
#ifndef _OSYSTEM_DS_H_
#define _OSYSTEM_DS_H_
+// Allow use of stuff in <nds.h>
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
+
#include "backends/base-backend.h"
#include "common/events.h"
#include "nds.h"
diff --git a/backends/platform/ds/arm9/source/wordcompletion.cpp b/backends/platform/ds/arm9/source/wordcompletion.cpp
index 36fa31247c..2257c49005 100644
--- a/backends/platform/ds/arm9/source/wordcompletion.cpp
+++ b/backends/platform/ds/arm9/source/wordcompletion.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "wordcompletion.h"
#include "osystem_ds.h"
+#include "wordcompletion.h"
#include "engines/agi/agi.h" // Caution for #define for NUM_CHANNELS, causes problems in mixer_intern.h
#ifdef ENABLE_AGI
diff --git a/backends/platform/ds/arm9/source/zipreader.cpp b/backends/platform/ds/arm9/source/zipreader.cpp
index 0de2b0c981..2ad0a39ed2 100644
--- a/backends/platform/ds/arm9/source/zipreader.cpp
+++ b/backends/platform/ds/arm9/source/zipreader.cpp
@@ -23,6 +23,7 @@
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/scummsys.h"
+#include "common/str.h"
#include "zipreader.h"
ZipFile::ZipFile() {
@@ -193,7 +194,7 @@ bool ZipFile::findFile(const char *search) {
}
- if (!stricmp(name, searchName)) {
+ if (!scumm_stricmp(name, searchName)) {
// consolePrintf("'%s'=='%s'\n", name, searchName);
return true; // Got it!
} else {
diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk
index 78216cb9a2..18feea00c2 100644
--- a/backends/platform/ds/ds.mk
+++ b/backends/platform/ds/ds.mk
@@ -75,7 +75,7 @@ endif
# Compiler options for files which should be optimised for speed
-OPT_SPEED := -O3 -mno-thumb
+OPT_SPEED := -O3 -marm
# Compiler options for files which should be optimised for space
OPT_SIZE := -Os -mthumb
@@ -134,7 +134,8 @@ engines/teenagent/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
#
#############################################################################
-all: scummvm.nds scummvm.ds.gba
+# FIXME: Newer versions of devkitARM don't include dsbuild, which is needed to create scummvm.ds.gba
+all: scummvm.nds # scummvm.ds.gba
clean: dsclean
@@ -145,11 +146,8 @@ dsclean:
# TODO: Add a 'dsdist' target ?
-%.bin: %.elf
- $(OBJCOPY) -S -O binary $< $@
-
-%.nds: %.bin $(ndsdir)/arm7/arm7.bin
- ndstool -c $@ -9 $< -7 $(ndsdir)/arm7/arm7.bin -b $(srcdir)/$(ndsdir)/$(LOGO) "$(@F);ScummVM $(VERSION);DS Port"
+%.nds: %.elf $(ndsdir)/arm7/arm7.elf
+ ndstool -c $@ -9 $< -7 $(ndsdir)/arm7/arm7.elf -b $(srcdir)/$(ndsdir)/$(LOGO) "$(@F);ScummVM $(VERSION);DS Port"
%.ds.gba: %.nds
dsbuild $< -o $@ -l $(srcdir)/$(ndsdir)/arm9/ndsloader.bin
@@ -170,10 +168,7 @@ dsclean:
# HACK/FIXME: C compiler, for cartreset.c -- we should switch this to use CXX
# as soon as possible.
-CC := $(DEVKITPRO)/devkitARM/bin/arm-eabi-gcc
-
-# HACK/TODO: Pointer to objcopy. This should really be set by configure
-OBJCOPY := $(DEVKITPRO)/devkitARM/bin/arm-eabi-objcopy
+CC := $(DEVKITPRO)/devkitARM/bin/arm-none-eabi-gcc
#
# Set various flags
@@ -194,7 +189,7 @@ ARM7_CFLAGS := -g -Wall -O2\
ARM7_CXXFLAGS := $(ARM7_CFLAGS) -fno-exceptions -fno-rtti
-ARM7_LDFLAGS := -g $(ARM7_ARCH) -mno-fpu
+ARM7_LDFLAGS := -g $(ARM7_ARCH) -mfloat-abi=soft
# HACK/FIXME: Define a custom build rule for cartreset.c.
# We do this because it is a .c file, not a .cpp file and so is outside our
@@ -218,10 +213,6 @@ $(ndsdir)/arm7/arm7.elf: \
$(ndsdir)/arm7/source/main.o
$(CXX) $(ARM7_LDFLAGS) -specs=ds_arm7.specs $+ -L$(DEVKITPRO)/libnds/lib -lnds7 -o $@
-# Rule for creating ARM7 .bin files from .elf files
-$(ndsdir)/arm7/arm7.bin: $(ndsdir)/arm7/arm7.elf
- $(OBJCOPY) -O binary $< $@
-
diff --git a/backends/platform/n64/portdefs.h b/backends/platform/n64/portdefs.h
index 63ec989a8d..364520803b 100644
--- a/backends/platform/n64/portdefs.h
+++ b/backends/platform/n64/portdefs.h
@@ -36,17 +36,4 @@
#undef assert
#define assert(x) ((x) ? 0 : (print_error("ASSERT TRIGGERED:\n\n("#x")\n%s\nline: %d", __FILE__, __LINE__)))
-// Typedef basic data types in a way that is compatible with the N64 SDK.
-typedef unsigned char byte;
-typedef unsigned char uint8;
-typedef signed char int8;
-typedef unsigned short int uint16;
-typedef signed short int int16;
-typedef unsigned int uint32;
-typedef signed int int32;
-
-// Define SCUMMVM_DONT_DEFINE_TYPES to prevent scummsys.h from trying to
-// re-define those data types.
-#define SCUMMVM_DONT_DEFINE_TYPES
-
-#endif
+#endif // __N64_PORTDEFS__
diff --git a/backends/platform/sdl/riscos/riscos.mk b/backends/platform/sdl/riscos/riscos.mk
index 534b7aeb52..0a3061fd3a 100644
--- a/backends/platform/sdl/riscos/riscos.mk
+++ b/backends/platform/sdl/riscos/riscos.mk
@@ -21,4 +21,5 @@ ifdef DYNAMIC_MODULES
endif
mkdir -p !ScummVM/docs
cp ${srcdir}/dists/riscos/!Help,feb !ScummVM/!Help,feb
- cp $(DIST_FILES_DOCS) !ScummVM/docs \ No newline at end of file
+ cp $(DIST_FILES_DOCS) !ScummVM/docs
+ cp -r ${srcdir}/doc/* !ScummVM/docs
diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp
index 1c9744518e..c5419a989a 100644
--- a/backends/plugins/ds/ds-provider.cpp
+++ b/backends/plugins/ds/ds-provider.cpp
@@ -20,6 +20,10 @@
*
*/
+// Allow use of stuff in <nds.h>
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
+
#include "common/scummsys.h"
#if defined(DYNAMIC_MODULES) && defined(__DS__)
diff --git a/backends/plugins/elf/version.cpp b/backends/plugins/elf/version.cpp
index ac999e1d7c..e91ec6b172 100644
--- a/backends/plugins/elf/version.cpp
+++ b/backends/plugins/elf/version.cpp
@@ -27,6 +27,6 @@
const char *gScummVMPluginBuildDate = "Git Master"; /* ScummVM Git Master */
#else
const char *gScummVMPluginBuildDate __attribute__((visibility("hidden"))) =
- __DATE__ " " __TIME__ ;
+ __DATE__ " " __TIME__;
#endif
#endif
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 2e981fb75a..bd8b9d07ac 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -131,7 +131,14 @@ static const char HELP_STRING[] =
" --native-mt32 True Roland MT-32 (disable GM emulation)\n"
" --enable-gs Enable Roland GS mode for MIDI playback\n"
" --output-rate=RATE Select output sample rate in Hz (e.g. 22050)\n"
- " --opl-driver=DRIVER Select AdLib (OPL) emulator (db, mame)\n"
+ " --opl-driver=DRIVER Select AdLib (OPL) emulator (db, mame"
+#ifndef DISABLE_NUKED_OPL
+ ", nuked"
+#endif
+#ifdef ENABLE_OPL2LPT
+ ", opl2lpt"
+#endif
+ ")\n"
" --aspect-ratio Enable aspect ratio correction\n"
" --render-mode=MODE Enable additional render modes (hercGreen, hercAmber,\n"
" cga, ega, vga, amiga, fmtowns, pc9821, pc9801, 2gs,\n"
@@ -148,7 +155,7 @@ static const char HELP_STRING[] =
" --alt-intro Use alternative intro for CD versions of Beneath a\n"
" Steel Sky and Flight of the Amazon Queen\n"
#endif
- " --copy-protection Enable copy protection in SCUMM games, when\n"
+ " --copy-protection Enable copy protection in games, when\n"
" ScummVM disables it by default.\n"
" --talkspeed=NUM Set talk speed for games (default: 60)\n"
#if defined(ENABLE_SCUMM) || defined(ENABLE_GROOVIE)
@@ -220,6 +227,7 @@ void registerDefaults() {
ConfMan.registerDefault("music_driver", "auto");
ConfMan.registerDefault("mt32_device", "null");
ConfMan.registerDefault("gm_device", "null");
+ ConfMan.registerDefault("opl2lpt_parport", "null");
ConfMan.registerDefault("cdrom", 0);
@@ -233,7 +241,7 @@ void registerDefaults() {
ConfMan.registerDefault("boot_param", 0);
ConfMan.registerDefault("dump_scripts", false);
ConfMan.registerDefault("save_slot", -1);
- ConfMan.registerDefault("autosave_period", 5 * 60); // By default, trigger autosave every 5 minutes
+ ConfMan.registerDefault("autosave_period", 5 * 60); // By default, trigger autosave every 5 minutes
#if defined(ENABLE_SCUMM) || defined(ENABLE_SWORD2)
ConfMan.registerDefault("object_labels", true);
@@ -300,7 +308,7 @@ void registerDefaults() {
// Use this for options which have an *optional* value
#define DO_OPTION_OPT(shortCmd, longCmd, defaultVal) \
- if (isLongCmd ? (!strcmp(s+2, longCmd) || !memcmp(s+2, longCmd"=", sizeof(longCmd"=") - 1)) : (tolower(s[1]) == shortCmd)) { \
+ if (isLongCmd ? (!strcmp(s + 2, longCmd) || !memcmp(s + 2, longCmd"=", sizeof(longCmd"=") - 1)) : (tolower(s[1]) == shortCmd)) { \
s += 2; \
if (isLongCmd) { \
s += sizeof(longCmd) - 1; \
@@ -329,7 +337,7 @@ void registerDefaults() {
// Use this for boolean options; this distinguishes between "-x" and "-X",
// resp. between "--some-option" and "--no-some-option".
#define DO_OPTION_BOOL(shortCmd, longCmd) \
- if (isLongCmd ? (!strcmp(s+2, longCmd) || !strcmp(s+2, "no-" longCmd)) : (tolower(s[1]) == shortCmd)) { \
+ if (isLongCmd ? (!strcmp(s + 2, longCmd) || !strcmp(s + 2, "no-" longCmd)) : (tolower(s[1]) == shortCmd)) { \
bool boolValue = (Common::isLower(s[1]) != 0); \
s += 2; \
if (isLongCmd) { \
@@ -342,7 +350,7 @@ void registerDefaults() {
// Use this for options which never have a value, i.e. for 'commands', like "--help".
#define DO_COMMAND(shortCmd, longCmd) \
- if (isLongCmd ? (!strcmp(s+2, longCmd)) : (tolower(s[1]) == shortCmd)) { \
+ if (isLongCmd ? (!strcmp(s + 2, longCmd)) : (tolower(s[1]) == shortCmd)) { \
s += 2; \
if (isLongCmd) \
s += sizeof(longCmd) - 1; \
@@ -375,7 +383,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
// argv[0] contains the name of the executable.
if (argv[0]) {
s = strrchr(argv[0], '/');
- s_appName = s ? (s+1) : argv[0];
+ s_appName = s ? (s + 1) : argv[0];
}
// We store all command line settings into a string map.
@@ -738,7 +746,7 @@ static Common::Error listSaves(const char *target) {
gameid = domain->getVal("gameid");
if (gameid.empty())
gameid = target;
- gameid.toLowercase(); // Normalize it to lower case
+ gameid.toLowercase(); // Normalize it to lower case
// Find the plugin that will handle the specified gameid
const Plugin *plugin = nullptr;
@@ -746,7 +754,7 @@ static Common::Error listSaves(const char *target) {
if (!plugin) {
return Common::Error(Common::kEnginePluginNotFound,
- Common::String::format("target '%s', gameid '%s", target, gameid.c_str()));
+ Common::String::format("target '%s', gameid '%s", target, gameid.c_str()));
}
const MetaEngine &metaEngine = plugin->get<MetaEngine>();
@@ -754,7 +762,7 @@ static Common::Error listSaves(const char *target) {
if (!metaEngine.hasFeature(MetaEngine::kSupportsListSaves)) {
// TODO: Include more info about the target (desc, engine name, ...) ???
return Common::Error(Common::kEnginePluginNotSupportSaves,
- Common::String::format("target '%s', gameid '%s", target, gameid.c_str()));
+ Common::String::format("target '%s', gameid '%s", target, gameid.c_str()));
} else {
// Query the plugin for a list of saved games
SaveStateList saveList = metaEngine.listSaves(target);
@@ -813,7 +821,7 @@ static void listAudioDevices() {
static GameList getGameList(const Common::FSNode &dir) {
Common::FSList files;
- //Collect all files from directory
+ // Collect all files from directory
if (!dir.getChildren(files, Common::FSNode::kListAll)) {
printf("Path %s does not exist or is not a directory.\n", dir.getPath().c_str());
return GameList();
@@ -1035,7 +1043,7 @@ void upgradeTargets() {
if (gameid.empty()) {
gameid = name;
}
- gameid.toLowercase(); // TODO: Is this paranoia? Maybe we should just assume all lowercase, always?
+ gameid.toLowercase(); // TODO: Is this paranoia? Maybe we should just assume all lowercase, always?
Common::FSNode dir(path);
Common::FSList files;
diff --git a/base/main.cpp b/base/main.cpp
index f529f3ec08..8e783c9776 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -213,7 +213,7 @@ static Common::Error runGame(const Plugin *plugin, OSystem &system, const Common
caption = EngineMan.findGame(ConfMan.get("gameid")).description();
}
if (caption.empty())
- caption = ConfMan.getActiveDomainName(); // Use the domain (=target) name
+ caption = ConfMan.getActiveDomainName(); // Use the domain (=target) name
if (!caption.empty()) {
system.setWindowCaption(caption.c_str());
}
@@ -394,7 +394,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
if (settings.contains("debuglevel")) {
gDebugLevel = (int)strtol(settings["debuglevel"].c_str(), 0, 10);
printf("Debuglevel (from command line): %d\n", gDebugLevel);
- settings.erase("debuglevel"); // This option should not be passed to ConfMan.
+ settings.erase("debuglevel"); // This option should not be passed to ConfMan.
} else if (ConfMan.hasKey("debuglevel"))
gDebugLevel = ConfMan.getInt("debuglevel");
@@ -535,12 +535,12 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
g_eventRec.deinit();
#endif
- #if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES)
+#if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES)
// do our best to prevent fragmentation by unloading as soon as we can
PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false);
// reallocate the config manager to get rid of any fragmentation
ConfMan.defragment();
- #endif
+#endif
// Did an error occur ?
if (result.getCode() != Common::kNoError && result.getCode() != Common::kUserCanceled) {
@@ -549,20 +549,20 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
}
// Quit unless an error occurred, or Return to launcher was requested
- #ifndef FORCE_RTL
+#ifndef FORCE_RTL
if (result.getCode() == Common::kNoError && !g_system->getEventManager()->shouldRTL())
break;
- #endif
+#endif
// Reset RTL flag in case we want to load another engine
g_system->getEventManager()->resetRTL();
- #ifdef FORCE_RTL
+#ifdef FORCE_RTL
g_system->getEventManager()->resetQuit();
- #endif
- #ifdef ENABLE_EVENTRECORDER
+#endif
+#ifdef ENABLE_EVENTRECORDER
if (g_eventRec.checkForContinueGame()) {
continue;
}
- #endif
+#endif
// At this point, we usually return to the launcher. However, the
// game may have requested that one or more other games be "chained"
diff --git a/base/plugins.cpp b/base/plugins.cpp
index 18755003b4..b8f63fd443 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -257,7 +257,7 @@ void PluginManagerUncached::init() {
unloadAllPlugins();
_allEnginePlugins.clear();
- unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); // empty the engine plugins
+ unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); // empty the engine plugins
for (ProviderList::iterator pp = _providers.begin();
pp != _providers.end();
@@ -362,7 +362,7 @@ bool PluginManagerUncached::loadNextPlugin() {
return true;
}
}
- return false; // no more in list
+ return false; // no more in list
}
/**
diff --git a/base/plugins.h b/base/plugins.h
index ce45f7102a..3ad2875906 100644
--- a/base/plugins.h
+++ b/base/plugins.h
@@ -179,9 +179,9 @@ public:
//unloadPlugin();
}
-// virtual bool isLoaded() const = 0; // TODO
- virtual bool loadPlugin() = 0; // TODO: Rename to load() ?
- virtual void unloadPlugin() = 0; // TODO: Rename to unload() ?
+// virtual bool isLoaded() const = 0; // TODO
+ virtual bool loadPlugin() = 0; // TODO: Rename to load() ?
+ virtual void unloadPlugin() = 0; // TODO: Rename to unload() ?
/**
* The following functions query information from the plugin object once
diff --git a/base/version.h b/base/version.h
index 2e362b5c72..74a0e72254 100644
--- a/base/version.h
+++ b/base/version.h
@@ -23,10 +23,10 @@
#ifndef BASE_VERSION_H
#define BASE_VERSION_H
-extern const char *gScummVMVersion; // e.g. "0.4.1"
-extern const char *gScummVMBuildDate; // e.g. "2003-06-24"
+extern const char *gScummVMVersion; // e.g. "0.4.1"
+extern const char *gScummVMBuildDate; // e.g. "2003-06-24"
extern const char *gScummVMVersionDate; // e.g. "0.4.1 (2003-06-24)"
-extern const char *gScummVMFullVersion; // e.g. "ScummVM 0.4.1 (2003-06-24)"
-extern const char *gScummVMFeatures; // e.g. "ALSA MPEG2 zLib"
+extern const char *gScummVMFullVersion; // e.g. "ScummVM 0.4.1 (2003-06-24)"
+extern const char *gScummVMFeatures; // e.g. "ALSA MPEG2 zLib"
#endif
diff --git a/common/archive.cpp b/common/archive.cpp
index 5a339900b6..b4fc7c12c7 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -267,7 +267,7 @@ SeekableReadStream *SearchSet::createReadStreamForMember(const String &name) con
SearchManager::SearchManager() {
- clear(); // Force a reset
+ clear(); // Force a reset
}
void SearchManager::clear() {
diff --git a/common/config-manager.cpp b/common/config-manager.cpp
index fdd0c6f033..082f261f51 100644
--- a/common/config-manager.cpp
+++ b/common/config-manager.cpp
@@ -85,7 +85,7 @@ void ConfigManager::loadDefaultConfigFile() {
// Open the default config file
assert(g_system);
SeekableReadStream *stream = g_system->createConfigReadStream();
- _filename.clear(); // clear the filename to indicate that we are using the default config file
+ _filename.clear(); // clear the filename to indicate that we are using the default config file
// ... load it, if available ...
if (stream) {
@@ -321,7 +321,7 @@ void ConfigManager::flushToDisk() {
void ConfigManager::writeDomain(WriteStream &stream, const String &name, const Domain &domain) {
if (domain.empty())
- return; // Don't bother writing empty domains.
+ return; // Don't bother writing empty domains.
// WORKAROUND: Fix for bug #1972625 "ALL: On-the-fly targets are
// written to the config file": Do not save domains that came from
diff --git a/common/config-manager.h b/common/config-manager.h
index 669faaaf88..58f4373dde 100644
--- a/common/config-manager.h
+++ b/common/config-manager.h
@@ -171,7 +171,7 @@ public:
DomainMap::iterator beginGameDomains() { return _gameDomains.begin(); }
DomainMap::iterator endGameDomains() { return _gameDomains.end(); }
- static void defragment(); // move in memory to reduce fragmentation
+ static void defragment(); // move in memory to reduce fragmentation
void copyFrom(ConfigManager &source);
private:
@@ -185,7 +185,7 @@ private:
Domain _transientDomain;
DomainMap _gameDomains;
- DomainMap _miscDomains; // Any other domains
+ DomainMap _miscDomains; // Any other domains
Domain _appDomain;
Domain _defaultsDomain;
diff --git a/common/fs.h b/common/fs.h
index f516bf7a9c..ed287cc17a 100644
--- a/common/fs.h
+++ b/common/fs.h
@@ -269,7 +269,7 @@ public:
class FSDirectory : public Archive {
FSNode _node;
- String _prefix; // string that is prepended to each cache item key
+ String _prefix; // string that is prepended to each cache item key
void setPrefix(const String &prefix);
// Caches are case insensitive, clashes are dealt with when creating
diff --git a/common/hash-str.h b/common/hash-str.h
index 82af6cca93..fcd41ab6a7 100644
--- a/common/hash-str.h
+++ b/common/hash-str.h
@@ -29,11 +29,10 @@
namespace Common {
uint hashit(const char *str);
-uint hashit_lower(const char *str); // Generate a hash based on the lowercase version of the string
+uint hashit_lower(const char *str); // Generate a hash based on the lowercase version of the string
inline uint hashit(const String &str) { return hashit(str.c_str()); }
inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); }
-
// FIXME: The following functors obviously are not consistently named
struct CaseSensitiveString_EqualTo {
@@ -53,8 +52,6 @@ struct IgnoreCase_Hash {
uint operator()(const String& x) const { return hashit_lower(x.c_str()); }
};
-
-
// Specalization of the Hash functor for String objects.
// We do case sensitve hashing here, because that is what
// the default EqualTo is compatible with. If one wants to use
@@ -78,9 +75,6 @@ struct Hash<const char *> {
// String map -- by default case insensitive
typedef HashMap<String, String, IgnoreCase_Hash, IgnoreCase_EqualTo> StringMap;
-
-
} // End of namespace Common
-
#endif
diff --git a/common/hashmap.cpp b/common/hashmap.cpp
index 99840993ce..e9eac9fc94 100644
--- a/common/hashmap.cpp
+++ b/common/hashmap.cpp
@@ -95,10 +95,10 @@ void updateHashCollisionStats(int collisions, int dummyHits, int lookups, int ar
g_size / g_totalHashmaps, g_max_size,
g_capacity / g_totalHashmaps, g_max_capacity);
debug(" %d less than %d; %d less than %d; %d less than %d; %d less than %d",
- g_stats[0], 2*8/3,
- g_stats[1],2*16/3,
- g_stats[2],2*32/3,
- g_stats[3],2*64/3);
+ g_stats[0], 2 * 8 / 3,
+ g_stats[1], 2 * 16 / 3,
+ g_stats[2], 2 * 32 / 3,
+ g_stats[3], 2 * 64 / 3);
// TODO:
// * Should record the maximal size of the map during its lifetime, not that at its death
diff --git a/common/hashmap.h b/common/hashmap.h
index d7ba100571..08651a8b01 100644
--- a/common/hashmap.h
+++ b/common/hashmap.h
@@ -355,7 +355,7 @@ HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() {
delete[] _storage;
#ifdef DEBUG_HASH_COLLISIONS
extern void updateHashCollisionStats(int, int, int, int, int);
- updateHashCollisionStats(_collisions, _dummyHits, _lookups, _mask+1, _size);
+ updateHashCollisionStats(_collisions, _dummyHits, _lookups, _mask + 1, _size);
#endif
}
@@ -369,9 +369,9 @@ HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() {
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
_mask = map._mask;
- _storage = new Node *[_mask+1];
+ _storage = new Node *[_mask + 1];
assert(_storage != NULL);
- memset(_storage, 0, (_mask+1) * sizeof(Node *));
+ memset(_storage, 0, (_mask + 1) * sizeof(Node *));
// Simply clone the map given to us, one by one.
_size = 0;
@@ -418,7 +418,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::expandStorage(size_type newCapacity) {
- assert(newCapacity > _mask+1);
+ assert(newCapacity > _mask + 1);
#ifndef NDEBUG
const size_type old_size = _size;
@@ -487,7 +487,7 @@ typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, Has
_lookups++;
debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d",
_collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups),
- (const void *)this, _mask+1, _size);
+ (const void *)this, _mask + 1, _size);
#endif
return ctr;
@@ -525,7 +525,7 @@ typename HashMap<Key, Val, HashFunc, EqualFunc>::size_type HashMap<Key, Val, Has
_lookups++;
debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d",
_collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups),
- (const void *)this, _mask+1, _size);
+ (const void *)this, _mask + 1, _size);
#endif
if (!found && first_free != _mask + 1)
diff --git a/common/language.cpp b/common/language.cpp
index b7397bec6d..e4ecd28211 100644
--- a/common/language.cpp
+++ b/common/language.cpp
@@ -46,7 +46,7 @@ const LanguageDescription g_languages[] = {
{ "jp", "ja_JP", "Japanese", JA_JPN },
{ "kr", "ko_KR", "Korean", KO_KOR },
{ "lv", "lv_LV", "Latvian", LV_LAT },
- { "nb", "nb_NO", "Norwegian Bokm\xE5l", NB_NOR }, // TODO Someone should verify the unix locale
+ { "nb", "nb_NO", "Norwegian Bokm\xE5l", NB_NOR },
{ "pl", "pl_PL", "Polish", PL_POL },
{ "br", "pt_BR", "Portuguese", PT_BRA },
{ "ru", "ru_RU", "Russian", RU_RUS },
diff --git a/common/list.h b/common/list.h
index 1bb4a2a5df..31cf161d22 100644
--- a/common/list.h
+++ b/common/list.h
@@ -170,7 +170,7 @@ public:
const_iterator i2;
const_iterator e2 = list.end();
- for (i = begin(), i2 = list.begin(); (i != e) && (i2 != e2) ; ++i, ++i2) {
+ for (i = begin(), i2 = list.begin(); (i != e) && (i2 != e2); ++i, ++i2) {
static_cast<Node *>(i._node)->_data = static_cast<const Node *>(i2._node)->_data;
}
diff --git a/common/memorypool.cpp b/common/memorypool.cpp
index 1a9bfe2e29..b947b38306 100644
--- a/common/memorypool.cpp
+++ b/common/memorypool.cpp
@@ -64,7 +64,7 @@ void MemoryPool::allocPage() {
// Allocate a new page
page.numChunks = _chunksPerPage;
- assert(page.numChunks * _chunkSize < 16*1024*1024); // Refuse to allocate pages bigger than 16 MB
+ assert(page.numChunks * _chunkSize < 16*1024*1024); // Refuse to allocate pages bigger than 16 MB
page.start = ::malloc(page.numChunks * _chunkSize);
assert(page.start);
diff --git a/common/memstream.h b/common/memstream.h
index f6bf990208..0d7375b6b5 100644
--- a/common/memstream.h
+++ b/common/memstream.h
@@ -289,8 +289,8 @@ public:
return dataSize;
}
- int32 pos() const { return _pos - _length; } //'read' position in the stream
- int32 size() const { return _size; } //that's also 'write' position in the stream, as it's append-only
+ int32 pos() const { return _pos - _length; } // 'read' position in the stream
+ int32 size() const { return _size; } // that's also 'write' position in the stream, as it's append-only
bool seek(int32, int) { return false; }
bool eos() const { return _eos; }
void clearErr() { _eos = false; }
diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp
index 1f283715d0..3db017ea8b 100644
--- a/common/recorderfile.cpp
+++ b/common/recorderfile.cpp
@@ -335,7 +335,7 @@ RecorderEvent PlaybackFile::getNextEvent() {
case kScreenShotTag:
_readStream->seek(-4, SEEK_CUR);
header.len = _readStream->readUint32BE();
- _readStream->skip(header.len-8);
+ _readStream->skip(header.len - 8);
break;
case kMD5Tag:
checkRecordedMD5();
@@ -575,7 +575,7 @@ int PlaybackFile::getScreensCount() {
int result = 0;
while (skipToNextScreenshot()) {
uint32 size = _readStream->readUint32BE();
- _readStream->skip(size-8);
+ _readStream->skip(size - 8);
++result;
}
return result;
@@ -608,10 +608,11 @@ Graphics::Surface *PlaybackFile::getScreenShot(int number) {
if (screenCount == number) {
screenCount++;
_readStream->seek(-4, SEEK_CUR);
- return Graphics::loadThumbnail(*_readStream);
+ Graphics::Surface *thumbnail;
+ return Graphics::loadThumbnail(*_readStream, thumbnail) ? thumbnail : NULL;
} else {
uint32 size = _readStream->readUint32BE();
- _readStream->skip(size-8);
+ _readStream->skip(size - 8);
screenCount++;
}
}
diff --git a/common/rect.h b/common/rect.h
index 6c4292c7af..135076bf1e 100644
--- a/common/rect.h
+++ b/common/rect.h
@@ -40,10 +40,10 @@ struct Point {
Point() : x(0), y(0) {}
Point(int16 x1, int16 y1) : x(x1), y(y1) {}
- bool operator==(const Point &p) const { return x == p.x && y == p.y; }
- bool operator!=(const Point &p) const { return x != p.x || y != p.y; }
- Point operator+(const Point &delta) const { return Point(x + delta.x, y + delta.y); }
- Point operator-(const Point &delta) const { return Point(x - delta.x, y - delta.y); }
+ bool operator==(const Point &p) const { return x == p.x && y == p.y; }
+ bool operator!=(const Point &p) const { return x != p.x || y != p.y; }
+ Point operator+(const Point &delta) const { return Point(x + delta.x, y + delta.y); }
+ Point operator-(const Point &delta) const { return Point(x - delta.x, y - delta.y); }
void operator+=(const Point &delta) {
x += delta.x;
diff --git a/common/scummsys.h b/common/scummsys.h
index 5486ba27c6..ce54f3b50e 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -398,6 +398,18 @@
#endif
#endif
+#ifndef WARN_UNUSED_RESULT
+ #if __cplusplus >= 201703L
+ #define WARN_UNUSED_RESULT [[nodiscard]]
+ #elif GCC_ATLEAST(3, 4)
+ #define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
+ #elif defined(_Check_return_)
+ #define WARN_UNUSED_RESULT _Check_return_
+ #else
+ #define WARN_UNUSED_RESULT
+ #endif
+#endif
+
#ifndef STRINGBUFLEN
#if defined(__N64__) || defined(__DS__) || defined(__3DS__)
#define STRINGBUFLEN 256
diff --git a/common/serializer.h b/common/serializer.h
index e8db40923a..18fb38563b 100644
--- a/common/serializer.h
+++ b/common/serializer.h
@@ -34,7 +34,7 @@ namespace Common {
template<typename T> \
void syncAs ## SUFFIX(T &val, Version minVersion = 0, Version maxVersion = kLastVersion) { \
if (_version < minVersion || _version > maxVersion) \
- return; \
+ return; \
if (_loadStream) \
val = static_cast<T>(_loadStream->read ## SUFFIX()); \
else { \
@@ -178,7 +178,7 @@ public:
*/
void skip(uint32 size, Version minVersion = 0, Version maxVersion = kLastVersion) {
if (_version < minVersion || _version > maxVersion)
- return; // Ignore anything which is not supposed to be present in this save game version
+ return; // Ignore anything which is not supposed to be present in this save game version
_bytesSynced += size;
if (isLoading())
@@ -194,7 +194,7 @@ public:
*/
void syncBytes(byte *buf, uint32 size, Version minVersion = 0, Version maxVersion = kLastVersion) {
if (_version < minVersion || _version > maxVersion)
- return; // Ignore anything which is not supposed to be present in this save game version
+ return; // Ignore anything which is not supposed to be present in this save game version
if (isLoading())
_loadStream->read(buf, size);
@@ -217,7 +217,7 @@ public:
*/
bool matchBytes(const char *magic, byte size, Version minVersion = 0, Version maxVersion = kLastVersion) {
if (_version < minVersion || _version > maxVersion)
- return true; // Ignore anything which is not supposed to be present in this save game version
+ return true; // Ignore anything which is not supposed to be present in this save game version
bool match;
if (isSaving()) {
@@ -238,7 +238,7 @@ public:
*/
void syncString(String &str, Version minVersion = 0, Version maxVersion = kLastVersion) {
if (_version < minVersion || _version > maxVersion)
- return; // Ignore anything which is not supposed to be present in this save game version
+ return; // Ignore anything which is not supposed to be present in this save game version
if (isLoading()) {
char c;
diff --git a/common/str.cpp b/common/str.cpp
index 2ef67175cd..7d40aebf94 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -63,7 +63,7 @@ void String::initWithCStr(const char *str, uint32 len) {
if (len >= _builtinCapacity) {
// Not enough internal storage, so allocate more
- _extern._capacity = computeCapacity(len+1);
+ _extern._capacity = computeCapacity(len + 1);
_extern._refCount = 0;
_str = new char[_extern._capacity];
assert(_str != 0);
@@ -593,7 +593,7 @@ String String::vformat(const char *fmt, va_list args) {
// vsnprintf didn't have enough space, so grow buffer
output.ensureCapacity(len, false);
scumm_va_copy(va, args);
- int len2 = vsnprintf(output._str, len+1, fmt, va);
+ int len2 = vsnprintf(output._str, len + 1, fmt, va);
va_end(va);
assert(len == len2);
output._size = len2;
@@ -741,7 +741,7 @@ String lastPathComponent(const String &path, const char sep) {
const char *last = str + path.size();
// Skip over trailing slashes
- while (last > str && *(last-1) == sep)
+ while (last > str && *(last - 1) == sep)
--last;
// Path consisted of only slashes -> return empty string
@@ -1010,7 +1010,7 @@ int scumm_strnicmp(const char *s1, const char *s2, uint n) {
byte l1, l2;
do {
if (n-- == 0)
- return 0; // no difference found so far -> signal equality
+ return 0; // no difference found so far -> signal equality
// Don't use ++ inside tolower, in case the macro uses its
// arguments more than once.
diff --git a/common/str.h b/common/str.h
index fd77fa90c8..cf7fc34f6b 100644
--- a/common/str.h
+++ b/common/str.h
@@ -285,7 +285,7 @@ public:
* except that it stores the result in (variably sized) String
* instead of a fixed size buffer.
*/
- static String format(const char *fmt, ...) GCC_PRINTF(1,2);
+ static String format(const char *fmt, ...) GCC_PRINTF(1, 2);
/**
* Print formatted data into a String object. Similar to vsprintf,
diff --git a/common/stream.cpp b/common/stream.cpp
index 8d93888020..0a5fa94ac3 100644
--- a/common/stream.cpp
+++ b/common/stream.cpp
@@ -99,7 +99,7 @@ bool MemoryReadStream::seek(int32 offs, int whence) {
// Reset end-of-stream flag on a successful seek
_eos = false;
- return true; // FIXME: STREAM REWRITE
+ return true; // FIXME: STREAM REWRITE
}
bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) {
@@ -124,7 +124,7 @@ bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) {
// Post-Condition
assert(_pos <= _size);
- return true; // FIXME: STREAM REWRITE
+ return true; // FIXME: STREAM REWRITE
}
#pragma mark -
@@ -413,7 +413,7 @@ BufferedSeekableReadStream::BufferedSeekableReadStream(SeekableReadStream *paren
bool BufferedSeekableReadStream::seek(int32 offset, int whence) {
// If it is a "local" seek, we may get away with "seeking" around
// in the buffer only.
- _eos = false; // seeking always cancels EOS
+ _eos = false; // seeking always cancels EOS
int relOffset = 0;
switch (whence) {
diff --git a/common/unzip.cpp b/common/unzip.cpp
index 1f4e601989..f585eb387d 100644
--- a/common/unzip.cpp
+++ b/common/unzip.cpp
@@ -485,13 +485,13 @@ static uLong unzlocal_SearchCentralDir(Common::SeekableReadStream &fin) {
uBackRead = 4;
while (uBackRead<uMaxBack) {
- uLong uReadSize,uReadPos ;
+ uLong uReadSize,uReadPos;
int i;
if (uBackRead+BUFREADCOMMENT>uMaxBack)
uBackRead = uMaxBack;
else
uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
+ uReadPos = uSizeFile-uBackRead;
uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
(BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
@@ -670,13 +670,13 @@ int unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info) {
static void unzlocal_DosDateToTmuDate(uLong ulDosDate, tm_unz* ptm) {
uLong uDate;
uDate = (uLong)(ulDosDate>>16);
- ptm->tm_mday = (uInt)(uDate&0x1f) ;
- ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
- ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+ ptm->tm_mday = (uInt)(uDate&0x1f);
+ ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1);
+ ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980);
ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
- ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
- ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
+ ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20);
+ ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f));
}
/*
@@ -772,7 +772,7 @@ static int unzlocal_GetCurrentFileInfoInternal(unzFile file,
lSeek+=file_info.size_filename;
if ((err==UNZ_OK) && (szFileName!=NULL)) {
- uLong uSizeRead ;
+ uLong uSizeRead;
if (file_info.size_filename<fileNameBufferSize) {
*(szFileName+file_info.size_filename)='\0';
uSizeRead = file_info.size_filename;
@@ -787,7 +787,7 @@ static int unzlocal_GetCurrentFileInfoInternal(unzFile file,
if ((err==UNZ_OK) && (extraField!=NULL)) {
- uLong uSizeRead ;
+ uLong uSizeRead;
if (file_info.size_file_extra<extraFieldBufferSize)
uSizeRead = file_info.size_file_extra;
else
@@ -810,7 +810,7 @@ static int unzlocal_GetCurrentFileInfoInternal(unzFile file,
if ((err==UNZ_OK) && (szComment!=NULL)) {
- uLong uSizeRead ;
+ uLong uSizeRead;
if (file_info.size_file_comment<commentBufferSize) {
*(szComment+file_info.size_file_comment)='\0';
uSizeRead = file_info.size_file_comment;
@@ -897,7 +897,7 @@ int unzGoToNextFile(unzFile file) {
return UNZ_END_OF_LIST_OF_FILE;
s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
- s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+ s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment;
s->num_file++;
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
&s->cur_file_info_internal,
@@ -1185,11 +1185,11 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
}
if (pfile_in_zip_read_info->compression_method==0) {
- uInt uDoCopy,i ;
+ uInt uDoCopy,i;
if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in)
- uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+ uDoCopy = pfile_in_zip_read_info->stream.avail_out;
else
- uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+ uDoCopy = pfile_in_zip_read_info->stream.avail_in;
for (i=0;i<uDoCopy;i++)
*(pfile_in_zip_read_info->stream.next_out+i) = *(pfile_in_zip_read_info->stream.next_in+i);
@@ -1327,7 +1327,7 @@ int unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) {
if (len>size_to_read)
read_now = (uInt)size_to_read;
else
- read_now = (uInt)len ;
+ read_now = (uInt)len;
if (read_now==0)
return 0;
@@ -1392,7 +1392,7 @@ int unzCloseCurrentFile(unzFile file) {
*/
int unzGetGlobalComment(unzFile file, char *szComment, uLong uSizeBuf) {
unz_s* s;
- uLong uReadThis ;
+ uLong uReadThis;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
diff --git a/common/updates.cpp b/common/updates.cpp
index 087002a7d3..4e4ed53b8f 100644
--- a/common/updates.cpp
+++ b/common/updates.cpp
@@ -47,7 +47,7 @@ int UpdateManager::normalizeInterval(int interval) {
val++;
}
- return val[-1]; // Return maximal acceptable value
+ return val[-1]; // Return maximal acceptable value
}
const char *UpdateManager::updateIntervalToString(int interval) {
diff --git a/common/updates.h b/common/updates.h
index 3a3049d4df..812aac718e 100644
--- a/common/updates.h
+++ b/common/updates.h
@@ -50,7 +50,7 @@ public:
kUpdateIntervalNotSupported = 0,
kUpdateIntervalOneDay = 86400,
kUpdateIntervalOneWeek = 604800,
- kUpdateIntervalOneMonth = 2628000 // average seconds per month (60*60*24*365)/12
+ kUpdateIntervalOneMonth = 2628000 // average seconds per month (60*60*24*365)/12
};
UpdateManager() {}
diff --git a/common/ustr.cpp b/common/ustr.cpp
index 35b5502a6d..e5c674f595 100644
--- a/common/ustr.cpp
+++ b/common/ustr.cpp
@@ -239,7 +239,7 @@ void U32String::ensureCapacity(uint32 new_size, bool keep_old) {
if (new_size < curCapacity)
newCapacity = curCapacity;
else
- newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
+ newCapacity = MAX(curCapacity * 2, computeCapacity(new_size + 1));
// Allocate new storage
newStorage = new value_type[newCapacity];
@@ -316,7 +316,7 @@ void U32String::initWithCStr(const value_type *str, uint32 len) {
if (len >= _builtinCapacity) {
// Not enough internal storage, so allocate more
- _extern._capacity = computeCapacity(len+1);
+ _extern._capacity = computeCapacity(len + 1);
_extern._refCount = 0;
_str = new value_type[_extern._capacity];
assert(_str != 0);
diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp
index 4470180710..84646ffa95 100644
--- a/common/xmlparser.cpp
+++ b/common/xmlparser.cpp
@@ -373,7 +373,7 @@ bool XMLParser::parse() {
break;
}
} else {
- ParserNode *node = allocNode(); //new ParserNode;
+ ParserNode *node = allocNode(); // new ParserNode;
node->name = _token;
node->ignore = false;
node->header = activeHeader;
diff --git a/common/zlib.cpp b/common/zlib.cpp
index 39130beb4e..8ea5d6c424 100644
--- a/common/zlib.cpp
+++ b/common/zlib.cpp
@@ -281,7 +281,7 @@ public:
_wrapped->seek(0, SEEK_SET);
_zlibErr = inflateReset(&_stream);
if (_zlibErr != Z_OK)
- return false; // FIXME: STREAM REWRITE
+ return false; // FIXME: STREAM REWRITE
_stream.next_in = _buf;
_stream.avail_in = 0;
}
@@ -297,7 +297,7 @@ public:
}
_eos = false;
- return true; // FIXME: STREAM REWRITE
+ return true; // FIXME: STREAM REWRITE
}
};
diff --git a/configure b/configure
index caaef90e32..8e2a387acc 100755
--- a/configure
+++ b/configure
@@ -134,6 +134,7 @@ _tremor=auto
_tremolo=no
_flac=auto
_mad=auto
+_opl2lpt=no
_alsa=auto
_seq_midi=auto
_sndio=auto
@@ -187,6 +188,7 @@ _plugin_suffix=
_nasm=auto
_optimization_level=
_default_optimization_level=-O2
+_nuked_opl=yes
# Default commands
_ranlib=ranlib
_strip=strip
@@ -381,6 +383,16 @@ define_in_config_if_yes() {
fi
}
+define_in_config_if_no() {
+ if test "$1" = no ; then
+ add_line_to_config_h "#define $2"
+ add_line_to_config_mk "$2 = 1"
+ else
+ add_line_to_config_h "#undef $2"
+ add_line_to_config_mk "# $2 = 1"
+ fi
+}
+
#
# Determine sdl-config
#
@@ -969,6 +981,7 @@ Optional Features:
--enable-plugins enable the support for dynamic plugins
--default-dynamic make plugins dynamic by default
--disable-mt32emu don't enable the integrated MT-32 emulator
+ --disable-nuked-opl don't build Nuked OPL driver
--disable-16bit don't enable 16bit color support
--disable-highres don't enable support for high resolution engines >320x240
--disable-savegame-timestamp don't use timestamps for blank savegame descriptions
@@ -1037,6 +1050,9 @@ Optional Libraries:
installed (optional)
--disable-fluidsynth disable fluidsynth MIDI driver [autodetect]
+ --with-ieee1284-prefix=DIR prefix where libieee1284 is installed (optional)
+ --enable-opl2lpt enable OPL2LPT support
+
--with-sparkle-prefix=DIR prefix where sparkle is installed
(OS X/Windows only - optional)
--disable-sparkle disable sparkle automatic update support
@@ -1122,6 +1138,8 @@ for ac_option in $@; do
--disable-vorbis) _vorbis=no ;;
--enable-tremor) _tremor=yes ;;
--disable-tremor) _tremor=no ;;
+ --enable-opl2lpt) _opl2lpt=yes ;;
+ --disable-opl2lpt) _opl2lpt=no ;;
--enable-flac) _flac=yes ;;
--disable-flac) _flac=no ;;
--enable-mad) _mad=yes ;;
@@ -1171,6 +1189,8 @@ for ac_option in $@; do
--default-dynamic) _plugins_default=dynamic ;;
--enable-mt32emu) _mt32emu=yes ;;
--disable-mt32emu) _mt32emu=no ;;
+ --enable-nuked-opl) _nuked_opl=yes ;;
+ --disable-nuked-opl) _nuked_opl=no ;;
--enable-translation) _translation=yes ;;
--disable-translation) _translation=no ;;
--enable-vkeybd) _vkeybd=yes ;;
@@ -1216,6 +1236,11 @@ for ac_option in $@; do
TREMOR_CFLAGS="-I$arg/include"
TREMOR_LIBS="-L$arg/lib"
;;
+ --with-ieee1284-prefix=*)
+ arg=`echo $ac_option | cut -d '=' -f 2`
+ IEEE1284_CFLAGS="-I$arg/include"
+ IEEE1284_LIBS="-L$arg/lib"
+ ;;
--with-flac-prefix=*)
arg=`echo $ac_option | cut -d '=' -f 2`
FLAC_CFLAGS="-I$arg/include"
@@ -1476,7 +1501,7 @@ dreamcast)
ds)
_host_os=ds
_host_cpu=arm
- _host_alias=arm-eabi
+ _host_alias=arm-none-eabi
;;
gamecube)
_host_os=gamecube
@@ -2326,6 +2351,7 @@ case $_host_os in
append_var CXXFLAGS "-Wno-format"
add_line_to_config_mk 'AMIGAOS = 1'
_port_mk="backends/platform/sdl/amigaos/amigaos.mk"
+ _nuked_opl=no
;;
android)
case $_host in
@@ -2555,7 +2581,8 @@ case $_host_os in
append_var DEFINES "-DARM"
append_var DEFINES "-DNONSTANDARD_PORT"
append_var CXXFLAGS "-isystem $DEVKITPRO/libnds/include"
- append_var CXXFLAGS "-isystem $DEVKITPRO/devkitARM/arm-eabi/include"
+ append_var CXXFLAGS "-isystem $DEVKITPRO/portlibs/nds/include"
+ append_var CXXFLAGS "-isystem $DEVKITPRO/portlibs/armv5te/include"
append_var CXXFLAGS "-mcpu=arm9tdmi"
append_var CXXFLAGS "-mtune=arm9tdmi"
append_var CXXFLAGS "-fomit-frame-pointer"
@@ -2564,9 +2591,8 @@ case $_host_os in
append_var CXXFLAGS "-fdata-sections"
append_var CXXFLAGS "-fno-strict-aliasing"
append_var CXXFLAGS "-fuse-cxa-atexit"
- append_var LDFLAGS "-specs=ds_arm9.specs"
append_var LDFLAGS "-mthumb-interwork"
- append_var LDFLAGS "-mno-fpu"
+ append_var LDFLAGS "-mfloat-abi=soft"
append_var LDFLAGS "-Wl,-Map,map.txt"
if test "$_dynamic_modules" = no ; then
append_var LDFLAGS "-Wl,--gc-sections"
@@ -2576,6 +2602,9 @@ case $_host_os in
# append_var LDFLAGS "-Wl,--retain-symbols-file,ds.syms"
fi
append_var LDFLAGS "-L$DEVKITPRO/libnds/lib"
+ append_var LDFLAGS "-L$DEVKITPRO/portlibs/nds/lib"
+ append_var LDFLAGS "-L$DEVKITPRO/portlibs/armv5te/lib"
+ append_var LIBS "-specs=ds_arm9.specs"
append_var LIBS "-lnds9"
;;
freebsd*)
@@ -2652,6 +2681,7 @@ case $_host_os in
append_var DEFINES "-DDISABLE_SID"
append_var DEFINES "-DREDUCE_MEMORY_USAGE"
add_line_to_config_mk 'N64 = 1'
+ _nuked_opl=no
;;
ps2)
append_var CXXFLAGS "-G2"
@@ -2880,6 +2910,7 @@ if test -n "$_host"; then
append_var CXXFLAGS "-mips32"
_backend="dingux"
_mt32emu=no
+ _nuked_opl=no
_optimization_level=-O3
# Disable alsa midi to get the port build on OpenDingux toolchain
_alsa=no
@@ -2961,6 +2992,7 @@ if test -n "$_host"; then
_backend="ds"
_build_scalers=no
_mt32emu=no
+ _nuked_opl=no
_port_mk="backends/platform/ds/ds.mk"
;;
gamecube)
@@ -3184,6 +3216,7 @@ if test -n "$_host"; then
_backend="ps2"
_build_scalers=no
_mt32emu=no
+ _nuked_opl=no
# HACK to enable mad & zlib (they are not properly detected due to linker issues).
# This trick doesn't work for tremor right now, as the PS2 port the resulting library
# libtremor, while our code later on expects it to be called libvorbisidec.
@@ -3401,6 +3434,7 @@ case $_backend in
append_var DEFINES "-DDISABLE_DOSBOX_OPL"
append_var LIBS "-lpng"
append_var LIBS "-Wl,-Map,mapfile.txt"
+ _nuked_opl=no
;;
psp2)
append_var LIBS "-lvitashaders -lSDL2 -lvita2d_fbo -lSceCommonDialog_stub"
@@ -3544,7 +3578,7 @@ esac
# Enable High resolution engines (>320x240) support only for backends which support it
#
case $_host in
- gcw0)
+ ds | gcw0)
if test "$_highres" = yes ; then
_highres=yes
else
@@ -3727,7 +3761,7 @@ POST_OBJS_FLAGS := -Wl,--no-whole-archive
append_var DEFINES "-DUNCACHED_PLUGINS"
append_var DEFINES "-DELF_NO_MEM_MANAGER"
_mak_plugins='
-PLUGIN_LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/ds/plugin.ld -mthumb-interwork -mno-fpu
+PLUGIN_LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/ds/plugin.ld -mthumb-interwork -mfloat-abi=soft
'
;;
freebsd*)
@@ -3879,6 +3913,11 @@ fi
define_in_config_if_yes "$_mt32emu" 'USE_MT32EMU'
#
+# Check whether Nuked OPL emulator support is disabled
+#
+define_in_config_if_no "$_nuked_opl" 'DISABLE_NUKED_OPL'
+
+#
# Check whether 16bit color support is requested
#
define_in_config_if_yes "$_16bit" 'USE_RGB_COLOR'
@@ -3995,6 +4034,27 @@ add_to_config_mk_if_yes "$_tremor" 'USE_TREMOR = 1'
echo "$_tremor"
#
+# Check for IEEE1284 for OPL2lPT
+#
+echocheck "OPL2LPT"
+if test "$_opl2lpt" = yes ; then
+ _opl2lpt=no
+ cat > $TMPC << EOF
+#include <ieee1284.h>
+struct parport_list parports;
+int main(void) { ieee1284_find_ports(&parports, 0); return 0; }
+EOF
+ cc_check $IEEE1284_CFLAGS $IEEE1284_LIBS -lieee1284 && \
+ _opl2lpt=yes
+fi
+if test "$_opl2lpt" = yes; then
+ append_var LIBS "$IEEE1284_LIBS -lieee1284"
+ append_var INCLUDES "$IEEE1284_CFLAGS"
+fi
+define_in_config_if_yes "$_opl2lpt" 'ENABLE_OPL2LPT'
+echo "$_opl2lpt"
+
+#
# Check for FLAC
#
echocheck "FLAC >= 1.0.1"
@@ -4024,7 +4084,7 @@ fi
define_in_config_if_yes "$_flac" 'USE_FLAC'
echo "$_flac"
-# Add the link to ogg only after verbs tremor and flac as it might be used by those.
+# Add the link to ogg only after vorbis, tremor and flac as it might be used by those.
if test "$_ogg" = yes ; then
append_var LIBS "$OGG_LIBS -logg"
append_var INCLUDES "$OGG_CFLAGS"
@@ -5017,6 +5077,10 @@ if test "$_mt32emu" = yes ; then
echo_n ", MT-32 emulator"
fi
+if test "$_nuked_opl" = yes ; then
+ echo_n ", Nuked OPL emulator"
+fi
+
if test "$_text_console" = yes ; then
echo_n ", text console"
fi
@@ -5232,6 +5296,7 @@ cat > config.h << EOF
$_config_h_data
/* Data types */
+#ifndef SCUMMVM_DONT_DEFINE_TYPES
typedef unsigned $type_1_byte byte;
typedef unsigned int uint;
typedef unsigned $type_1_byte uint8;
@@ -5242,6 +5307,7 @@ typedef signed $type_1_byte int8;
typedef signed $type_2_byte int16;
typedef signed $type_4_byte int32;
typedef signed $type_8_byte int64;
+#endif
typedef $type_ptr uintptr;
diff --git a/devtools/create_supernova/po_parser.cpp b/devtools/create_supernova/po_parser.cpp
index f4a9b96388..05a8ac14a7 100644
--- a/devtools/create_supernova/po_parser.cpp
+++ b/devtools/create_supernova/po_parser.cpp
@@ -69,7 +69,7 @@ void PoMessageList::insert(const char *translation, const char *msg, const char
const char *PoMessageList::findTranslation(const char *msg, const char *context) {
if (msg == NULL || *msg == '\0')
- NULL;
+ return NULL;
// binary-search for the message
int leftIndex = 0;
diff --git a/devtools/create_supernova/strings-en.po b/devtools/create_supernova/strings-en.po
index f1c9d2fae2..1d0328982a 100644
--- a/devtools/create_supernova/strings-en.po
+++ b/devtools/create_supernova/strings-en.po
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: Mission Supernova 1.0\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
"POT-Creation-Date: 2017-07-22 19:53+0100\n"
-"PO-Revision-Date: 2018-01-07 18:01+0000\n"
-"Last-Translator: Joseph-Eugene Winzer <Joe.Winzer@gmx.de>\n"
+"PO-Revision-Date: 2018-04-13 21:29+0000\n"
+"Last-Translator: Adrian Frhwirth <bonki@scummvm.org>\n"
"Language-Team: none\n"
"Language: en\n"
"MIME-Version: 1.0\n"
@@ -1629,7 +1629,7 @@ msgstr "Pssst, not so loud, otherwise everyone|will want an autograph from me."
#: ../../msn/msn_r2.c:730
msgid ""
"Ich habe extra eine Maske auf, damit|ich nicht von jedem angelabert werde."
-msgstr "I have an extra mask on so I don't|get yakked on by everyone."
+msgstr "I'm deliberately wearing a mask so I don't|get yakked on by everyone."
#: ../../msn/msn_r2.c:731
msgid "Žh ... ach so."
@@ -1698,7 +1698,7 @@ msgstr "What? Ridiculous!"
#: ../../msn/msn_r2.c:745
msgid "Wie erkl„ren Sie sich dann,|daс ich ihnen gegenbersitze?"
-msgstr "How do you explain then that|I am seated opposite you?"
+msgstr "Then how do you explain the fact that|I am seated opposite you?"
#: ../../msn/msn_r2.c:746
msgid "Ja, das ist in der Tat seltsam."
@@ -1721,7 +1721,8 @@ msgid ""
"Na gut, ich glaube Ihnen. Lassen wir jetzt|dieses Thema, langsam wird es mir "
"zu bunt!"
msgstr ""
-"OK. I believe you. Let's move away from|this topic before it goes too far!"
+"Fair enough, I believe you. Let's move away from|this topic before it goes "
+"too far!"
#: ../../msn/msn_r2.c:761
msgid "Eine Partie Schach! Das ist eine gute Idee."
diff --git a/devtools/create_xeen/constants.cpp b/devtools/create_xeen/constants.cpp
index 8bea0fd22c..65903f58e0 100644
--- a/devtools/create_xeen/constants.cpp
+++ b/devtools/create_xeen/constants.cpp
@@ -968,7 +968,7 @@ const char *const GOLD_GEMS =
"Gems\x3r\t000%s\x2\x3""c\v096\t013G\f37o\fdld\t040G\f37e\fdms\t067ESC\x1";
const char *const GOLD_GEMS_2 =
- "\t000\v000\x3""c%s\x3l\n"
+ "\x3""c\v000\t000%s\x3l\n"
"\n"
"\x4""077Gold\x3r\t000%s\x3l\n"
"\x4""077Gems\x3r\t000%s\x3l\t000\v051\x4""077\n"
@@ -1598,6 +1598,7 @@ const char *const QUESTS_DIALOG_TEXT =
"\t289Exit";
const char *const CLOUDS_OF_XEEN_LINE = "\b \b*-- \f04Clouds of Xeen\fd --";
const char *const DARKSIDE_OF_XEEN_LINE = "\b \b*-- \f04Darkside of Xeen\fd --";
+const char *const SWORDS_OF_XEEN_LINE = "\b \b*-- \f04Swords of Xeen\fd --";
const char *const NO_QUEST_ITEMS =
"\r\x3""c\v000 000Quest Items\x3l\x2\n"
@@ -1755,7 +1756,7 @@ const char *const WHICH_ELEMENT1 =
"\f15E\fdlec\t074\f15C\fdold\t104\f15A\fdcid\x1";
const char *const WHICH_ELEMENT2 =
- "\r\x3""cWhich Element?', 2, 0Bh, '034\t014\f15F\fdire\t044"
+ "\r\x3""cWhich Element?\x2\v034\t014\f15F\fdire\t044"
"\f15E\fdlec\t074\f15C\fdold\t104\f15A\fdcid\x1";
const char *const DETECT_MONSTERS = "\x3""cDetect Monsters";
@@ -1768,7 +1769,7 @@ const char *const LLOYDS_BEACON =
"%s\x3l\n"
"x = %d\x3r\t000y = %d\x3""c\x2\v122\t021\f15S\fdet\t060\f15R\fdeturn\x1";
-const char *const HOW_MANY_SQUARES = "\x3""cTeleport\nHow many squares %s (1-9)";
+const char *const HOW_MANY_SQUARES = "\x3""cTeleport\nHow many squares %s (1-9)\n";
const char *const TOWN_PORTAL =
"\x3""cTown Portal\x3l\n"
@@ -1782,8 +1783,18 @@ const char *const TOWN_PORTAL =
"To which Town (1-5)\n"
"\n";
-const int TOWN_MAP_NUMBERS[2][5] = {
- { 28, 29, 30, 31, 32 }, { 29, 31, 33, 35, 37 }
+const char *const TOWN_PORTAL_SWORDS =
+ "\x3""cTown Portal\x3l\n"
+ "\n"
+ "\t0101. %s\n"
+ "\t0102. %s\n"
+ "\t0103. %s\x3""c\n"
+ "\n"
+ "To which Town (1-3)\n"
+ "\n";
+
+const int TOWN_MAP_NUMBERS[3][5] = {
+ { 28, 29, 30, 31, 32 }, { 29, 31, 33, 35, 37 }, { 53, 92, 63, 0, 0 }
};
const char *const MONSTER_DETAILS =
@@ -1922,6 +1933,8 @@ const char *const MUSIC_FILES2[6][7] = {
};
const char *const DIFFICULTY_TEXT = "\v000\t000\x3""cSelect Game Preference";
+const char *const SAVE_OFF_LIMITS = "\x3""c\v002\t000The Gods of Game Restoration deem this area off limits!\n"
+ "Sorry, no saving in this maze.";
void writeConstants(CCArchive &cc) {
Common::MemFile file;
@@ -2178,6 +2191,7 @@ void writeConstants(CCArchive &cc) {
file.syncString(QUESTS_DIALOG_TEXT);
file.syncString(CLOUDS_OF_XEEN_LINE);
file.syncString(DARKSIDE_OF_XEEN_LINE);
+ file.syncString(SWORDS_OF_XEEN_LINE);
file.syncString(NO_QUEST_ITEMS);
file.syncString(NO_CURRENT_QUESTS);
file.syncString(NO_AUTO_NOTES);
@@ -2227,7 +2241,8 @@ void writeConstants(CCArchive &cc) {
file.syncString(LLOYDS_BEACON);
file.syncString(HOW_MANY_SQUARES);
file.syncString(TOWN_PORTAL);
- file.syncNumbers2D((const int *)TOWN_MAP_NUMBERS, 2, 5);
+ file.syncString(TOWN_PORTAL_SWORDS);
+ file.syncNumbers2D((const int *)TOWN_MAP_NUMBERS, 3, 5);
file.syncString(MONSTER_DETAILS);
file.syncStrings(MONSTER_SPECIAL_ATTACKS, 23);
file.syncString(IDENTIFY_MONSTERS);
@@ -2261,6 +2276,7 @@ void writeConstants(CCArchive &cc) {
file.syncStrings(MUSIC_FILES1, 5);
file.syncStrings2D((const char *const *)MUSIC_FILES2, 6, 7);
file.syncString(DIFFICULTY_TEXT);
+ file.syncString(SAVE_OFF_LIMITS);
cc.add("CONSTANTS", file);
}
diff --git a/dists/engine-data/supernova.dat b/dists/engine-data/supernova.dat
index 74d9092aef..b4638c2717 100644
--- a/dists/engine-data/supernova.dat
+++ b/dists/engine-data/supernova.dat
Binary files differ
diff --git a/dists/engine-data/xeen.ccs b/dists/engine-data/xeen.ccs
index 162e7fa4bd..f9179611ff 100644
--- a/dists/engine-data/xeen.ccs
+++ b/dists/engine-data/xeen.ccs
Binary files differ
diff --git a/doc/cz/PrectiMe b/doc/cz/PrectiMe
index 67980e1256..8d033aacea 100644
--- a/doc/cz/PrectiMe
+++ b/doc/cz/PrectiMe
@@ -1023,7 +1023,7 @@ ScummVM mХЏХОe takУЉ hru spustit pХ™У­mo pomocУ­ argumentХЏ pХ™У­kazovУЉ Х™УЁdky
--native-mt32 PravУН Roland MT-32 (zakУЁХОe emulaci GM)
--enable-gs PovolУ­ reХОim Roland GS pro pХ™ehrУЁvУЁnУ­ MIDI
--output-rate=FREKVENCE VУНstupnУ­ vzorkovacУ­ kmitoФet v Hz (napХ™. 22050)
- --opl-driver=OVLADAФŒ Vybere emulУЁtor AdLib (OPL) (db, mame)
+ --opl-driver=OVLADAФŒ Vybere emulУЁtor AdLib (OPL) (db, mame, nuked)
--aspect-ratio PovolУ­ korekci pomФ›ru stran
--render-mode=REХНIM PovolУ­ dodateФnУЉ reХОimy vykreslenУ­ (hercGreen, hercAmber,
cga, ega, vga, amiga, fmtowns, pc9821, pc9801, 2gs,
diff --git a/doc/de/LIESMICH b/doc/de/LIESMICH
index 532160aa25..1209b8e057 100644
--- a/doc/de/LIESMICH
+++ b/doc/de/LIESMICH
@@ -1589,7 +1589,7 @@ gestartet werden -- siehe nУЄchster Abschnitt.
(GM-Emulation deaktiviert)
--enable-gs Aktiviert Roland-GS-Modus fУМr MIDI-Wiedergabe.
--output-rate=FREQUENZ WУЄhlt Ausgabefrequenz in Hz (z. B. 22050).
- --opl-driver=TREIBER WУЄhlt AdLib-(OPL-)Emulator (db, mame).
+ --opl-driver=TREIBER WУЄhlt AdLib-(OPL-)Emulator (db, mame, nuked).
--aspect-ratio Aktiviert SeitenverhУЄltniskorrektur.
--render-mode=MODUS Aktiviert zusУЄtzlichen Render-Modus (hercGreen,
hercAmber, cga, ega, vga, amiga, fmtowns, pc9821,
diff --git a/doc/de/NEUES b/doc/de/NEUES
index 6d3a1eef4c..1ee2283242 100644
--- a/doc/de/NEUES
+++ b/doc/de/NEUES
@@ -543,7 +543,7 @@ Programmcodes finden Sie auf Englisch unter:
KQ6, LB2, LSL2, LSL5, Pharkas, PQ1VGA, SQ4 und SQ5 beseitigt.
- MIDI-Parser verbessert, sodass Musikereignisse genauer verarbeitet werden.
-SCUMM:
+ SCUMM:
- Spielstandsbenennungsschema von HE-Spielen geУЄndert, sodass immer der
Zielname des Spiels enthalten ist.
- Fehler beseitigt, durch den man mehrere Trainer in Backyard Football hatte.
diff --git a/doc/se/LasMig b/doc/se/LasMig
index d47918d1f4..91cdd3b2f0 100644
--- a/doc/se/LasMig
+++ b/doc/se/LasMig
@@ -712,7 +712,7 @@ Ordning: scummvm [INSTУ„LLNINGAR]... [SPEL]
--native-mt32 True Roland MT-32 (deaktivera GM-emulation)
--enable-gs Aktivera Roland GS-lУЄge fУЖr MIDI-uppspelning
--output-rate=RATE VУЄlj ljudfrekvens i Hz (t.ex. 22050)
- --opl-driver=DRIVER VУЄlj AdLib (OPL)-emulator (db, mame)
+ --opl-driver=DRIVER VУЄlj AdLib (OPL)-emulator (db, mame, nuked)
--aspect-ratio Aktivera korrektion av bildfУЖrhУЅllande
--render-mode=MODE Aktivera ytterligare renderingslУЄgen (cga, ega,
hercGreen, hercAmber, amiga)
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 1855280a24..c1af19026b 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -488,11 +488,6 @@ Common::Error AccessEngine::loadGameState(int slot) {
if (!readSavegameHeader(saveFile, header))
error("Invalid savegame");
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
// Load most of the savegame data
synchronize(s);
delete saveFile;
@@ -537,9 +532,8 @@ void AccessEngine::synchronize(Common::Serializer &s) {
const char *const SAVEGAME_STR = "ACCESS";
#define SAVEGAME_STR_SIZE 6
-bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header) {
+WARN_UNUSED_RESULT bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -557,9 +551,9 @@ bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHead
header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
diff --git a/engines/access/access.h b/engines/access/access.h
index 972dd4c380..56646f01c9 100644
--- a/engines/access/access.h
+++ b/engines/access/access.h
@@ -306,7 +306,7 @@ public:
/**
* Read in a savegame header
*/
- static bool readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header, bool skipThumbnail = true);
/**
* Write out a savegame header
diff --git a/engines/access/detection.cpp b/engines/access/detection.cpp
index 3e70de3635..186fcbdf06 100644
--- a/engines/access/detection.cpp
+++ b/engines/access/detection.cpp
@@ -157,11 +157,9 @@ SaveStateList AccessMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- Access::AccessEngine::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+ if (Access::AccessEngine::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- header._thumbnail->free();
- delete header._thumbnail;
delete in;
}
}
@@ -187,7 +185,11 @@ SaveStateDescriptor AccessMetaEngine::querySaveMetaInfos(const char *target, int
if (f) {
Access::AccessSavegameHeader header;
- Access::AccessEngine::readSavegameHeader(f, header);
+ if (!Access::AccessEngine::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index 2cebc3e3c6..d8f2ab492d 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -152,7 +152,7 @@ void Scripts::searchForSequence() {
_data->seek(0);
int sequenceId;
do {
- while (_data->readByte() != SCRIPT_START_BYTE) ;
+ while (_data->readByte() != SCRIPT_START_BYTE);
sequenceId = _data->readUint16LE();
} while (sequenceId != _sequence);
}
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index e63beb2c07..ab634bc02a 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -401,7 +401,11 @@ SaveStateDescriptor AdlMetaEngine::querySaveMetaInfos(const char *target, int sl
return SaveStateDescriptor();
}
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*inFile);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*inFile, thumbnail)) {
+ delete inFile;
+ return SaveStateDescriptor();
+ }
sd.setThumbnail(thumbnail);
delete inFile;
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index e26f5c84fc..817be08f2c 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -375,7 +375,11 @@ SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int sl
char saveVersion = in->readByte();
if (saveVersion >= 4) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ delete in;
+ return SaveStateDescriptor();
+ }
descriptor.setThumbnail(thumbnail);
diff --git a/engines/avalanche/detection.cpp b/engines/avalanche/detection.cpp
index def395b77f..64634dc017 100644
--- a/engines/avalanche/detection.cpp
+++ b/engines/avalanche/detection.cpp
@@ -193,7 +193,12 @@ SaveStateDescriptor AvalancheMetaEngine::querySaveMetaInfos(const char *target,
SaveStateDescriptor desc(slot, description);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*f);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*f, thumbnail)) {
+ warning("Cannot read thumbnail data, possibly broken savegame");
+ delete f;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
delete f;
diff --git a/engines/bbvs/bbvs.h b/engines/bbvs/bbvs.h
index 9fb6b9cac3..a9d37c2551 100644
--- a/engines/bbvs/bbvs.h
+++ b/engines/bbvs/bbvs.h
@@ -417,7 +417,7 @@ public:
const char *getSavegameFilename(int num);
bool existsSavegame(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
- static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
+ WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true);
void allocSnapshot();
void freeSnapshot();
diff --git a/engines/bbvs/detection.cpp b/engines/bbvs/detection.cpp
index 1b2c644dda..b30c6d3f2d 100644
--- a/engines/bbvs/detection.cpp
+++ b/engines/bbvs/detection.cpp
@@ -124,7 +124,7 @@ SaveStateList BbvsMetaEngine::listSaves(const char *target) const {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Bbvs::BbvsEngine::readSaveHeader(in, false, header) == Bbvs::BbvsEngine::kRSHENoError) {
+ if (Bbvs::BbvsEngine::readSaveHeader(in, header) == Bbvs::BbvsEngine::kRSHENoError) {
saveList.push_back(SaveStateDescriptor(slotNum, header.description));
}
delete in;
@@ -142,7 +142,7 @@ SaveStateDescriptor BbvsMetaEngine::querySaveMetaInfos(const char *target, int s
if (in) {
Bbvs::BbvsEngine::SaveHeader header;
Bbvs::BbvsEngine::kReadSaveHeaderError error;
- error = Bbvs::BbvsEngine::readSaveHeader(in, true, header);
+ error = Bbvs::BbvsEngine::readSaveHeader(in, header, false);
delete in;
if (error == Bbvs::BbvsEngine::kRSHENoError) {
SaveStateDescriptor desc(slot, header.description);
diff --git a/engines/bbvs/saveload.cpp b/engines/bbvs/saveload.cpp
index 74c255c860..d4782aad39 100644
--- a/engines/bbvs/saveload.cpp
+++ b/engines/bbvs/saveload.cpp
@@ -27,7 +27,7 @@
namespace Bbvs {
-BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+WARN_UNUSED_RESULT BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) {
header.version = in->readUint32LE();
if (header.version > BBVS_SAVEGAME_VERSION)
@@ -38,10 +38,8 @@ BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableRead
while (descriptionLen--)
header.description += (char)in->readByte();
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*in);
- } else {
- Graphics::skipThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ return kRSHEIoError;
}
// Not used yet, reserved for future usage
@@ -101,7 +99,7 @@ void BbvsEngine::loadgame(const char *filename) {
SaveHeader header;
- kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
+ kReadSaveHeaderError errorCode = readSaveHeader(in, header);
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
diff --git a/engines/bladerunner/audio_speech.cpp b/engines/bladerunner/audio_speech.cpp
index 87f73737d4..5ffde9db6c 100644
--- a/engines/bladerunner/audio_speech.cpp
+++ b/engines/bladerunner/audio_speech.cpp
@@ -110,7 +110,7 @@ void AudioSpeech::stopSpeech() {
bool AudioSpeech::isPlaying() const {
if (_channel == -1) {
- return false;
+ return false;
}
return _isActive;
}
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index ab8ad36979..dac8e6dd78 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -75,6 +75,7 @@
#include "bladerunner/zbuffer.h"
#include "common/array.h"
+#include "common/config-manager.h"
#include "common/error.h"
#include "common/events.h"
#include "common/savefile.h"
@@ -475,8 +476,20 @@ void BladeRunnerEngine::initChapterAndScene() {
_actors[i]->movementTrackNext(true);
}
- _settings->setChapter(1);
- _settings->setNewSetAndScene(_gameInfo->getInitialSetId(), _gameInfo->getInitialSceneId());
+ if (ConfMan.hasKey("boot_param")) {
+ int param = ConfMan.getInt("boot_param"); // CTTTSSS
+ int chapter = param / 1000000;
+ param -= chapter * 1000000;
+ int set = param / 1000;
+ param -= set * 1000;
+ int scene = param;
+
+ _settings->setChapter(chapter);
+ _settings->setNewSetAndScene(set, scene);
+ } else {
+ _settings->setChapter(1);
+ _settings->setNewSetAndScene(_gameInfo->getInitialSetId(), _gameInfo->getInitialSceneId());
+ }
}
void BladeRunnerEngine::shutdown() {
@@ -1548,7 +1561,6 @@ bool BladeRunnerEngine::openArchive(const Common::String &name) {
* archive when it runs out of slots. */
error("openArchive: No more archive slots");
- return false;
}
_archives[i].open(name);
@@ -1581,9 +1593,11 @@ Common::SeekableReadStream *BladeRunnerEngine::getResourceStream(const Common::S
if (!_archives[i].isOpen()) {
continue;
}
+
if (false) {
debug("getResource: Searching archive %s for %s.", _archives[i].getName().c_str(), name.c_str());
}
+
Common::SeekableReadStream *stream = _archives[i].createReadStreamForMember(name);
if (stream) {
return stream;
diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp
index 6f5c7153b6..5dfd3f47ae 100644
--- a/engines/bladerunner/debugger.cpp
+++ b/engines/bladerunner/debugger.cpp
@@ -56,6 +56,7 @@ Debugger::Debugger(BladeRunnerEngine *vm) : GUI::Debugger() {
_vm = vm;
_viewSceneObjects = false;
+ _viewActorsOnly = false;
_viewUI = false;
_viewZBuffer = false;
@@ -107,7 +108,7 @@ bool Debugger::cmdAnimation(int argc, const char **argv) {
bool Debugger::cmdDraw(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Enables debug rendering of scene objects, ui elements, zbuffer or disables debug rendering.\n");
- debugPrintf("Usage: %s (obj | ui | zbuf | reset)\n", argv[0]);
+ debugPrintf("Usage: %s (obj | actors | ui | zbuf | reset)\n", argv[0]);
return true;
}
@@ -115,6 +116,10 @@ bool Debugger::cmdDraw(int argc, const char **argv) {
if (arg == "obj") {
_viewSceneObjects = !_viewSceneObjects;
debugPrintf("Drawing scene objects = %i\n", _viewSceneObjects);
+ } else if (arg == "actors") {
+ _viewSceneObjects = !_viewSceneObjects;
+ _viewActorsOnly = _viewSceneObjects;
+ debugPrintf("Drawing scene actors = %i\n", _viewSceneObjects);
} else if (arg == "ui") {
_viewUI = !_viewUI;
debugPrintf("Drawing UI elements = %i\n", _viewUI);
@@ -389,6 +394,9 @@ void Debugger::drawSceneObjects() {
Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (a + b));
int color;
+ if (_viewActorsOnly && sceneObject->type != kSceneObjectTypeActor)
+ continue;
+
switch (sceneObject->type) {
case kSceneObjectTypeUnknown:
break;
@@ -421,6 +429,9 @@ void Debugger::drawSceneObjects() {
}
}
+ if (_viewActorsOnly)
+ return;
+
//draw regions
for (int i = 0; i < 10; i++) {
Regions::Region *region = &_vm->_scene->_regions->_regions[i];
diff --git a/engines/bladerunner/debugger.h b/engines/bladerunner/debugger.h
index bfe4e49b9b..e507e8c176 100644
--- a/engines/bladerunner/debugger.h
+++ b/engines/bladerunner/debugger.h
@@ -41,6 +41,7 @@ class Debugger : public GUI::Debugger{
public:
bool _viewSceneObjects;
+ bool _viewActorsOnly;
bool _viewUI;
bool _viewZBuffer;
diff --git a/engines/bladerunner/obstacles.cpp b/engines/bladerunner/obstacles.cpp
index ada41df7b3..69d1ba47c3 100644
--- a/engines/bladerunner/obstacles.cpp
+++ b/engines/bladerunner/obstacles.cpp
@@ -38,6 +38,8 @@ Obstacles::Obstacles(BladeRunnerEngine *vm) {
Obstacles::~Obstacles() {
delete[] _vertices;
+ delete[] _polygonsBackup;
+ delete[] _polygons;
}
void Obstacles::clear() {
diff --git a/engines/bladerunner/screen_effects.h b/engines/bladerunner/screen_effects.h
index ad0fb5090f..d16f1cf284 100644
--- a/engines/bladerunner/screen_effects.h
+++ b/engines/bladerunner/screen_effects.h
@@ -39,12 +39,12 @@ class ScreenEffects {
public:
struct Entry {
Color256 palette[16];
- uint16 x;
- uint16 y;
- uint16 width;
- uint16 height;
- uint16 z;
- uint8 *data;
+ uint16 x;
+ uint16 y;
+ uint16 width;
+ uint16 height;
+ uint16 z;
+ uint8 *data;
};
BladeRunnerEngine *_vm;
@@ -58,7 +58,7 @@ public:
~ScreenEffects();
void readVqa(Common::SeekableReadStream *stream);
- void getColor(Color256 *outColor, uint16 x, uint16 y, uint16 z) const ;
+ void getColor(Color256 *outColor, uint16 x, uint16 y, uint16 z) const;
//TODO
//bool isAffectingArea(int x, int y, int width, int height, int unk);
diff --git a/engines/bladerunner/ui/end_credits.cpp b/engines/bladerunner/ui/end_credits.cpp
index 1ab0b9f8a3..6d964d0290 100644
--- a/engines/bladerunner/ui/end_credits.cpp
+++ b/engines/bladerunner/ui/end_credits.cpp
@@ -160,6 +160,9 @@ void EndCredits::show() {
free(textPositions);
delete textResource;
+ delete fontSmall;
+ delete fontBig;
+
_vm->_music->stop(0);
_vm->_mouse->enable();
}
diff --git a/engines/cge/cge.h b/engines/cge/cge.h
index d3f8a93c1d..668224d2f7 100644
--- a/engines/cge/cge.h
+++ b/engines/cge/cge.h
@@ -246,7 +246,7 @@ public:
void mainLoop();
void handleFrame();
void saveGame(int slotNumber, const Common::String &desc);
- static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
void switchMusic();
void selectPocket(int n);
void expandSprite(Sprite *spr);
diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp
index b60f201cb0..fcbbf34a4d 100644
--- a/engines/cge/cge_main.cpp
+++ b/engines/cge/cge_main.cpp
@@ -242,10 +242,6 @@ bool CGEEngine::loadGame(int slotNumber, SavegameHeader *header, bool tiny) {
delete readStream;
return true;
}
-
- // Delete the thumbnail
- saveHeader.thumbnail->free();
- delete saveHeader.thumbnail;
}
// Get in the savegame
@@ -424,9 +420,7 @@ void CGEEngine::syncGame(Common::SeekableReadStream *readStream, Common::WriteSt
}
}
-bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
- header.thumbnail = nullptr;
-
+WARN_UNUSED_RESULT bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) {
// Get the savegame version
header.version = in->readByte();
if (header.version > kSavegameVersion)
@@ -439,9 +433,9 @@ bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &heade
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp
index 482591bf50..cae2e036b9 100644
--- a/engines/cge/detection.cpp
+++ b/engines/cge/detection.cpp
@@ -221,10 +221,6 @@ SaveStateList CGEMetaEngine::listSaves(const char *target) const {
// Valid savegame
if (CGE::CGEEngine::readSavegameHeader(file, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
}
} else {
// Must be an original format savegame
@@ -253,7 +249,7 @@ SaveStateDescriptor CGEMetaEngine::querySaveMetaInfos(const char *target, int sl
f->read(buffer, kSavegameStrSize + 1);
bool hasHeader = !strncmp(buffer, CGE::savegameStr, kSavegameStrSize + 1) &&
- CGE::CGEEngine::readSavegameHeader(f, header);
+ CGE::CGEEngine::readSavegameHeader(f, header, false);
delete f;
if (!hasHeader) {
diff --git a/engines/cge/vga13h.cpp b/engines/cge/vga13h.cpp
index 4d3a103663..a7e065fe01 100644
--- a/engines/cge/vga13h.cpp
+++ b/engines/cge/vga13h.cpp
@@ -707,7 +707,7 @@ uint8 Vga::closest(Dac *pal, const uint8 colR, const uint8 colG, const uint8 col
uint16 D = ((r > R) ? (r - R) : (R - r)) +
((g > G) ? (g - G) : (G - g)) +
((b > B) ? (b - B) : (B - b)) +
- ((l > L) ? (l - L) : (L - l)) * 10 ;
+ ((l > L) ? (l - L) : (L - l)) * 10;
if (D < dif) {
found = i;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 18f919b5eb..899520c6dd 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -161,7 +161,7 @@ public:
virtual Common::Error loadGameState(int slot);
virtual Common::Error run();
- static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
GUI::Debugger *getDebugger() {
return _console;
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index d05dfffedc..68f16d8dc9 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -221,10 +221,6 @@ SaveStateList CGE2MetaEngine::listSaves(const char *target) const {
// Valid savegame
if (CGE2::CGE2Engine::readSavegameHeader(file, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
}
} else {
// Must be an original format savegame
@@ -253,7 +249,7 @@ SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int s
f->read(buffer, kSavegameStrSize + 1);
bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) &&
- CGE2::CGE2Engine::readSavegameHeader(f, header);
+ CGE2::CGE2Engine::readSavegameHeader(f, header, false);
delete f;
if (!hasHeader) {
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index cd0be84567..83cba5316d 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -117,10 +117,6 @@ bool CGE2Engine::loadGame(int slotNumber) {
delete readStream;
return false;
}
-
- // Delete the thumbnail
- saveHeader.thumbnail->free();
- delete saveHeader.thumbnail;
}
resetGame();
@@ -180,9 +176,7 @@ void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &h
out->writeSint16LE(td.tm_min);
}
-bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
- header.thumbnail = nullptr;
-
+WARN_UNUSED_RESULT bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) {
// Get the savegame version
header.version = in->readByte();
if (header.version > kSavegameVersion)
@@ -195,9 +189,9 @@ bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &head
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 8b0d8b6c77..8b8acb6ade 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -938,13 +938,13 @@ uint8 Vga::closest(Dac *pal, const uint8 colR, const uint8 colG, const uint8 col
uint16 D = ((r > R) ? (r - R) : (R - r)) +
((g > G) ? (g - G) : (G - g)) +
((b > B) ? (b - B) : (B - b)) +
- ((l > L) ? (l - L) : (L - l)) * 10 ;
+ ((l > L) ? (l - L) : (L - l)) * 10;
if (D < dif) {
found = i;
dif = D;
if (D == 0)
- break; // exact!
+ break; // exact!
}
}
return found;
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
index 6f5d236173..3dfd414fd2 100644
--- a/engines/cruise/detection.cpp
+++ b/engines/cruise/detection.cpp
@@ -241,9 +241,8 @@ SaveStateList CruiseMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
Cruise::CruiseSavegameHeader header;
- Cruise::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- delete header.thumbnail;
+ if (Cruise::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
delete in;
}
}
@@ -264,7 +263,11 @@ SaveStateDescriptor CruiseMetaEngine::querySaveMetaInfos(const char *target, int
if (f) {
Cruise::CruiseSavegameHeader header;
- Cruise::readSavegameHeader(f, header);
+ if (!Cruise::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp
index a62648df08..7aaeb06905 100644
--- a/engines/cruise/saveload.cpp
+++ b/engines/cruise/saveload.cpp
@@ -43,9 +43,8 @@ struct overlayRestoreTemporary {
overlayRestoreTemporary ovlRestoreData[90];
-bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header) {
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[6];
- header.thumbnail = NULL;
// Validate the header Id
in->read(saveIdentBuffer, 6);
@@ -62,9 +61,9 @@ bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header) {
while ((ch = (char)in->readByte()) != '\0') header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
return true;
}
@@ -827,8 +826,10 @@ Common::Error loadSavegameData(int saveGameIdx) {
// Skip over the savegame header
CruiseSavegameHeader header;
- readSavegameHeader(f, header);
- delete header.thumbnail;
+ if (!readSavegameHeader(f, header)) {
+ delete f;
+ return Common::kReadingFailed;
+ }
// Synchronise the remaining data of the savegame
Common::Serializer s(f, NULL);
diff --git a/engines/cruise/saveload.h b/engines/cruise/saveload.h
index 6fb1f4b545..c92f0e9da5 100644
--- a/engines/cruise/saveload.h
+++ b/engines/cruise/saveload.h
@@ -38,7 +38,7 @@ struct CruiseSavegameHeader {
Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName);
Common::Error loadSavegameData(int saveGameIdx);
-bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header);
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header, bool skipThumbnail = true);
void initVars();
} // End of namespace Cruise
diff --git a/engines/cryo/eden.cpp b/engines/cryo/eden.cpp
index 103d9fde9e..220b4bbb41 100644
--- a/engines/cryo/eden.cpp
+++ b/engines/cryo/eden.cpp
@@ -2321,7 +2321,7 @@ void EdenGame::my_bulle() {
} else if (c >= 0x80 && c < 0x90)
SysBeep(1);
else if (c >= 0x90 && c < 0xA0) {
- while (*textPtr++ != 0xFF) ;
+ while (*textPtr++ != 0xFF);
textPtr--;
} else if (c >= 0xA0 && c < 0xC0)
_globals->_textToken1 = c & 0xF;
@@ -2333,7 +2333,7 @@ void EdenGame::my_bulle() {
#ifdef FAKE_DOS_VERSION
_globals->_textWidthLimit = c1 + 160;
#else
- _globals->_textWidthLimit = c1 + _subtitlesXCenter; //TODO: signed? 160 in pc ver
+ _globals->_textWidthLimit = c1 + _subtitlesXCenter; // TODO: signed? 160 in pc ver
#endif
else {
byte c2 = *textPtr++;
diff --git a/engines/dm/dm.h b/engines/dm/dm.h
index 16307778ba..e330cb6be7 100644
--- a/engines/dm/dm.h
+++ b/engines/dm/dm.h
@@ -332,7 +332,7 @@ public:
Thing _thingParty; // @ C0xFFFF_THING_PARTY
};
-bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header);
+WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header, bool skipThumbnail = true);
} // End of namespace DM
diff --git a/engines/dm/loadsave.cpp b/engines/dm/loadsave.cpp
index 3d8f76c33f..864a726367 100644
--- a/engines/dm/loadsave.cpp
+++ b/engines/dm/loadsave.cpp
@@ -70,7 +70,10 @@ LoadgameResult DMEngine::loadgame(int16 slot) {
file = saveFileManager->openForLoading(fileName);
SaveGameHeader header;
- readSaveGameHeader(file, &header);
+ if (!readSaveGameHeader(file, &header)) {
+ delete file;
+ return kDMLoadgameFailure;
+ }
warning("MISSING CODE: missing check for matching format and platform in save in f435_loadgame");
@@ -397,7 +400,7 @@ bool DMEngine::writeCompleteSaveFile(int16 saveSlot, Common::String& saveDescrip
return true;
}
-bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header) {
+WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header, bool skipThumbnail) {
uint32 id = in->readUint32BE();
// Check if it's a valid ScummVM savegame
@@ -419,7 +422,11 @@ bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header) {
header->_descr.setDescription(saveName);
// Get the thumbnail
- header->_descr.setThumbnail(Graphics::loadThumbnail(*in));
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail, skipThumbnail)) {
+ return false;
+ }
+ header->_descr.setThumbnail(thumbnail);
uint32 saveDate = in->readUint32BE();
uint16 saveTime = in->readUint16BE();
diff --git a/engines/draci/detection.cpp b/engines/draci/detection.cpp
index 65427bd8cd..9a76e3890c 100644
--- a/engines/draci/detection.cpp
+++ b/engines/draci/detection.cpp
@@ -132,10 +132,6 @@ SaveStateList DraciMetaEngine::listSaves(const char *target) const {
Draci::DraciSavegameHeader header;
if (Draci::readSavegameHeader(in, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
}
delete in;
}
@@ -157,7 +153,11 @@ SaveStateDescriptor DraciMetaEngine::querySaveMetaInfos(const char *target, int
if (f) {
Draci::DraciSavegameHeader header;
- Draci::readSavegameHeader(f, header);
+ if (!Draci::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/draci/saveload.cpp b/engines/draci/saveload.cpp
index 3e7f8651c1..e30af5375e 100644
--- a/engines/draci/saveload.cpp
+++ b/engines/draci/saveload.cpp
@@ -35,9 +35,8 @@ namespace Draci {
static const char *const draciIdentString = "DRACI";
-bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) {
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[6];
- header.thumbnail = NULL;
// Validate the header Id
in->read(saveIdentBuffer, 6);
@@ -59,9 +58,9 @@ bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) {
header.playtime = in->readUint32LE();
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
return true;
}
@@ -130,10 +129,6 @@ Common::Error loadSavegameData(int saveGameIdx, DraciEngine *vm) {
if (!readSavegameHeader(f, header)) {
return Common::kNoGameDataFoundError;
}
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
// Pre-processing
vm->_game->rememberRoomNumAsPrevious();
diff --git a/engines/draci/saveload.h b/engines/draci/saveload.h
index 6f951a3409..bceaebb468 100644
--- a/engines/draci/saveload.h
+++ b/engines/draci/saveload.h
@@ -42,7 +42,7 @@ struct DraciSavegameHeader {
class DraciEngine;
-bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header);
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header, bool skipThumbnail = true);
void writeSavegameHeader(Common::OutSaveFile *out, const DraciSavegameHeader &header);
Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName, DraciEngine &vm);
Common::Error loadSavegameData(int saveGameIdx, DraciEngine *vm);
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index 5f453839e7..a1f2f3e117 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -430,7 +430,11 @@ SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, i
return SaveStateDescriptor();
}
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ delete in;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
delete in;
diff --git a/engines/dreamweb/detection.cpp b/engines/dreamweb/detection.cpp
index 11966047b0..36af0c3811 100644
--- a/engines/dreamweb/detection.cpp
+++ b/engines/dreamweb/detection.cpp
@@ -198,7 +198,12 @@ SaveStateDescriptor DreamWebMetaEngine::querySaveMetaInfos(const char *target, i
uint32 saveDate = in->readUint32LE();
uint32 saveTime = in->readUint32LE();
uint32 playTime = in->readUint32LE();
- Graphics::Surface *thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ warning("Missing or broken thumbnail - skipping");
+ delete in;
+ return desc;
+ }
int day = (saveDate >> 24) & 0xFF;
int month = (saveDate >> 16) & 0xFF;
diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp
index 9dd1d6beb4..3144a0ebff 100644
--- a/engines/fullpipe/detection.cpp
+++ b/engines/fullpipe/detection.cpp
@@ -184,7 +184,9 @@ SaveStateList FullpipeMetaEngine::listSaves(const char *target) const {
Common::ScopedPtr<Common::InSaveFile> in(saveFileMan->openForLoading(*file));
if (in) {
Fullpipe::FullpipeSavegameHeader header;
- Fullpipe::readSavegameHeader(in.get(), header);
+ if (!Fullpipe::readSavegameHeader(in.get(), header)) {
+ continue;
+ }
SaveStateDescriptor desc;
@@ -212,7 +214,9 @@ SaveStateDescriptor FullpipeMetaEngine::querySaveMetaInfos(const char *target, i
if (f) {
Fullpipe::FullpipeSavegameHeader header;
- Fullpipe::readSavegameHeader(f.get(), header);
+ if (!Fullpipe::readSavegameHeader(f.get(), header, false)) {
+ return SaveStateDescriptor();
+ }
// Create the return descriptor
SaveStateDescriptor desc;
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 03c3093086..eb5957c78e 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -84,7 +84,7 @@ struct FullpipeSavegameHeader {
uint32 date;
uint16 time;
uint32 playtime;
- Common::SharedPtr<Graphics::Surface> thumbnail;
+ Graphics::Surface *thumbnail;
};
struct SaveHeader {
@@ -142,7 +142,7 @@ class GameLoader : public CObject {
};
const char *getSavegameFile(int saveGameIdx);
-bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header);
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header, bool skipThumbnail = true);
void parseSavegameHeader(Fullpipe::FullpipeSavegameHeader &header, SaveStateDescriptor &desc);
Inventory2 *getGameLoaderInventory();
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index be1e73ff70..45ccabc7d5 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -2142,7 +2142,8 @@ bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) {
return false;
Fullpipe::FullpipeSavegameHeader header;
- Fullpipe::readSavegameHeader(f.get(), header);
+ if (!Fullpipe::readSavegameHeader(f.get(), header))
+ return false;
// Create the return descriptor
SaveStateDescriptor desc(slot, header.saveName);
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 9d4d5ab09a..250c527f40 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -193,7 +193,7 @@ void fillDummyHeader(Fullpipe::FullpipeSavegameHeader &header) {
header.playtime = 0;
}
-bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header) {
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header, bool skipThumbnail) {
uint oldPos = in->pos();
in->seek(-4, SEEK_END);
@@ -237,13 +237,13 @@ bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header)
header.description = header.saveName;
// Get the thumbnail
- header.thumbnail = Common::SharedPtr<Graphics::Surface>(Graphics::loadThumbnail(*in), Graphics::SurfaceDeleter());
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ in->seek(oldPos, SEEK_SET); // Rewind the file
+ return false;
+ }
in->seek(oldPos, SEEK_SET); // Rewind the file
- if (!header.thumbnail)
- return false;
-
return true;
}
diff --git a/engines/gnap/detection.cpp b/engines/gnap/detection.cpp
index d19d420ff8..97c9128002 100644
--- a/engines/gnap/detection.cpp
+++ b/engines/gnap/detection.cpp
@@ -141,13 +141,8 @@ SaveStateList GnapMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- Gnap::GnapEngine::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
+ if (Gnap::GnapEngine::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
delete in;
}
}
@@ -179,7 +174,11 @@ SaveStateDescriptor GnapMetaEngine::querySaveMetaInfos(const char *target, int s
SaveStateDescriptor desc(slot, saveName);
if (version != 1) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*file, thumbnail)) {
+ delete file;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
}
diff --git a/engines/gnap/gnap.cpp b/engines/gnap/gnap.cpp
index cf8710c64d..9b0015e646 100644
--- a/engines/gnap/gnap.cpp
+++ b/engines/gnap/gnap.cpp
@@ -979,7 +979,7 @@ int GnapEngine::playSoundC() {
if (!_timers[_soundTimerIndexC]) {
_timers[_soundTimerIndexC] = getRandom(50) + 150;
- soundId = kSoundIdsC[getRandom(7)] ;
+ soundId = kSoundIdsC[getRandom(7)];
playSound(soundId | 0x10000, false);
}
return soundId;
diff --git a/engines/gnap/gnap.h b/engines/gnap/gnap.h
index dbefa31795..dd653304e7 100644
--- a/engines/gnap/gnap.h
+++ b/engines/gnap/gnap.h
@@ -319,7 +319,7 @@ public:
Common::String generateSaveName(int slot);
void synchronize(Common::Serializer &s);
void writeSavegameHeader(Common::OutSaveFile *out, GnapSavegameHeader &header);
- static bool readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header, bool skipThumbnail = true);
void delayTicks(int val, int idx, bool updateCursor);
void delayTicksA(int val, int idx);
diff --git a/engines/gnap/menu.cpp b/engines/gnap/menu.cpp
index 9606273b4c..34b5f18473 100644
--- a/engines/gnap/menu.cpp
+++ b/engines/gnap/menu.cpp
@@ -589,9 +589,8 @@ void GnapEngine::writeSavegameHeader(Common::OutSaveFile *out, GnapSavegameHeade
out->writeSint16LE(td.tm_min);
}
-bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header) {
+WARN_UNUSED_RESULT bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -612,9 +611,9 @@ bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &
if (header._version == 1)
header._thumbnail = nullptr;
else {
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
}
// Read in save date/time
diff --git a/engines/hopkins/detection.cpp b/engines/hopkins/detection.cpp
index 041afecaa8..ebefee6278 100644
--- a/engines/hopkins/detection.cpp
+++ b/engines/hopkins/detection.cpp
@@ -168,9 +168,6 @@ SaveStateList HopkinsMetaEngine::listSaves(const char *target) const {
if (in) {
if (Hopkins::SaveLoadManager::readSavegameHeader(in, header)) {
saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- header._thumbnail->free();
- delete header._thumbnail;
}
delete in;
@@ -198,7 +195,11 @@ SaveStateDescriptor HopkinsMetaEngine::querySaveMetaInfos(const char *target, in
if (f) {
Hopkins::hopkinsSavegameHeader header;
- Hopkins::SaveLoadManager::readSavegameHeader(f, header);
+ if (!Hopkins::SaveLoadManager::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp
index fc613f892d..b8f1c73304 100644
--- a/engines/hopkins/dialogs.cpp
+++ b/engines/hopkins/dialogs.cpp
@@ -692,7 +692,7 @@ void DialogsManager::showSaveLoad(SaveLoadMode mode) {
for (int slotNumber = 1; slotNumber <= 6; ++slotNumber) {
hopkinsSavegameHeader header;
- if (_vm->_saveLoad->readSavegameHeader(slotNumber, header)) {
+ if (_vm->_saveLoad->readSavegameHeader(slotNumber, header, false)) {
Graphics::Surface thumb8;
_vm->_saveLoad->convertThumb16To8(header._thumbnail, &thumb8);
diff --git a/engines/hopkins/saveload.cpp b/engines/hopkins/saveload.cpp
index 05c7fb8119..35a80458ff 100644
--- a/engines/hopkins/saveload.cpp
+++ b/engines/hopkins/saveload.cpp
@@ -77,9 +77,8 @@ void SaveLoadManager::load(const Common::String &file, byte *buf) {
delete savefile;
}
-bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header) {
+WARN_UNUSED_RESULT bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = NULL;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -96,9 +95,9 @@ bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegame
while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
@@ -186,10 +185,10 @@ Common::Error SaveLoadManager::loadGame(int slot) {
// Read in the savegame header
hopkinsSavegameHeader header;
- readSavegameHeader(savefile, header);
- if (header._thumbnail)
- header._thumbnail->free();
- delete header._thumbnail;
+ if (!readSavegameHeader(savefile, header)) {
+ delete savefile;
+ return Common::kReadingFailed;
+ }
// Read in the savegame data
syncSavegameData(serializer, header._version);
@@ -212,14 +211,14 @@ Common::Error SaveLoadManager::loadGame(int slot) {
return Common::kNoError;
}
-bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header) {
+WARN_UNUSED_RESULT bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header, bool skipThumbnail) {
// Try and open the save file for reading
Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(
_vm->generateSaveName(slot));
if (!savefile)
return false;
- bool result = readSavegameHeader(savefile, header);
+ bool result = readSavegameHeader(savefile, header, skipThumbnail);
delete savefile;
return result;
}
diff --git a/engines/hopkins/saveload.h b/engines/hopkins/saveload.h
index 7b4ec307f5..33234f49fa 100644
--- a/engines/hopkins/saveload.h
+++ b/engines/hopkins/saveload.h
@@ -61,9 +61,9 @@ public:
bool saveFile(const Common::String &file, const void *buf, size_t n);
void load(const Common::String &file, byte *buf);
- static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header, bool skipThumbnail = true);
void writeSavegameHeader(Common::OutSaveFile *out, hopkinsSavegameHeader &header);
- bool readSavegameHeader(int slot, hopkinsSavegameHeader &header);
+ WARN_UNUSED_RESULT bool readSavegameHeader(int slot, hopkinsSavegameHeader &header, bool skipThumbnail = true);
Common::Error saveGame(int slot, const Common::String &saveName);
Common::Error loadGame(int slot);
diff --git a/engines/hugo/detection.cpp b/engines/hugo/detection.cpp
index 4e4746c002..6d2fec5421 100644
--- a/engines/hugo/detection.cpp
+++ b/engines/hugo/detection.cpp
@@ -241,7 +241,12 @@ SaveStateDescriptor HugoMetaEngine::querySaveMetaInfos(const char *target, int s
SaveStateDescriptor desc(slot, saveName);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*file, thumbnail)) {
+ warning("Missing or broken savegame thumbnail");
+ delete file;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
uint32 saveDate = file->readUint32BE();
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 70c7e7c93c..79e1d9f494 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -256,7 +256,7 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
- if (Kyra::KyraEngine_v1::readSaveHeader(in, false, header) == Kyra::KyraEngine_v1::kRSHENoError) {
+ if (Kyra::KyraEngine_v1::readSaveHeader(in, header) == Kyra::KyraEngine_v1::kRSHENoError) {
// WORKAROUND: Old savegames are using 'German' as description for kyra3 restart game save (slot 0),
// since that looks odd we replace it by "New Game".
if (slotNum == 0 && header.gameID == Kyra::GI_KYRA3)
@@ -298,7 +298,7 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
Kyra::KyraEngine_v1::SaveHeader header;
Kyra::KyraEngine_v1::ReadSaveHeaderError error;
- error = Kyra::KyraEngine_v1::readSaveHeader(in, true, header);
+ error = Kyra::KyraEngine_v1::readSaveHeader(in, header, false);
delete in;
if (error == Kyra::KyraEngine_v1::kRSHENoError) {
diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h
index 1401d59dae..d214da0944 100644
--- a/engines/kyra/eobcommon.h
+++ b/engines/kyra/eobcommon.h
@@ -885,7 +885,7 @@ protected:
void inflictMonsterDamage(EoBMonsterInPlay *m, int damage, bool giveExperience);
void calcAndInflictMonsterDamage(EoBMonsterInPlay *m, int times, int pips, int offs, int flags, int savingThrowType, int savingThrowEffect);
void calcAndInflictCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int savingThrowEffect);
- int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int damageType) ;
+ int calcCharacterDamage(int charIndex, int times, int itemOrPips, int useStrModifierOrBase, int flags, int savingThrowType, int damageType);
void inflictCharacterDamage(int charIndex, int damage);
bool characterAttackHitTest(int charIndex, int monsterIndex, int item, int attackType);
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 4de7494510..bbbd59a4b8 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -416,7 +416,7 @@ protected:
kRSHEIoError = 3
};
- static ReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *file, bool loadThumbnail, SaveHeader &header);
+ WARN_UNUSED_RESULT static ReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *file, SaveHeader &header, bool skipThumbnail = true);
void loadGameStateCheck(int slot);
virtual Common::Error loadGameState(int slot) = 0;
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index b44850f5c9..c306d6cb5d 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -37,12 +37,11 @@
namespace Kyra {
-KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+WARN_UNUSED_RESULT KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) {
uint32 type = in->readUint32BE();
header.originalSave = false;
header.oldHeader = false;
header.flags = 0;
- header.thumbnail = 0;
if (type == MKTAG('K', 'Y', 'R', 'A') || type == MKTAG('A', 'R', 'Y', 'K')) { // old Kyra1 header ID
header.gameID = GI_KYRA1;
@@ -125,10 +124,8 @@ KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekabl
header.flags = in->readUint32BE();
if (header.version >= 14) {
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*in);
- } else {
- Graphics::skipThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ return kRSHEIoError;
}
}
@@ -140,7 +137,7 @@ Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filena
if (!(in = _saveFileMan->openForLoading(filename)))
return 0;
- ReadSaveHeaderError errorCode = KyraEngine_v1::readSaveHeader(in, false, header);
+ ReadSaveHeaderError errorCode = KyraEngine_v1::readSaveHeader(in, header);
if (errorCode != kRSHENoError) {
if (errorCode == kRSHEInvalidType)
warning("No ScummVM Kyra engine savefile header");
diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp
index 6c1bd572e1..3a9a647fa5 100644
--- a/engines/kyra/screen_eob.cpp
+++ b/engines/kyra/screen_eob.cpp
@@ -499,7 +499,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y,
int16 dX = x - (_dsX1 << 3);
int16 dY = y;
int16 dW = _dsX2 - _dsX1;
- uint8 pixelsPerByte = *src++ ;
+ uint8 pixelsPerByte = *src++;
uint16 dH = *src++;
uint16 width = (*src++) << 3;
@@ -1211,7 +1211,7 @@ void Screen_EoB::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, ui
if (t <= v && (ii == rootColor || ii != i)) {
v = t;
- col = ii ;
+ col = ii;
}
}
*dst++ = col;
diff --git a/engines/kyra/sequences_darkmoon.cpp b/engines/kyra/sequences_darkmoon.cpp
index 53a30d0079..68d6f752e0 100644
--- a/engines/kyra/sequences_darkmoon.cpp
+++ b/engines/kyra/sequences_darkmoon.cpp
@@ -876,7 +876,7 @@ void DarkMoonEngine::seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *da
const uint8 *shp = sq->_shapes[(*++posOld) - 1];
items[i + 1].data = shp;
items[i + 1].size = shp[1];
- items[i + 1].x = (dm->w - shp[2]) << 2 ;
+ items[i + 1].x = (dm->w - shp[2]) << 2;
items[i + 1].dataType = 1;
delete[] items[i + 1].str;
items[i + 1].str = 0;
diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp
index 942cf16502..7ee1ad7e4b 100644
--- a/engines/kyra/sequences_hof.cpp
+++ b/engines/kyra/sequences_hof.cpp
@@ -3378,7 +3378,7 @@ void KyraEngine_HoF::seq_showStarcraftLogo() {
int KyraEngine_HoF::seq_playIntro() {
bool startupSaveLoadable = saveFileLoadable(0);
- return SeqPlayer_HOF(this, _screen, _system, startupSaveLoadable).play(kSequenceVirgin, startupSaveLoadable? kSequenceTitle : kSequenceNoLooping);
+ return SeqPlayer_HOF(this, _screen, _system, startupSaveLoadable).play(kSequenceVirgin, startupSaveLoadable ? kSequenceTitle : kSequenceNoLooping);
}
int KyraEngine_HoF::seq_playOutro() {
diff --git a/engines/lab/lab.h b/engines/lab/lab.h
index 2a1e527098..aedf0181ec 100644
--- a/engines/lab/lab.h
+++ b/engines/lab/lab.h
@@ -502,7 +502,7 @@ private:
void handleTrialWarning();
};
-bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header);
+WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail = true);
} // End of namespace Lab
diff --git a/engines/lab/savegame.cpp b/engines/lab/savegame.cpp
index 656595e3e5..46ef1486f0 100644
--- a/engines/lab/savegame.cpp
+++ b/engines/lab/savegame.cpp
@@ -76,7 +76,7 @@ void LabEngine::writeSaveGameHeader(Common::OutSaveFile *out, const Common::Stri
out->writeUint32BE(playTime);
}
-bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
+WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail) {
uint32 id = in->readUint32BE();
// Check if it's a valid ScummVM savegame
@@ -98,7 +98,11 @@ bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
header._descr.setDescription(saveName);
// Get the thumbnail
- header._descr.setThumbnail(Graphics::loadThumbnail(*in));
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail, skipThumbnail)) {
+ return false;
+ }
+ header._descr.setThumbnail(thumbnail);
uint32 saveDate = in->readUint32BE();
uint16 saveTime = in->readUint16BE();
@@ -174,7 +178,11 @@ bool LabEngine::loadGame(int slot) {
return false;
SaveGameHeader header;
- readSaveGameHeader(file, header);
+ if (!readSaveGameHeader(file, header)) {
+ delete file;
+ return false;
+ }
+
_roomNum = file->readUint16LE();
_music->checkRoomMusic(1, _roomNum);
_direction = file->readUint16LE();
diff --git a/engines/lilliput/detection.cpp b/engines/lilliput/detection.cpp
index a09e5f05de..466c89e362 100644
--- a/engines/lilliput/detection.cpp
+++ b/engines/lilliput/detection.cpp
@@ -233,7 +233,11 @@ SaveStateDescriptor LilliputMetaEngine::querySaveMetaInfos(const char *target, i
SaveStateDescriptor desc(slot, saveName);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*file, thumbnail)) {
+ delete file;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
desc.setDeletableFlag(true);
diff --git a/engines/lilliput/lilliput.cpp b/engines/lilliput/lilliput.cpp
index 70b729cc15..4624209874 100644
--- a/engines/lilliput/lilliput.cpp
+++ b/engines/lilliput/lilliput.cpp
@@ -107,6 +107,7 @@ static const byte _basisPalette[768] = {
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63
};
+
LilliputEngine::LilliputEngine(OSystem *syst, const LilliputGameDescription *gd) : Engine(syst), _gameDescription(gd) {
_system = syst;
DebugMan.addDebugChannel(kDebugEngine, "Engine", "Engine debug level");
@@ -128,7 +129,7 @@ LilliputEngine::LilliputEngine(OSystem *syst, const LilliputGameDescription *gd)
_skipDisplayFlag2 = 0;
_displayMap = false;
_debugFlag = 0;
- _byte14837 = 0;
+ _debugFlag2 = 0;
_scriptHandler = new LilliputScript(this);
_soundHandler = new LilliputSound(this);
@@ -152,44 +153,39 @@ LilliputEngine::LilliputEngine(OSystem *syst, const LilliputGameDescription *gd)
_nextCharacterIndex = 0;
_waitingSignal = -1;
_waitingSignalCharacterId = -1;
- _word1817B = 0;
+ _newModesEvaluatedNumber = 0;
_savedSurfaceUnderMousePos = Common::Point(0, 0);
_displayGreenHand = false;
_isCursorGreenHand = false;
_displayStringIndex = 0;
- _word1289D = 0;
+ _signalTimer = 0;
_numCharacters = 0;
_saveFlag = true;
_actionType = kActionNone;
- _array16C54[0] = _array16C58[3] = 1;
- _array16C54[1] = _array16C58[2] = 2;
- _array16C54[2] = _array16C58[1] = 4;
- _array16C54[3] = _array16C58[0] = 8;
+ _doorEntranceMask[0] = _doorExitMask[3] = 1;
+ _doorEntranceMask[1] = _doorExitMask[2] = 2;
+ _doorEntranceMask[2] = _doorExitMask[1] = 4;
+ _doorEntranceMask[3] = _doorExitMask[0] = 8;
for (int i = 0; i < 3; i++)
_codeEntered[i] = 0;
for (int i = 0; i < 4; i++)
- _array1692B[i] = 0;
+ _homeInDirLikelyhood[i] = 0;
for (int i = 0; i < 40; i++) {
- _characterTargetPosX[i] = 0;
- _characterTargetPosY[i] = 0;
+ _characterTargetPos[i] = Common::Point(0, 0);
_charactersToDisplay[i] = 0;
- _characterRelativePositionX[i] = -1;
- _characterRelativePositionY[i] = -1;
- _characterDisplayX[i] = 0;
- _characterDisplayY[i] = 0;
+ _characterRelativePos[i] = Common::Point(-1, -1);
+ _characterDisplay[i] = Common::Point(0, 0);
_characterMagicPuffFrame[i] = -1;
- _characterSubTargetPosX[i] = -1;
- _characterSubTargetPosY[i] = -1;
- _stingArray[i] = 0;
+ _characterSubTargetPos[i] = Common::Point(-1, -1);
+ _specialCubes[i] = 0;
- _array11D49[i] = -1;
- _characterPositionX[i] = -1;
- _characterPositionY[i] = -1;
+ _characterSignals[i] = -1;
+ _characterPos[i] = Common::Point(-1, -1);
_characterPosAltitude[i] = 0;
_characterFrameArray[i] = 0;
_characterCarried[i] = -1;
@@ -197,12 +193,11 @@ LilliputEngine::LilliputEngine(OSystem *syst, const LilliputGameDescription *gd)
_characterAboveDist[i] = 0;
_spriteSizeArray[i] = 20;
_characterDirectionArray[i] = 0;
- _rulesBuffer2_10[i] = 0;
+ _characterMobility[i] = 0;
_characterTypes[i] = 0;
_characterBehaviour[i] = 0;
- _characterHomePosX[i] = 0;
- _characterHomePosY[i] = 0;
- _array1289F[i] = -1;
+ _characterHomePos[i] = Common::Point(0, 0);
+ _signalArr[i] = -1;
}
for (int i = 0; i < 30; i++)
@@ -225,6 +220,37 @@ LilliputEngine::LilliputEngine(OSystem *syst, const LilliputGameDescription *gd)
_bufferIsoChars = NULL;
_bufferIsoMap = NULL;
_bufferCubegfx = NULL;
+
+ _sequencesArr = nullptr;
+ _packedStringIndex = nullptr;
+ _packedStringNumb = 0;
+ _packedStrings = nullptr;
+ _initScript = nullptr;
+ _initScriptSize = 0;
+ _menuScript = nullptr;
+ _menuScriptSize = 0;
+ _arrayGameScriptIndex = nullptr;
+ _gameScriptIndexSize = 0;
+ _arrayGameScripts = nullptr;
+ _listNumb = 0;
+ _listIndex = nullptr;
+ _listArr = nullptr;
+ _rectNumb = 0;
+ for (int i = 0; i < 40; ++i) {
+ _rectXMinMax[i].min = 0;
+ _rectXMinMax[i].max = 0;
+ _rectYMinMax[i].min = 0;
+ _rectYMinMax[i].max = 0;
+ }
+ _interfaceHotspotNumb = 0;
+ for (int i = 0; i < 20; ++i)
+ _keyboardMapping[i] = Common::KEYCODE_DOLLAR;
+
+ _shouldQuit = false;
+ _eventMan = nullptr;
+ _lastTime = 0;
+ _gameType = kGameTypeNone;
+ _platform = Common::kPlatformUnknown;
}
LilliputEngine::~LilliputEngine() {
@@ -258,7 +284,7 @@ void LilliputEngine::update() {
}
void LilliputEngine::newInt8() {
- _soundHandler->contentFct1();
+ _soundHandler->refresh();
if (_byte12A05 != 0)
--_byte12A05;
@@ -415,7 +441,7 @@ void LilliputEngine::displayInterfaceHotspots() {
for (int index = 0; index < _interfaceHotspotNumb; index++) {
int tmpVal = _scriptHandler->_interfaceHotspotStatus[index] * 20;
- display16x16IndexedBuf(_bufferIdeogram, tmpVal + index, Common::Point(_interfaceHotspotsX[index], _interfaceHotspotsY[index]));
+ display16x16IndexedBuf(_bufferIdeogram, tmpVal + index, _interfaceHotspots[index]);
}
}
@@ -608,46 +634,41 @@ void LilliputEngine::moveCharacters() {
if (_characterCarried[i] != -1) {
int index2 = _characterCarried[i];
_characterPosAltitude[i] = _characterPosAltitude[index2] + _characterAboveDist[i];
- int8 tmpVal = _characterBehindDist[i];
+ int8 behindDist = _characterBehindDist[i];
_characterDirectionArray[i] = _characterDirectionArray[index2];
- int var3 = _characterPositionX[index2];
- int var4 = _characterPositionY[index2];
+ int nextPosX = _characterPos[index2].x;
+ int nextPosY = _characterPos[index2].y;
switch (_characterDirectionArray[i]) {
case 0:
- var3 -= tmpVal;
+ nextPosX -= behindDist;
break;
case 1:
- var4 += tmpVal;
+ nextPosY += behindDist;
break;
case 2:
- var4 -= tmpVal;
+ nextPosY -= behindDist;
break;
default:
- var3 += tmpVal;
+ nextPosX += behindDist;
break;
}
- _characterPositionX[i] = var3;
- _characterPositionY[i] = var4;
+ _characterPos[i] = Common::Point(nextPosX, nextPosY);
}
- _scriptHandler->_characterTilePos[i] = Common::Point(_characterPositionX[i] >> 3, _characterPositionY[i] >> 3);
- _characterRelativePositionX[i] = -1;
- _characterRelativePositionY[i] = -1;
- _characterDisplayX[i] = -1;
- _characterDisplayY[i] = -1;
-
- int tmpVal2 = (_characterPositionX[i] >> 3) - _scriptHandler->_viewportPos.x;
- int tmpVal3 = (_characterPositionY[i] >> 3) - _scriptHandler->_viewportPos.y;
- if ((tmpVal2 >= 0) && (tmpVal2 <= 7) && (tmpVal3 >= 0) && (tmpVal3 <= 7)) {
- _characterRelativePositionX[i] = tmpVal2;
- _characterRelativePositionY[i] = tmpVal3;
- tmpVal2 = _characterPositionX[i] - pos16213.x;
- tmpVal3 = _characterPositionY[i] - pos16213.y;
- int tmpVal4 = _characterPosAltitude[i];
- _characterDisplayX[i] = ((60 + tmpVal2 - tmpVal3) * 2) & 0xFF;
- _characterDisplayY[i] = (20 + tmpVal2 + tmpVal3 - tmpVal4) & 0xFF;
+ _scriptHandler->_characterTilePos[i] = Common::Point(_characterPos[i].x >> 3, _characterPos[i].y >> 3);
+ _characterRelativePos[i] = Common::Point(-1, -1);
+ _characterDisplay[i] = Common::Point(-1, -1);
+
+ int tileX = (_characterPos[i].x >> 3) - _scriptHandler->_viewportPos.x;
+ int tileY = (_characterPos[i].y >> 3) - _scriptHandler->_viewportPos.y;
+ if ((tileX >= 0) && (tileX <= 7) && (tileY >= 0) && (tileY <= 7)) {
+ _characterRelativePos[i] = Common::Point(tileX, tileY);
+ int tempX = _characterPos[i].x - pos16213.x;
+ int tempY = _characterPos[i].y - pos16213.y;
+ _characterDisplay[i].x = ((60 + tempX - tempY) * 2) & 0xFF;
+ _characterDisplay[i].y = (20 + tempX + tempY - _characterPosAltitude[i]) & 0xFF;
_charactersToDisplay[_numCharactersToDisplay] = i;
++_numCharactersToDisplay;
}
@@ -662,10 +683,9 @@ void LilliputEngine::setNextDisplayCharacter(int var1) {
byte charNum = var1 & 0xFF;
if (charNum < _numCharactersToDisplay) {
int index = _charactersToDisplay[charNum];
- _nextDisplayCharacterPos = Common::Point(_characterRelativePositionX[index], _characterRelativePositionY[index]);
- } else {
+ _nextDisplayCharacterPos = _characterRelativePos[index];
+ } else
_nextDisplayCharacterPos = Common::Point(-1, -1);
- }
}
void LilliputEngine::prepareGameArea() {
@@ -685,7 +705,7 @@ void LilliputEngine::prepareGameArea() {
for (int posX = 0; posX < 8; posX++) {
if (map[1] != 0xFF) {
int var1 = map[1];
- if ((_rulesChunk9[var1] & 128) != 0)
+ if ((_cubeFlags[var1] & 128) != 0)
var1 += _animationTick;
displayIsometricBlock(_savedSurfaceGameArea1, var1, posX, posY, 1 << 8);
}
@@ -693,7 +713,7 @@ void LilliputEngine::prepareGameArea() {
if (map[2] != 0xFF) {
int var1 = map[2];
- if ((_rulesChunk9[var1] & 128) != 0)
+ if ((_cubeFlags[var1] & 128) != 0)
var1 += _animationTick;
displayIsometricBlock(_savedSurfaceGameArea1, var1, posX, posY, 2 << 8);
}
@@ -714,10 +734,10 @@ void LilliputEngine::displayRefreshScreen() {
restoreMapPoints();
updateCharPosSequence();
- sub12F37();
- sub16CA0();
- sub16EBC();
- sub171CF();
+ handleCharacterTimers();
+ checkInteractions();
+ checkSpecialCubes();
+ handleSignals();
displayCharactersOnMap();
} else {
scrollToViewportCharacterTarget();
@@ -725,10 +745,10 @@ void LilliputEngine::displayRefreshScreen() {
prepareGameArea();
displayGameArea();
updateCharPosSequence();
- sub12F37();
- sub16CA0();
- sub16EBC();
- sub171CF();
+ handleCharacterTimers();
+ checkInteractions();
+ checkSpecialCubes();
+ handleSignals();
handleGameMouseClick();
checkInterfaceActivationDelay();
displayHeroismIndicator();
@@ -807,8 +827,8 @@ void LilliputEngine::paletteFadeIn() {
}
}
-int16 LilliputEngine::sub16DD5(int x1, int y1, int x2, int y2) {
- debugC(2, kDebugEngine, "sub16DD5(%d, %d, %d, %d)", x1, y1, x2, y2);
+int16 LilliputEngine::checkObstacle(int x1, int y1, int x2, int y2) {
+ debugC(2, kDebugEngine, "checkObstacle(%d, %d, %d, %d)", x1, y1, x2, y2);
int index = ((y1 * 64) + x1) * 4;
assert((index > 0) && (index <= 16380));
@@ -822,8 +842,8 @@ int16 LilliputEngine::sub16DD5(int x1, int y1, int x2, int y2) {
int16 mapMoveY = 0;
int16 mapMoveX = 0;
- int16 byte16DD4 = 0;
- int16 byte16DD3 = 0;
+ int16 nonDiagdelta = 0;
+ int16 diagDelta = 0;
if (dx < 0) {
dx = -dx;
@@ -850,9 +870,9 @@ int16 LilliputEngine::sub16DD5(int x1, int y1, int x2, int y2) {
mapMoveY = tmpMapMoveY;
}
- byte16DD4 = dy * 2;
- int16 var1 = byte16DD4 - dx;
- byte16DD3 = byte16DD4 - (dx * 2);
+ nonDiagdelta = dy * 2;
+ int16 var1 = nonDiagdelta - dx;
+ diagDelta = nonDiagdelta - (dx * 2);
mapMoveX += mapMoveY;
tmpMapMoveX += tmpMapMoveY;
@@ -862,10 +882,10 @@ int16 LilliputEngine::sub16DD5(int x1, int y1, int x2, int y2) {
while (*isoMap == 0xFF) {
if (var1 >= 0) {
isoMap += tmpMapMoveX;
- var1 += byte16DD3;
+ var1 += diagDelta;
} else {
isoMap += mapMoveX;
- var1 += byte16DD4;
+ var1 += nonDiagdelta;
}
count++;
@@ -876,8 +896,8 @@ int16 LilliputEngine::sub16DD5(int x1, int y1, int x2, int y2) {
return tmpMapMoveY;
}
-void LilliputEngine::sub15F75() {
- debugC(2, kDebugEngineTBC, "sub15F75()");
+void LilliputEngine::startNavigateFromMap() {
+ debugC(2, kDebugEngine, "startNavigateFromMap()");
_selectedCharacterId = -1;
_savedMousePosDivided = Common::Point(-1, -1);
@@ -915,7 +935,7 @@ void LilliputEngine::checkMapClosing(bool &forceReturnFl) {
return;
_mouseButton = 0;
- sub15F75();
+ startNavigateFromMap();
}
_displayMap = false;
@@ -929,8 +949,8 @@ void LilliputEngine::checkMapClosing(bool &forceReturnFl) {
forceReturnFl = true;
}
-void LilliputEngine::sub16CA0() {
- debugC(2, kDebugEngine, "sub16CA0()");
+void LilliputEngine::checkInteractions() {
+ debugC(2, kDebugEngine, "checkInteractions()");
for (int index = _numCharacters - 1; index >= 0; index--) {
if (_characterTypes[index] & 1)
@@ -944,7 +964,7 @@ void LilliputEngine::sub16CA0() {
continue;
for (int index2 = _numCharacters - 1; index2 >= 0; index2--) {
- byte byte16C9F = 0;
+ byte _newStatus = 0;
if ((index != index2) &&
(_characterCarried[index] != index2) &&
(_characterCarried[index2] != index) &&
@@ -957,56 +977,56 @@ void LilliputEngine::sub16CA0() {
if ((x > -6) && (x < 6)) {
int y = c2 - d2;
if ((y > -6) && (y < 6)) {
- byte16C9F = 1;
+ _newStatus = 1;
if ((c1 == d1) && (c2 == d2)) {
- byte16C9F = 4;
+ _newStatus = 4;
} else if ((_characterTypes[index] & 4) != 0) {
- byte16C9F = 0;
+ _newStatus = 0;
} else {
switch (_characterDirectionArray[index]) {
case 0:
if (d1 > c1) {
- byte16C9F = 2;
+ _newStatus = 2;
if (d2 == c2)
- byte16C9F = 3;
+ _newStatus = 3;
- if (sub16DD5(c1, c2, d1, d2) != 0)
- byte16C9F = 1;
+ if (checkObstacle(c1, c2, d1, d2) != 0)
+ _newStatus = 1;
}
break;
case 1:
if (d2 < c2) {
- byte16C9F = 2;
+ _newStatus = 2;
if (d1 == c1)
- byte16C9F = 3;
+ _newStatus = 3;
- if (sub16DD5(c1, c2, d1, d2) != 0)
- byte16C9F = 1;
+ if (checkObstacle(c1, c2, d1, d2) != 0)
+ _newStatus = 1;
}
break;
case 2:
if (d2 > c2) {
- byte16C9F = 2;
+ _newStatus = 2;
if (d1 == c1)
- byte16C9F = 3;
+ _newStatus = 3;
- if (sub16DD5(c1, c2, d1, d2) != 0)
- byte16C9F = 1;
+ if (checkObstacle(c1, c2, d1, d2) != 0)
+ _newStatus = 1;
}
break;
default:
if (d1 < c1) {
- byte16C9F = 2;
+ _newStatus = 2;
if (d2 == c2)
- byte16C9F = 3;
+ _newStatus = 3;
- if (sub16DD5(c1, c2, d1, d2) != 0)
- byte16C9F = 1;
+ if (checkObstacle(c1, c2, d1, d2) != 0)
+ _newStatus = 1;
}
break;
}
@@ -1019,9 +1039,9 @@ void LilliputEngine::sub16CA0() {
int8 v2 = _scriptHandler->_interactions[index2 + (index * 40)] & 0xFF;
int8 v1 = v2;
- if (v2 != byte16C9F) {
+ if (v2 != _newStatus) {
_scriptHandler->_characterScriptEnabled[index] = 1;
- v2 = byte16C9F;
+ v2 = _newStatus;
}
_scriptHandler->_interactions[index2 + (index * 40)] = (v1 << 8) + v2;
}
@@ -1100,19 +1120,19 @@ void LilliputEngine::sortCharacters() {
int index1 = _charactersToDisplay[var2];
int index2 = _charactersToDisplay[var2 + 1];
- if (_characterRelativePositionY[index1] < _characterRelativePositionY[index2])
+ if (_characterRelativePos[index1].y < _characterRelativePos[index2].y)
continue;
- if (_characterRelativePositionY[index1] == _characterRelativePositionY[index2]) {
- if (_characterRelativePositionX[index1] < _characterRelativePositionX[index2])
+ if (_characterRelativePos[index1].y == _characterRelativePos[index2].y) {
+ if (_characterRelativePos[index1].x < _characterRelativePos[index2].x)
continue;
- if (_characterRelativePositionX[index1] == _characterRelativePositionX[index2]) {
+ if (_characterRelativePos[index1].x == _characterRelativePos[index2].x) {
if (_characterPosAltitude[index1] < _characterPosAltitude[index2])
continue;
if (_characterPosAltitude[index1] == _characterPosAltitude[index2]) {
- if (_characterDisplayY[index1] < _characterDisplayY[index2])
+ if (_characterDisplay[index1].y < _characterDisplay[index2].y)
continue;
}
}
@@ -1135,12 +1155,12 @@ void LilliputEngine::scrollToViewportCharacterTarget() {
if (_scriptHandler->_viewportCharacterTarget == -1)
return;
- int var2 = (_characterPositionX[_scriptHandler->_viewportCharacterTarget] >> 3) - _scriptHandler->_viewportPos.x;
- int var4 = (_characterPositionY[_scriptHandler->_viewportCharacterTarget] >> 3) - _scriptHandler->_viewportPos.y;
+ int tileX = (_characterPos[_scriptHandler->_viewportCharacterTarget].x >> 3) - _scriptHandler->_viewportPos.x;
+ int tileY = (_characterPos[_scriptHandler->_viewportCharacterTarget].y >> 3) - _scriptHandler->_viewportPos.y;
Common::Point newPos = _scriptHandler->_viewportPos;
- if (var2 >= 1) {
- if (var2 > 6) {
+ if (tileX >= 1) {
+ if (tileX > 6){
newPos.x += 4;
if (newPos.x > 56)
newPos.x = 56;
@@ -1151,19 +1171,18 @@ void LilliputEngine::scrollToViewportCharacterTarget() {
newPos.x = 0;
}
- if ((var4 < 1) && (newPos.y < 4))
+ if ((tileY < 1) && (newPos.y < 4))
newPos.y = 0;
else {
- if (var4 < 1)
+ if (tileY < 1)
newPos.y -= 4;
- if (var4 > 6) {
+ if (tileY > 6) {
newPos.y += 4;
if (newPos.y >= 56)
newPos.y = 56;
}
}
-
viewportScrollTo(newPos);
}
@@ -1204,7 +1223,7 @@ void LilliputEngine::viewportScrollTo(Common::Point goalPos) {
dy = 0;
} while ((dx != 0) || (dy != 0));
- _soundHandler->contentFct5();
+ _soundHandler->update();
}
void LilliputEngine::renderCharacters(byte *buf, Common::Point pos) {
@@ -1217,12 +1236,12 @@ void LilliputEngine::renderCharacters(byte *buf, Common::Point pos) {
if (buf[1] != 0xFF) {
int tmpIndex = buf[1];
- if ((_rulesChunk9[tmpIndex] & 16) == 0)
+ if ((_cubeFlags[tmpIndex] & 16) == 0)
++_byte16552;
}
int index = _charactersToDisplay[_currentDisplayCharacter];
- Common::Point characterPos = Common::Point(_characterDisplayX[index], _characterDisplayY[index]);
+ Common::Point characterPos = _characterDisplay[index];
if (index == _scriptHandler->_talkingCharacter)
displaySpeechBubbleTail(characterPos);
@@ -1330,195 +1349,170 @@ byte LilliputEngine::getDirection(Common::Point param1, Common::Point param2) {
byte LilliputEngine::sequenceCharacterHomeIn(int index, Common::Point param1) {
debugC(2, kDebugEngine, "sequenceCharacterHomeIn(%d, %d - %d)", index, param1.x, param1.y);
- Common::Point var3 = Common::Point(_characterSubTargetPosX[index], _characterSubTargetPosY[index]);
+ Common::Point target = _characterSubTargetPos[index];
- if (var3.x != -1) {
- if (var3 != _scriptHandler->_characterTilePos[index]) {
- sub1693A_chooseDirections(index);
+ if (target.x != -1) {
+ if (target != _scriptHandler->_characterTilePos[index]) {
+ homeInChooseDirection(index);
_scriptHandler->_characterNextSequence[index] -= (param1.x & 0x0F);
- return 3;
+ return kSeqNoInc | kSeqRepeat;
}
- if ((var3.x == _characterTargetPosX[index]) && (var3.y == _characterTargetPosY[index]))
- return 2;
+ if (target == _characterTargetPos[index])
+ return kSeqRepeat;
}
- sub167EF(index);
+ homeInPathFinding(index);
Common::Point pos1 = _scriptHandler->_characterTilePos[index];
- Common::Point pos2 = Common::Point(_characterSubTargetPosX[index], _characterSubTargetPosY[index]);
+ Common::Point pos2 = _characterSubTargetPos[index];
_characterDirectionArray[index] = getDirection(pos1, pos2);
- sub1693A_chooseDirections(index);
+ homeInChooseDirection(index);
_scriptHandler->_characterNextSequence[index] -= (param1.x & 0x0F);
- return 3;
-
+ return kSeqNoInc | kSeqRepeat;
}
-void LilliputEngine::sub167EF(int index) {
- debugC(2, kDebugEngine, "sub167EF(%d)", index);
+void LilliputEngine::homeInPathFinding(int index) {
+ debugC(2, kDebugEngine, "homeInPathFinding(%d)", index);
- int16 word167EB = findHotspot(_scriptHandler->_characterTilePos[index]);
- int16 word167ED = findHotspot(Common::Point(_characterTargetPosX[index], _characterTargetPosY[index]));
+ int16 enclosureSrc = checkEnclosure(_scriptHandler->_characterTilePos[index]);
+ int16 enclosureDst = checkEnclosure(_characterTargetPos[index]);
- if (word167EB == word167ED) {
- _characterSubTargetPosX[index] = _characterTargetPosX[index];
- _characterSubTargetPosY[index] = _characterTargetPosY[index];
+ if (enclosureSrc == enclosureDst) {
+ _characterSubTargetPos[index] = _characterTargetPos[index];
return;
}
- if (word167EB == -1) {
- int tmpVal = reverseFindHotspot(Common::Point(_characterTargetPosX[index], _characterTargetPosY[index]));
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[tmpVal].x;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[tmpVal].y;
+ if (enclosureSrc == -1) {
+ int tmpVal = checkOuterEnclosure(_characterTargetPos[index]);
+ _characterSubTargetPos[index] = _portalPos[tmpVal];
return;
}
- if ((word167ED != -1) &&
- (_characterTargetPosX[index] >= _rectXMinMax[word167EB].min) &&
- (_characterTargetPosX[index] <= _rectXMinMax[word167EB].max) &&
- (_characterTargetPosY[index] >= _rectYMinMax[word167EB].min) &&
- (_characterTargetPosY[index] <= _rectYMinMax[word167EB].max)) {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167ED].x;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167ED].y;
+ if ((enclosureDst != -1) &&
+ (_characterTargetPos[index].x >= _rectXMinMax[enclosureSrc].min) &&
+ (_characterTargetPos[index].x <= _rectXMinMax[enclosureSrc].max) &&
+ (_characterTargetPos[index].y >= _rectYMinMax[enclosureSrc].min) &&
+ (_characterTargetPos[index].y <= _rectYMinMax[enclosureSrc].max)) {
+ _characterSubTargetPos[index] = _portalPos[enclosureDst];
return;
}
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y;
- int var4h = _rectXMinMax[word167EB].min;
- int var4l = _rectXMinMax[word167EB].max;
+ _characterSubTargetPos[index] = _portalPos[enclosureSrc];
- if (var4h != var4l) {
- if (_rulesBuffer12Pos4[word167EB].x == var4h) {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x - 1;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y;
+ if (_rectXMinMax[enclosureSrc].min != _rectXMinMax[enclosureSrc].max) {
+ if (_portalPos[enclosureSrc].x == _rectXMinMax[enclosureSrc].min) {
+ _characterSubTargetPos[index] = Common::Point(_portalPos[enclosureSrc].x - 1, _portalPos[enclosureSrc].y);
return;
}
- if (_rulesBuffer12Pos4[word167EB].x == var4l) {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x + 1;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y;
+ if (_portalPos[enclosureSrc].x == _rectXMinMax[enclosureSrc].max) {
+ _characterSubTargetPos[index] = Common::Point(_portalPos[enclosureSrc].x + 1, _portalPos[enclosureSrc].y);
return;
}
- var4h = (_rectYMinMax[word167EB].min);
- var4l = (_rectYMinMax[word167EB].max);
+ if (_rectYMinMax[enclosureSrc].min != _rectYMinMax[enclosureSrc].max) {
+ if (_portalPos[enclosureSrc].y == _rectYMinMax[enclosureSrc].min)
+ _characterSubTargetPos[index] = Common::Point(_portalPos[enclosureSrc].x, _portalPos[enclosureSrc].y - 1);
+ else // CHECKME: Should be a check on y == max
+ _characterSubTargetPos[index] = Common::Point(_portalPos[enclosureSrc].x, _portalPos[enclosureSrc].y + 1);
- if (var4h != var4l) {
- if (_rulesBuffer12Pos4[word167EB].y == var4h) {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y - 1;
- } else {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y + 1;
- }
return;
}
}
- // var4h == var4l
- int mapIndex = (_rulesBuffer12Pos4[word167EB].y * 64 + _rulesBuffer12Pos4[word167EB].x) * 4;
+ int mapIndex = (_portalPos[enclosureSrc].y * 64 + _portalPos[enclosureSrc].x) * 4;
assert(mapIndex < 16384);
int tmpVal = _bufferIsoMap[mapIndex + 3];
- if ((tmpVal & 8) != 0) {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x + 1;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y;
- } else if ((tmpVal & 4) != 0) {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y - 1;
- } else if ((tmpVal & 2) != 0) {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y + 1;
- } else {
- _characterSubTargetPosX[index] = _rulesBuffer12Pos4[word167EB].x - 1;
- _characterSubTargetPosY[index] = _rulesBuffer12Pos4[word167EB].y;
- }
+ if ((tmpVal & 8) != 0)
+ _characterSubTargetPos[index] = Common::Point(_portalPos[enclosureSrc].x + 1, _portalPos[enclosureSrc].y);
+ else if ((tmpVal & 4) != 0)
+ _characterSubTargetPos[index] = Common::Point(_portalPos[enclosureSrc].x, _portalPos[enclosureSrc].y - 1);
+ else if ((tmpVal & 2) != 0)
+ _characterSubTargetPos[index] = Common::Point(_portalPos[enclosureSrc].x, _portalPos[enclosureSrc].y + 1);
+ else
+ _characterSubTargetPos[index] = Common::Point(_portalPos[enclosureSrc].x - 1, _portalPos[enclosureSrc].y);
+
return;
}
-void LilliputEngine::sub1693A_chooseDirections(int index) {
- debugC(2, kDebugEngine, "sub1693A_chooseDirections(%d)", index);
+void LilliputEngine::homeInChooseDirection(int index) {
+ debugC(2, kDebugEngine, "homeInChooseDirection(%d)", index);
static const int16 mapArrayMove[4] = {4, -256, 256, -4};
- _word16937Pos = _scriptHandler->_characterTilePos[index];
+ _curCharacterTilePos = _scriptHandler->_characterTilePos[index];
- sub16A08(index);
+ evaluateDirections(index);
+ int direction = (_characterDirectionArray[index] ^ 3);
- int var2 = (_characterDirectionArray[index] ^ 3);
- // initialized by sub16A08, values: [0, 3[
- _array1692B[var2] -= 8;
- byte byte16939 = 0;
+ _homeInDirLikelyhood[direction] -= 8;
+ byte closeWallFl = 0;
- int mapIndex = ((_word16937Pos.y * 64) + _word16937Pos.x) * 4;
+ int mapIndex = ((_curCharacterTilePos.y * 64) + _curCharacterTilePos.x) * 4;
int retVal = 0;
for (int i = 3; i >= 0; i--) {
int mapIndexDiff = mapArrayMove[i];
assert(mapIndex + mapIndexDiff + 3 < 16384);
- if (((_bufferIsoMap[mapIndex + mapIndexDiff + 3] & _array16C54[i]) != 0) && ((_bufferIsoMap[mapIndex + 3] & _array16C58[i]) != 0)) {
- if ((_bufferIsoMap[mapIndex + mapIndexDiff + 3] & 0x80) != 0 && (sub16A76(i, index) != 0)) {
- _array1692B[i] -= 20;
+ if (((_bufferIsoMap[mapIndex + mapIndexDiff + 3] & _doorEntranceMask[i]) != 0) && ((_bufferIsoMap[mapIndex + 3] & _doorExitMask[i]) != 0)) {
+ if ((_bufferIsoMap[mapIndex + mapIndexDiff + 3] & 0x80) != 0 && (homeInAvoidDeadEnds(i, index) != 0)) {
+ _homeInDirLikelyhood[i] -= 20;
}
- int tmpVal = ((_rulesBuffer2_10[index] & 7) ^ 7);
- retVal = _rulesChunk9[_bufferIsoMap[mapIndex + mapIndexDiff]];
+ int tmpVal = ((_characterMobility[index] & 7) ^ 7);
+ retVal = _cubeFlags[_bufferIsoMap[mapIndex + mapIndexDiff]];
tmpVal &= retVal;
if (tmpVal == 0)
continue;
}
- _array1692B[i] = -98;
- ++byte16939;
+ _homeInDirLikelyhood[i] = -98;
+ ++closeWallFl;
}
- if (byte16939 != 0)
- _array1692B[_characterDirectionArray[index]] += 3;
+ if (closeWallFl != 0)
+ _homeInDirLikelyhood[_characterDirectionArray[index]] += 3;
int tmpVal = -99;
for (int i = 3; i >= 0; i--) {
- if (tmpVal < _array1692B[i]) {
+ if (tmpVal < _homeInDirLikelyhood[i]) {
retVal = i;
- tmpVal = _array1692B[i];
+ tmpVal = _homeInDirLikelyhood[i];
}
}
_characterDirectionArray[index] = retVal;
}
-byte LilliputEngine::sub16A76(int indexb, int indexs) {
- debugC(2, kDebugEngine, "sub16A76(%d, %d)", indexb, indexs);
+byte LilliputEngine::homeInAvoidDeadEnds(int indexb, int indexs) {
+ debugC(2, kDebugEngine, "homeInAvoidDeadEnds(%d, %d)", indexb, indexs);
- static const int8 _array16A6C[4] = {1, 0, 0, -1};
- static const int8 _array16A70[4] = {0, -1, 1, 0};
+ static const int8 constDirX[4] = {1, 0, 0, -1};
+ static const int8 constDirY[4] = {0, -1, 1, 0};
- int8 var1h = _word16937Pos.x + _array16A6C[indexb];
- int8 var1l = _word16937Pos.y + _array16A70[indexb];
+ Common::Point tmpPos = Common::Point(_curCharacterTilePos.x + constDirX[indexb], _curCharacterTilePos.y + constDirY[indexb]);
- int16 var2 = findHotspot(Common::Point(var1h, var1l));
+ int16 var2 = checkEnclosure(tmpPos);
if (var2 == -1)
return 1;
-// int _word16A74 = var2; // useless?
-
- var1h = _word16937Pos.x;
- var1l = _word16937Pos.y;
+ tmpPos = _curCharacterTilePos;
- if ((var1h >= _rectXMinMax[var2].min) && (var1h <= _rectXMinMax[var2].max) && (var1l >= _rectYMinMax[var2].min) && (var1l <= _rectYMinMax[var2].max))
+ if ((tmpPos.x >= _rectXMinMax[var2].min) && (tmpPos.x <= _rectXMinMax[var2].max) && (tmpPos.y >= _rectYMinMax[var2].min) && (tmpPos.y <= _rectYMinMax[var2].max))
return 0;
- var1h = _characterSubTargetPosX[indexs];
- var1l = _characterSubTargetPosY[indexs];
+ tmpPos = _characterSubTargetPos[indexs];
- if ((var1h >= _rectXMinMax[var2].min) && (var1h <= _rectXMinMax[var2].max) && (var1l >= _rectYMinMax[var2].min) && (var1l <= _rectYMinMax[var2].max))
+ if ((tmpPos.x >= _rectXMinMax[var2].min) && (tmpPos.x <= _rectXMinMax[var2].max) && (tmpPos.y >= _rectYMinMax[var2].min) && (tmpPos.y <= _rectYMinMax[var2].max))
return 0;
return 1;
}
-int16 LilliputEngine::findHotspot(Common::Point pos) {
- debugC(2, kDebugEngine, "findHotspot(%d, %d)", pos.x, pos.y);
+int16 LilliputEngine::checkEnclosure(Common::Point pos) {
+ debugC(2, kDebugEngine, "checkEnclosure(%d, %d)", pos.x, pos.y);
for (int i = 0; i < _rectNumb; i++) {
if ((pos.x >= _rectXMinMax[i].min) && (pos.x <= _rectXMinMax[i].max) && (pos.y >= _rectYMinMax[i].min) && (pos.y <= _rectYMinMax[i].max))
@@ -1527,8 +1521,8 @@ int16 LilliputEngine::findHotspot(Common::Point pos) {
return -1;
}
-int16 LilliputEngine::reverseFindHotspot(Common::Point pos) {
- debugC(2, kDebugEngine, "reverseFindHotspot(%d, %d)", pos.x, pos.y);
+int16 LilliputEngine::checkOuterEnclosure(Common::Point pos) {
+ debugC(2, kDebugEngine, "checkOuterEnclosure(%d, %d)", pos.x, pos.y);
for (int i = _rectNumb - 1; i >= 0 ; i--) {
if ((pos.x >= _rectXMinMax[i].min) && (pos.x <= _rectXMinMax[i].max) && (pos.y >= _rectYMinMax[i].min) && (pos.y <= _rectYMinMax[i].max))
@@ -1537,9 +1531,8 @@ int16 LilliputEngine::reverseFindHotspot(Common::Point pos) {
return -1;
}
-
-void LilliputEngine::sub16A08(int index) {
- debugC(2, kDebugEngine, "sub16A08(%d)", index);
+void LilliputEngine::evaluateDirections(int index) {
+ debugC(2, kDebugEngine, "evaluateDirections(%d)", index);
static const int8 arrayMoveX[4] = {1, 0, 0, -1};
static const int8 arrayMoveY[4] = {0, -1, 1, 0};
@@ -1547,13 +1540,13 @@ void LilliputEngine::sub16A08(int index) {
int16 arrayDistance[4];
for (int i = 3; i >= 0; i--) {
- int16 var1h = _word16937Pos.x + arrayMoveX[i] - _characterSubTargetPosX[index];
- int16 var1l = _word16937Pos.y + arrayMoveY[i] - _characterSubTargetPosY[index];
+ int16 var1h = _curCharacterTilePos.x + arrayMoveX[i] - _characterSubTargetPos[index].x;
+ int16 var1l = _curCharacterTilePos.y + arrayMoveY[i] - _characterSubTargetPos[index].y;
arrayDistance[i] = (var1l * var1l) + (var1h * var1h);
}
for (int i = 0; i < 4; i++)
- _array1692B[i] = 0;
+ _homeInDirLikelyhood[i] = 0;
int8 tmpIndex = 0;
for (int i = 3; i > 0; i--) {
@@ -1565,7 +1558,7 @@ void LilliputEngine::sub16A08(int index) {
}
}
arrayDistance[tmpIndex] = 0x7FFF;
- _array1692B[tmpIndex] = i;
+ _homeInDirLikelyhood[tmpIndex] = i;
}
}
@@ -1580,7 +1573,7 @@ void LilliputEngine::addCharToBuf(byte character) {
void LilliputEngine::numberToString(int param1) {
debugC(2, kDebugEngine, "numberToString(%d)", param1);
- static const int _array18AE3[6] = {10000, 1000, 100, 10, 1};
+ static const int exp10[6] = {10000, 1000, 100, 10, 1};
int var1 = param1;
bool hideZeros = true;
@@ -1588,9 +1581,9 @@ void LilliputEngine::numberToString(int param1) {
int count = 0;
while (var1 >= 0) {
++count;
- var1 -= _array18AE3[i];
+ var1 -= exp10[i];
}
- var1 += _array18AE3[i];
+ var1 += exp10[i];
--count;
byte tmpVal = count + 0x30;
@@ -1610,8 +1603,8 @@ void LilliputEngine::updateCharPosSequence() {
int index = _numCharacters - 1;
byte result;
while (index >= 0) {
- result = 2;
- while (result & 2) {
+ result = kSeqRepeat;
+ while (result & kSeqRepeat) {
if (_scriptHandler->_characterNextSequence[index] == 16)
break;
@@ -1630,16 +1623,6 @@ void LilliputEngine::updateCharPosSequence() {
// x stands for the next direction, y for the poseType
result = sequenceSetCharacterDirection(index, var1.x, var1.y);
break;
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- result = 0;
- break;
case 10: // Seek move target
result = sequenceSeekMovingCharacter(index, var1);
break;
@@ -1649,21 +1632,21 @@ void LilliputEngine::updateCharPosSequence() {
case 12: // Home in target
result = sequenceCharacterHomeIn(index, var1);
break;
- case 13: // Character
- result = sub16722(index, var1);
+ case 13: // Character mobility
+ result = sequenceSetMobility(index, var1);
break;
- case 14: // ??
- result = sub166F7(index, var1, index2);
+ case 14: // Repeat sequence
+ result = sequenceRepeat(index, var1, index2);
break;
case 15: // End
- result = sub166EA(index);
+ result = sequenceEnd(index);
break;
default:
- error("updateCharPosSequence - unexpected value %d", posSeqType);
+ result = kSeqNone;
break;
}
- if ((result & 1) == 0) {
+ if ((result & kSeqNoInc) == 0) {
++_scriptHandler->_characterNextSequence[index];
if (_scriptHandler->_characterNextSequence[index] == 16)
_scriptHandler->_characterScriptEnabled[index] = 1;
@@ -1673,31 +1656,32 @@ void LilliputEngine::updateCharPosSequence() {
}
}
-byte LilliputEngine::sub166EA(int index) {
- debugC(2, kDebugEngine, "sub166EA(%d)", index);
+byte LilliputEngine::sequenceEnd(int index) {
+ debugC(2, kDebugEngine, "sequenceEnd(%d)", index);
_scriptHandler->_characterNextSequence[index] = 16;
_scriptHandler->_characterScriptEnabled[index] = 1;
- return 1;
+
+ return kSeqNoInc;
}
-byte LilliputEngine::sub166F7(int index, Common::Point var1, int tmpVal) {
- debugC(2, kDebugEngine, "sub166F7(%d, %d - %d, %d)", index, var1.x, var1.y, tmpVal);
+byte LilliputEngine::sequenceRepeat(int index, Common::Point var1, int tmpVal) {
+ debugC(2, kDebugEngine, "sequenceRepeat(%d, %d - %d, %d)", index, var1.x, var1.y, tmpVal);
- byte a2 = var1.y;
- if (a2 != 0) {
- if ((a2 & 0xF0) == 0)
- a2 |= (a2 << 4);
+ byte counter = var1.y;
+ if (counter != 0) {
+ if ((counter & 0xF0) == 0)
+ counter |= (counter << 4);
- a2 -= 16;
- _scriptHandler->_sequenceArr[tmpVal] = Common::Point(var1.x, a2);
+ counter -= 16;
+ _scriptHandler->_sequenceArr[tmpVal] = Common::Point(var1.x, counter);
- if ((a2 & 0xF0) == 0)
- return 2;
+ if ((counter & 0xF0) == 0)
+ return kSeqRepeat;
}
_scriptHandler->_characterNextSequence[index] -= (var1.x & 0x0F);
- return 3;
+ return kSeqNoInc | kSeqRepeat;
}
byte LilliputEngine::sequenceSetCharacterDirection(int index, int direction, int poseType) {
@@ -1706,24 +1690,24 @@ byte LilliputEngine::sequenceSetCharacterDirection(int index, int direction, int
char newDir = direction & 3;
_characterDirectionArray[index] = newDir;
setCharacterPose(index, poseType);
- return 0;
+
+ return kSeqNone;
}
-byte LilliputEngine::sub16722(int index, Common::Point var1) {
- debugC(2, kDebugEngineTBC, "sub16722(%d, %d - %d)", index, var1.x, var1.y);
+byte LilliputEngine::sequenceSetMobility(int index, Common::Point var1) {
+ debugC(2, kDebugEngine, "sequenceSetMobility(%d, %d - %d)", index, var1.x, var1.y);
- _rulesBuffer2_10[index] = var1.y;
- return 2;
+ _characterMobility[index] = var1.y;
+ return kSeqRepeat;
}
byte LilliputEngine::sequenceSound(int index, Common::Point var1) {
debugC(2, kDebugEngine, "sequenceSound(%d, %d - %d)", index, var1.x, var1.y);
int param4x = ((index | 0xFF00) >> 8);
- int param1 = var1.y;
- _soundHandler->contentFct2(param1, _scriptHandler->_viewportPos,
+ _soundHandler->play(var1.y, _scriptHandler->_viewportPos,
_scriptHandler->_characterTilePos[index], Common::Point(param4x, 0));
- return 2;
+ return kSeqRepeat;
}
byte LilliputEngine::sequenceSeekMovingCharacter(int index, Common::Point var1) {
@@ -1732,21 +1716,16 @@ byte LilliputEngine::sequenceSeekMovingCharacter(int index, Common::Point var1)
int charIndex = _scriptHandler->_characterSeek[index];
Common::Point charPos = _scriptHandler->_characterTilePos[charIndex];
- if ((_characterSubTargetPosX[index] != -1)
- && (_characterSubTargetPosX[index] == _characterTargetPosX[index])
- && (_characterSubTargetPosY[index] == _characterTargetPosY[index])) {
- _characterSubTargetPosX[index] = charPos.x;
- _characterSubTargetPosY[index] = charPos.y;
- }
+ if ((_characterSubTargetPos[index].x != -1) && (_characterSubTargetPos[index] == _characterTargetPos[index]))
+ _characterSubTargetPos[index] = charPos;
- _characterTargetPosX[index] = charPos.x;
- _characterTargetPosY[index] = charPos.y;
+ _characterTargetPos[index] = charPos;
return sequenceCharacterHomeIn(index, var1);
}
-void LilliputEngine::sub16EBC() {
- debugC(2, kDebugEngine, "sub16EBC()");
+void LilliputEngine::checkSpecialCubes() {
+ debugC(2, kDebugEngine, "checkSpecialCubes()");
for (int index1 = _numCharacters - 1; index1 >= 0; index1--) {
// Hack: The original doesn't check if it's disabled, which looks wrong
@@ -1758,20 +1737,19 @@ void LilliputEngine::sub16EBC() {
assert((mapIndex >= 0) && (mapIndex < 16384));
byte var1 = _bufferIsoMap[mapIndex] & 0x40;
- if (var1 == _stingArray[index1])
+ if (var1 == _specialCubes[index1])
continue;
- _stingArray[index1] = var1;
+ _specialCubes[index1] = var1;
if (var1 != 0)
_scriptHandler->_characterScriptEnabled[index1] = 1;
}
}
-void LilliputEngine::sub12F37() {
- debugC(2, kDebugEngine, "sub12F37()");
+void LilliputEngine::handleCharacterTimers() {
+ debugC(2, kDebugEngine, "handleCharacterTimers()");
int index1 = _animationTick + 2;
- int index2 = 0;
for (byte i = 0; i < _numCharacters; i++) {
byte *varPtr = getCharacterAttributesPtr(index1);
@@ -1781,12 +1759,11 @@ void LilliputEngine::sub12F37() {
} else {
--varPtr[0];
if (varPtr[0] == 1)
- _scriptHandler->_characterScriptEnabled[index2] = 1;
+ _scriptHandler->_characterScriptEnabled[i] = 1;
}
}
index1 += 32;
- ++index2;
}
}
@@ -1945,7 +1922,7 @@ void LilliputEngine::checkClickOnCharacter(Common::Point pos, bool &forceReturnF
for (int8 i = 0; i < _numCharacters; i++) {
// check if position is over a character
- if ((pos.x >= _characterDisplayX[i]) && (pos.x <= _characterDisplayX[i] + 17) && (pos.y >= _characterDisplayY[i]) && (pos.y <= _characterDisplayY[i] + 17) && (i != _host)) {
+ if ((pos.x >= _characterDisplay[i].x) && (pos.x <= _characterDisplay[i].x + 17) && (pos.y >= _characterDisplay[i].y) && (pos.y <= _characterDisplay[i].y + 17) && (i != _host)) {
_selectedCharacterId = i;
_actionType = kActionGoto;
if (_delayedReactivationAction)
@@ -1962,7 +1939,7 @@ void LilliputEngine::checkInterfaceHotspots(bool &forceReturnFl) {
forceReturnFl = false;
for (int index = _interfaceHotspotNumb - 1; index >= 0; index--) {
- if (isMouseOverHotspot(_mousePos, Common::Point(_interfaceHotspotsX[index], _interfaceHotspotsY[index]))) {
+ if (isMouseOverHotspot(_mousePos, _interfaceHotspots[index])) {
handleInterfaceHotspot(index, 1);
forceReturnFl = true;
return;
@@ -2067,7 +2044,7 @@ byte LilliputEngine::sequenceMoveCharacter(int idx, int moveType, int poseType)
warning("sequenceMoveCharacter - Unexpected value %d", moveType);
}
- return 0;
+ return kSeqNone;
}
void LilliputEngine::turnCharacter1(int index) {
@@ -2111,32 +2088,32 @@ void LilliputEngine::moveCharacterDown2(int index) {
void LilliputEngine::moveCharacterSpeed2(int index) {
debugC(2, kDebugEngine, "moveCharacterSpeed2(%d)", index);
- sub16B31_moveCharacter(index, 2);
+ moveCharacterForward(index, 2);
}
void LilliputEngine::moveCharacterSpeed4(int index) {
debugC(2, kDebugEngine, "moveCharacterSpeed4(%d)", index);
- sub16B31_moveCharacter(index, 4);
+ moveCharacterForward(index, 4);
}
void LilliputEngine::moveCharacterBack2(int index) {
debugC(2, kDebugEngine, "moveCharacterBack2(%d)", index);
- sub16B31_moveCharacter(index, -2);
+ moveCharacterForward(index, -2);
}
void LilliputEngine::moveCharacterSpeed3(int index) {
debugC(2, kDebugEngine, "moveCharacterSpeed3(%d)", index);
- sub16B31_moveCharacter(index, 3);
+ moveCharacterForward(index, 3);
}
-void LilliputEngine::sub16B31_moveCharacter(int index, int16 speed) {
- debugC(2, kDebugEngine, "sub16B31_moveCharacter(%d, %d)", index, speed);
+void LilliputEngine::moveCharacterForward(int index, int16 speed) {
+ debugC(2, kDebugEngine, "moveCharacterForward(%d, %d)", index, speed);
- int16 newX = _characterPositionX[index];
- int16 newY = _characterPositionY[index];
+ int16 newX = _characterPos[index].x;
+ int16 newY = _characterPos[index].y;
switch (_characterDirectionArray[index]) {
case 0:
newX += speed;
@@ -2151,16 +2128,15 @@ void LilliputEngine::sub16B31_moveCharacter(int index, int16 speed) {
newX -= speed;
break;
}
- sub16B8F_moveCharacter(index, Common::Point(newX, newY), _characterDirectionArray[index]);
+ checkCollision(index, Common::Point(newX, newY), _characterDirectionArray[index]);
}
-void LilliputEngine::sub16B8F_moveCharacter(int index, Common::Point pos, int direction) {
- debugC(2, kDebugEngine, "sub16B8F_moveCharacter(%d, %d - %d, %d)", index, pos.x, pos.y, direction);
+void LilliputEngine::checkCollision(int index, Common::Point pos, int direction) {
+ debugC(2, kDebugEngine, "checkCollision(%d, %d - %d, %d)", index, pos.x, pos.y, direction);
int16 diffX = pos.x >> 3;
if (((diffX & 0xFF) == _scriptHandler->_characterTilePos[index].x) && ((pos.y >> 3) == _scriptHandler->_characterTilePos[index].y)) {
- _characterPositionX[index] = pos.x;
- _characterPositionY[index] = pos.y;
+ _characterPos[index] = pos;
return;
}
@@ -2170,74 +2146,73 @@ void LilliputEngine::sub16B8F_moveCharacter(int index, Common::Point pos, int di
int mapIndex = (_scriptHandler->_characterTilePos[index].y * 64 + _scriptHandler->_characterTilePos[index].x) * 4;
assert(mapIndex < 16384);
- if ((_bufferIsoMap[mapIndex + 3] & _array16C58[direction]) == 0)
+ if ((_bufferIsoMap[mapIndex + 3] & _doorExitMask[direction]) == 0)
return;
mapIndex = ((pos.y & 0xFFF8) << 3) + diffX;
mapIndex <<= 2;
- if ((_bufferIsoMap[mapIndex + 3] & _array16C54[direction]) == 0)
+ if ((_bufferIsoMap[mapIndex + 3] & _doorEntranceMask[direction]) == 0)
return;
- byte var1 = _rulesBuffer2_10[index];
+ byte var1 = _characterMobility[index];
var1 &= 7;
var1 ^= 7;
- if ((var1 & _rulesChunk9[_bufferIsoMap[mapIndex]]) != 0)
+ if ((var1 & _cubeFlags[_bufferIsoMap[mapIndex]]) != 0)
return;
- _characterPositionX[index] = pos.x;
- _characterPositionY[index] = pos.y;
+ _characterPos[index] = pos;
}
-void LilliputEngine::sub17224(byte type, byte index, int var4) {
- debugC(2, kDebugEngine, "sub17224(%d, %d, %d)", type, index, var4);
+void LilliputEngine::signalDispatcher(byte type, byte index, int var4) {
+ debugC(2, kDebugEngine, "signalDispatcher(%d, %d, %d)", type, index, var4);
- if (type == 0) {
- sub17264(index, var4);
+ if (type == 0) { // Message sent to one target character
+ sendMessageToCharacter(index, var4);
return;
}
- if (type == 3) {
+ if (type == 3) { // Broadcast - Sent to all characters
for (int i = _numCharacters - 1; i >= 0; i--)
- sub17264(i, var4);
+ sendMessageToCharacter(i, var4);
return;
}
int index2 = var4 & 0xFF;
for (byte i = 0; i < _numCharacters; i++) {
if ((_scriptHandler->_interactions[index2] & 0xFF) >= type)
- sub17264(i, var4);
+ sendMessageToCharacter(i, var4);
index2 += 40;
}
}
-void LilliputEngine::sub17264(byte index, int var4) {
- debugC(2, kDebugEngine, "sub17264(%d, %d)", index, var4);
+void LilliputEngine::sendMessageToCharacter(byte index, int var4) {
+ debugC(2, kDebugEngine, "sendMessageToCharacter(%d, %d)", index, var4);
- if (_array11D49[index] != -1) {
- _array1289F[index] = var4;
+ if (_characterSignals[index] != -1) {
+ _signalArr[index] = var4;
} else {
_scriptHandler->_characterScriptEnabled[index] = 1;
- _array11D49[index] = var4;
+ _characterSignals[index] = var4;
}
}
-void LilliputEngine::sub171CF() {
- debugC(2, kDebugEngine, "sub171CF()");
+void LilliputEngine::handleSignals() {
+ debugC(2, kDebugEngine, "handleSignals()");
for (byte i = 0; i < _numCharacters; i++) {
- if (_array1289F[i] != -1) {
- _array11D49[i] = _array1289F[i];
- _array1289F[i] = -1;
+ if (_signalArr[i] != -1) {
+ _characterSignals[i] = _signalArr[i];
+ _signalArr[i] = -1;
_scriptHandler->_characterScriptEnabled[i] = 1;
}
}
- ++_word1289D;
+ ++_signalTimer;
for (int i = 0; i < 10; i++) {
- if ((_signalArray[(3 * i) + 1] != -1) && (_signalArray[3 * i] == _word1289D)) {
+ if ((_signalArray[(3 * i) + 1] != -1) && (_signalArray[3 * i] == _signalTimer)) {
int16 var1 = _signalArray[(3 * i) + 1];
int var4 = _signalArray[(3 * i) + 2];
_signalArray[(3 * i) + 1] = -1;
@@ -2245,7 +2220,7 @@ void LilliputEngine::sub171CF() {
byte type = var1 >> 8;
byte index = var1 & 0xFF;
- sub17224(type, index, var4);
+ signalDispatcher(type, index, var4);
}
}
}
@@ -2274,10 +2249,10 @@ void LilliputEngine::checkInterfaceActivationDelay() {
void LilliputEngine::displayHeroismIndicator() {
debugC(2, kDebugEngine, "displayHeroismIndicator()");
- if (_scriptHandler->_savedBuffer215Ptr == NULL)
+ if (_scriptHandler->_barAttrPtr == NULL)
return;
- int var1 = (_scriptHandler->_savedBuffer215Ptr[0] * 25) >> 8;
+ int var1 = (_scriptHandler->_barAttrPtr[0] * 25) >> 8;
if (var1 == _scriptHandler->_heroismLevel)
return;
@@ -2296,7 +2271,6 @@ void LilliputEngine::displayHeroismIndicator() {
var2 = _scriptHandler->_heroismLevel & 0xFF;
if (var2 != 0) {
-// sub16064(var1, _scriptHandler->_byte15FFA);
for (int i = 0; i < (var2 << 2); i++) {
((byte *)_mainSurface->getPixels())[index] = var1;
((byte *)_mainSurface->getPixels())[index + 1] = var1;
@@ -2306,7 +2280,6 @@ void LilliputEngine::displayHeroismIndicator() {
}
if (25 - _scriptHandler->_heroismLevel != 0) {
-// sub16064(23, 25 - _scriptHandler->_byte15FFA);
var2 = (25 - _scriptHandler->_heroismLevel) << 2;
for (int i = 0; i < var2; i++) {
((byte *)_mainSurface->getPixels())[index] = 23;
@@ -2485,13 +2458,13 @@ void LilliputEngine::loadRules() {
_word10800_ERULES = f.readUint16LE();
- // Chunk 1
+ // Chunk 1 : Sequences
int size = f.readUint16LE();
- _rulesChunk1 = (byte *)malloc(sizeof(byte) * size);
+ _sequencesArr = (byte *)malloc(sizeof(byte) * size);
for (int i = 0; i < size; ++i)
- _rulesChunk1[i] = f.readByte();
+ _sequencesArr[i] = f.readByte();
- // Chunk 2
+ // Chunk 2 : Characters
_numCharacters = (f.readUint16LE() & 0xFF);
assert(_numCharacters <= 40);
@@ -2499,12 +2472,12 @@ void LilliputEngine::loadRules() {
curWord = f.readUint16LE();
if (curWord != 0xFFFF)
curWord = (curWord << 3) + 4;
- _characterPositionX[j] = curWord;
+ _characterPos[j].x = curWord;
curWord = f.readUint16LE();
if (curWord != 0xFFFF)
curWord = (curWord << 3) + 4;
- _characterPositionY[j] = curWord;
+ _characterPos[j].y = curWord;
_characterPosAltitude[j] = (f.readUint16LE() & 0xFF);
_characterFrameArray[j] = f.readUint16LE();
@@ -2513,11 +2486,11 @@ void LilliputEngine::loadRules() {
_characterAboveDist[j] = f.readByte();
_spriteSizeArray[j] = f.readByte();
_characterDirectionArray[j] = f.readByte();
- _rulesBuffer2_10[j] = f.readByte();
+ _characterMobility[j] = f.readByte();
_characterTypes[j] = f.readByte();
_characterBehaviour[j] = f.readByte();
- _characterHomePosX[j] = f.readByte();
- _characterHomePosY[j] = f.readByte();
+ _characterHomePos[j].x = f.readByte();
+ _characterHomePos[j].y = f.readByte();
for (int k = 0; k < 32; k++)
_characterVariables[(j * 32) + k] = f.readByte();
@@ -2566,25 +2539,25 @@ void LilliputEngine::loadRules() {
for (int i = 0; i < curWord; ++i)
_arrayGameScripts[i] = f.readByte();
- // Chunk 9
+ // Chunk 9 : Cube flags
for (int i = 0; i < 60; i++)
- _rulesChunk9[i] = f.readByte();
+ _cubeFlags[i] = f.readByte();
- // Chunk 10 & 11
- _rulesChunk10_size = f.readByte();
- assert(_rulesChunk10_size <= 20);
+ // Chunk 10 & 11 : Lists
+ _listNumb = f.readByte();
+ assert(_listNumb <= 20);
- if (_rulesChunk10_size != 0) {
- _rulesChunk10 = (int16 *)malloc(sizeof(int16) * _rulesChunk10_size);
+ if (_listNumb != 0) {
+ _listIndex = (int16 *)malloc(sizeof(int16) * _listNumb);
int totalSize = 0;
- for (int i = 0; i < _rulesChunk10_size; ++i) {
- _rulesChunk10[i] = totalSize;
+ for (int i = 0; i < _listNumb; ++i) {
+ _listIndex[i] = totalSize;
totalSize += f.readByte();
}
if (totalSize != 0) {
- _rulesChunk11 = (byte *)malloc(sizeof(byte) * totalSize);
+ _listArr = (byte *)malloc(sizeof(byte) * totalSize);
for (int i = 0; i < totalSize; i++)
- _rulesChunk11[i] = f.readByte();
+ _listArr[i] = f.readByte();
}
}
@@ -2597,13 +2570,14 @@ void LilliputEngine::loadRules() {
_rectXMinMax[i].min = (int16)f.readByte();
_rectYMinMax[i].max = (int16)f.readByte();
_rectYMinMax[i].min = (int16)f.readByte();
+
int16 tmpValY = (int16)f.readByte();
int16 tmpValX = (int16)f.readByte();
- _rulesBuffer12Pos3[i] = Common::Point(tmpValX, tmpValY);
+ _keyPos[i] = Common::Point(tmpValX, tmpValY);
+
tmpValY = (int16)f.readByte();
tmpValX = (int16)f.readByte();
- // _rulesBuffer12Pos4 is used by the into
- _rulesBuffer12Pos4[i] = Common::Point(tmpValX, tmpValY);
+ _portalPos[i] = Common::Point(tmpValX, tmpValY);
}
// Chunk 13
@@ -2612,10 +2586,10 @@ void LilliputEngine::loadRules() {
_interfaceTwoStepAction[i] = f.readByte();
for (int i = 0 ; i < 20; i++)
- _interfaceHotspotsX[i] = f.readSint16LE();
+ _interfaceHotspots[i].x = f.readSint16LE();
for (int i = 0 ; i < 20; i++)
- _interfaceHotspotsY[i] = f.readSint16LE();
+ _interfaceHotspots[i].y = f.readSint16LE();
for (int i = 0; i < 20; i++) {
byte curByte = f.readByte();
@@ -2636,8 +2610,6 @@ void LilliputEngine::loadRules() {
}
}
f.close();
-
- // Skipped: Load Savegame
}
void LilliputEngine::displayVGAFile(Common::String fileName) {
@@ -2653,13 +2625,13 @@ void LilliputEngine::fixPaletteEntries(uint8 *palette, int num) {
debugC(1, kDebugEngine, "fixPaletteEntries(palette, %d)", num);
// Color values are coded on 6bits (for old 6bits DAC)
for (int32 i = 0; i < num * 3; i++) {
- int32 a = palette[i];
- assert(a < 64);
+ int32 col = palette[i];
+ assert(col < 64);
- a = (a << 2) | (a >> 4);
- if (a > 255)
- a = 255;
- palette[i] = a;
+ col = (col << 2) | (col >> 4);
+ if (col > 255)
+ col = 255;
+ palette[i] = col;
}
}
@@ -2676,13 +2648,9 @@ void LilliputEngine::initPalette() {
void LilliputEngine::setCurrentCharacter(int index) {
debugC(1, kDebugEngine, "setCurrentCharacter(%d)", index);
- _currentScriptCharacter = index;
-
assert(index < 40);
- int posX = _characterPositionX[index];
- int posY = _characterPositionY[index];
-
- _currentScriptCharacterPos = Common::Point(posX >> 3, posY >> 3);
+ _currentScriptCharacter = index;
+ _currentScriptCharacterPos = Common::Point(_characterPos[index].x >> 3, _characterPos[index].y >> 3);
_currentCharacterAttributes = getCharacterAttributesPtr(_currentScriptCharacter * 32);
}
@@ -2737,10 +2705,10 @@ void LilliputEngine::handleGameScripts() {
_scriptHandler->_characterScriptEnabled[index] = 0;
setCurrentCharacter(index);
- _waitingSignal = _array11D49[index] >> 8;
- _waitingSignalCharacterId = _array11D49[index] & 0xFF;
- _array11D49[index] = -1;
- _word1817B = 0;
+ _waitingSignal = _characterSignals[index] >> 8;
+ _waitingSignalCharacterId = _characterSignals[index] & 0xFF;
+ _characterSignals[index] = -1;
+ _newModesEvaluatedNumber = 0;
int tmpVal = _characterBehaviour[index];
if (tmpVal == 0xFF)
@@ -2790,8 +2758,9 @@ Common::Error LilliputEngine::run() {
// Setup mixer
syncSoundSettings();
- //TODO: Init sound/music player
+ _soundHandler->init();
+ // Init palette
initPalette();
// Load files. In the original, the size was hardcoded
diff --git a/engines/lilliput/lilliput.h b/engines/lilliput/lilliput.h
index b7b2cc5e04..6d67021b55 100644
--- a/engines/lilliput/lilliput.h
+++ b/engines/lilliput/lilliput.h
@@ -75,6 +75,10 @@ enum InterfaceHotspotStatus {
kHotspotSelected = 3
};
+#define kSeqNone 0
+#define kSeqNoInc 1 << 0
+#define kSeqRepeat 1 << 1
+
struct LilliputGameDescription;
struct SmallAnim {
@@ -125,10 +129,10 @@ public:
int8 _lastInterfaceHotspotIndex;
byte _lastInterfaceHotspotButton; // Unused: set by 2 functions, but never used elsewhere
byte _debugFlag; // Mostly useless, as the associated functions are empty
- byte _byte14837; // Unused byte, set by an opcode
+ byte _debugFlag2; // Unused byte, set by an opcode
byte _codeEntered[3];
- char _array1692B[4];
+ char _homeInDirLikelyhood[4];
byte *_bufferIsoMap;
byte *_bufferCubegfx;
byte *_bufferMen;
@@ -149,25 +153,24 @@ public:
int _nextCharacterIndex;
int8 _waitingSignal;
int8 _waitingSignalCharacterId;
- uint16 _word1817B;
+ uint16 _newModesEvaluatedNumber;
Common::Point _savedSurfaceUnderMousePos;
bool _displayGreenHand;
bool _isCursorGreenHand;
int _currentDisplayCharacter;
int _displayStringIndex;
- int _word1289D;
- Common::Point _word16937Pos;
+ int _signalTimer;
+ Common::Point _curCharacterTilePos;
int16 _mapSavedPixelIndex[40];
byte _mapSavedPixel[40];
- int16 _array11D49[40];
- int16 _array1289F[40];
+ int16 _characterSignals[40];
+ int16 _signalArr[40];
int16 _signalArray[30];
- byte *_rulesChunk1;
+ byte *_sequencesArr;
int16 _currentScriptCharacter;
- int16 _characterPositionX[40];
- int16 _characterPositionY[40];
+ Common::Point _characterPos[40];
int8 _characterPosAltitude[40];
int16 _characterFrameArray[40];
int8 _characterCarried[40];
@@ -175,11 +178,10 @@ public:
byte _characterAboveDist[40];
byte _spriteSizeArray[40];
byte _characterDirectionArray[40];
- byte _rulesBuffer2_10[40];
+ byte _characterMobility[40];
byte _characterTypes[40];
byte _characterBehaviour[40];
- byte _characterHomePosX[40];
- byte _characterHomePosY[40];
+ Common::Point _characterHomePos[40];
byte _characterVariables[1400 + 3120];
byte *_currentCharacterAttributes;
byte _poseArray[40 * 32];
@@ -193,34 +195,29 @@ public:
int *_arrayGameScriptIndex;
int _gameScriptIndexSize;
byte *_arrayGameScripts;
- byte _rulesChunk9[60];
- byte _rulesChunk10_size;
- int16 *_rulesChunk10;
- byte *_rulesChunk11;
+ byte _cubeFlags[60];
+ byte _listNumb;
+ int16 *_listIndex;
+ byte *_listArr;
int16 _rectNumb;
MinMax _rectXMinMax[40];
MinMax _rectYMinMax[40];
- Common::Point _rulesBuffer12Pos3[40];
- Common::Point _rulesBuffer12Pos4[40];
+ Common::Point _keyPos[40];
+ Common::Point _portalPos[40];
int _interfaceHotspotNumb;
byte _interfaceTwoStepAction[20];
- int16 _interfaceHotspotsX[20];
- int16 _interfaceHotspotsY[20];
+ Common::Point _interfaceHotspots[20];
Common::KeyCode _keyboardMapping[20];
- int16 _characterTargetPosX[40];
- int16 _characterTargetPosY[40];
+ Common::Point _characterTargetPos[40];
byte _savedSurfaceUnderMouse[16 * 16];
byte _charactersToDisplay[40];
- int16 _characterRelativePositionX[40];
- int16 _characterRelativePositionY[40];
- int16 _characterDisplayX[40];
- int16 _characterDisplayY[40];
+ Common::Point _characterRelativePos[40];
+ Common::Point _characterDisplay[40];
int8 _characterMagicPuffFrame[40];
- int16 _characterSubTargetPosX[40];
- int16 _characterSubTargetPosY[40];
- byte _stingArray[40];
- byte _array16C54[4];
- byte _array16C58[4];
+ Common::Point _characterSubTargetPos[40];
+ byte _specialCubes[40];
+ byte _doorEntranceMask[4];
+ byte _doorExitMask[4];
byte _savedSurfaceGameArea1[176 * 256]; // 45056
byte _savedSurfaceGameArea2[176 * 256]; // 45056
byte _savedSurfaceGameArea3[176 * 256]; // 45056
@@ -256,7 +253,7 @@ public:
void displaySmallIndexedAnim(byte index, byte subIndex);
void unselectInterfaceHotspots();
- void sub15F75();
+ void startNavigateFromMap();
void resetSmallAnims();
void paletteFadeOut();
void paletteFadeIn();
@@ -266,15 +263,15 @@ public:
void viewportScrollTo(Common::Point goalPos);
void checkSpeechClosing();
void updateCharPosSequence();
- void sub16A08(int index);
- byte sub16A76(int indexb, int indexs);
- void sub17224(byte type, byte index, int var4);
- void sub17264(byte index, int var4);
- int16 findHotspot(Common::Point pos);
- int16 reverseFindHotspot(Common::Point pos);
- byte sub16722(int index, Common::Point var1);
- byte sub166EA(int index);
- void sub167EF(int index);
+ void evaluateDirections(int index);
+ byte homeInAvoidDeadEnds(int indexb, int indexs);
+ void signalDispatcher(byte type, byte index, int var4);
+ void sendMessageToCharacter(byte index, int var4);
+ int16 checkEnclosure(Common::Point pos);
+ int16 checkOuterEnclosure(Common::Point pos);
+ byte sequenceSetMobility(int index, Common::Point var1);
+ byte sequenceEnd(int index);
+ void homeInPathFinding(int index);
void renderCharacters(byte *buf, Common::Point pos);
@@ -284,15 +281,15 @@ public:
byte getDirection(Common::Point param1, Common::Point param2);
void addCharToBuf(byte character);
void numberToString(int param1);
- void sub12F37();
+ void handleCharacterTimers();
byte sequenceMoveCharacter(int idx, int moveType, int poseType);
void setCharacterPose(int idx, int poseIdx);
- void sub16EBC();
- void sub16CA0();
+ void checkSpecialCubes();
+ void checkInteractions();
byte sequenceSetCharacterDirection(int index, int direction, int poseType);
- void sub171CF();
+ void handleSignals();
void checkInterfaceActivationDelay();
- int16 sub16DD5(int x1, int y1, int x2, int y2);
+ int16 checkObstacle(int x1, int y1, int x2, int y2);
void displayCharactersOnMap();
void restoreMapPoints();
void displayHeroismIndicator();
@@ -316,12 +313,12 @@ public:
void moveCharacterSpeed4(int index);
void moveCharacterBack2(int index);
void moveCharacterSpeed3(int index);
- void sub16B31_moveCharacter(int index, int16 speed);
- void sub16B8F_moveCharacter(int index, Common::Point pos, int direction);
+ void moveCharacterForward(int index, int16 speed);
+ void checkCollision(int index, Common::Point pos, int direction);
byte sequenceSeekMovingCharacter(int index, Common::Point var1);
byte sequenceSound(int index, Common::Point var1);
- byte sub166F7(int index, Common::Point var1, int tmpVal);
- void sub1693A_chooseDirections(int index);
+ byte sequenceRepeat(int index, Common::Point var1, int tmpVal);
+ void homeInChooseDirection(int index);
void initGame(const LilliputGameDescription *gd);
byte *loadVGA(Common::String filename, int fileSize, bool loadPal);
diff --git a/engines/lilliput/script.cpp b/engines/lilliput/script.cpp
index 7600028991..07911f945f 100644
--- a/engines/lilliput/script.cpp
+++ b/engines/lilliput/script.cpp
@@ -33,23 +33,22 @@ LilliputScript::LilliputScript(LilliputEngine *vm) : _vm(vm), _currScript(NULL)
_cubeSet = 0;
_lastRandomValue = 0;
_scriptForVal = 0;
- _byte1881A = 0;
- _byte18823 = 0;
+ _textVarNumber = 0;
_speechDisplaySpeed = 3;
_speechTimer = 0;
_word16F00_characterId = -1;
- _word129A3 = 0;
+ _monitoredCharacter = 0;
_viewportCharacterTarget = -1;
_heroismBarX = 0;
_heroismBarBottomY = 0;
_viewportPos.x = 0;
_viewportPos.y = 0;
_currentSpeechId = 0;
- _array129A5[0] = 0;
- _array129A5[1] = 1;
- _array129A5[2] = 2;
- _array129A5[3] = 3;
- _savedBuffer215Ptr = NULL;
+ _monitoredAttr[0] = 0;
+ _monitoredAttr[1] = 1;
+ _monitoredAttr[2] = 2;
+ _monitoredAttr[3] = 3;
+ _barAttrPtr = NULL;
_word1825E = Common::Point(0, 0);
for (int i = 0; i < 20; i++) {
@@ -57,8 +56,10 @@ LilliputScript::LilliputScript(LilliputEngine *vm) : _vm(vm), _currScript(NULL)
_interfaceButtonActivationDelay[i] = 0;
}
- for (int i = 0; i < 32; i++)
- _array1813BPos[i] = Common::Point(0, 0);
+ for (int i = 0; i < 32; i++) {
+ _newEvaluatedModes[i]._mode = 0;
+ _newEvaluatedModes[i]._priority = 0;
+ }
for (int i = 0; i < 40; i++) {
_characterScriptEnabled[i] = 1;
@@ -76,6 +77,11 @@ LilliputScript::LilliputScript(LilliputEngine *vm) : _vm(vm), _currScript(NULL)
for (int i = 0; i < 1600; i++)
_interactions[i] = 0;
+
+ _heroismLevel = 0;
+ _talkingCharacter = -1;
+ _byte16F05_ScriptHandler = 0;
+ _word18821 = 0;
}
LilliputScript::~LilliputScript() {
@@ -205,7 +211,7 @@ byte LilliputScript::handleOpcodeType1(int curWord) {
return OC_CheckCurrentCharacterAttr1();
break;
case 0x28:
- return OC_isCurrentCharacterStung();
+ return OC_isCurrentCharacterSpecial();
break;
case 0x29:
return OC_CurrentCharacterAttr3Equals1();
@@ -271,7 +277,7 @@ void LilliputScript::handleOpcodeType2(int curWord) {
OC_ComputeCharacterVariable();
break;
case 0x9:
- OC_getRandom_type2();
+ OC_setAttributeToRandom();
break;
case 0xA:
OC_setCharacterPosition();
@@ -301,7 +307,7 @@ void LilliputScript::handleOpcodeType2(int curWord) {
OC_computeChararacterAttr();
break;
case 0x13:
- OC_setByte18823();
+ OC_setTextVarNumber();
break;
case 0x14:
OC_callScript();
@@ -367,10 +373,10 @@ void LilliputScript::handleOpcodeType2(int curWord) {
OC_changeCurrentCharacterSprite();
break;
case 0x29:
- OC_sub17E99();
+ OC_getList();
break;
case 0x2A:
- OC_sub17EC5();
+ OC_setList();
break;
case 0x2B:
OC_setCharacterDirectionTowardsPos();
@@ -406,7 +412,7 @@ void LilliputScript::handleOpcodeType2(int curWord) {
OC_setCharacterProperties();
break;
case 0x36:
- OC_sub1805D();
+ OC_setMonitoredCharacter();
break;
case 0x37:
OC_setNewPose();
@@ -427,19 +433,19 @@ void LilliputScript::handleOpcodeType2(int curWord) {
OC_setCurrentCharacterAltitude();
break;
case 0x3D:
- OC_sub1817F();
+ OC_setModePriority();
break;
case 0x3E:
- OC_sub181BB();
+ OC_setComputedModePriority();
break;
case 0x3F:
- OC_sub18213();
+ OC_selectBestMode();
break;
case 0x40:
OC_magicPuffEntrance();
break;
case 0x41:
- OC_sub18260();
+ OC_spawnCharacterAtPos();
break;
case 0x42:
OC_CharacterVariableAddOrRemoveFlag();
@@ -472,7 +478,7 @@ void LilliputScript::handleOpcodeType2(int curWord) {
OC_setDebugFlag();
break;
case 0x4C:
- OC_setByte14837();
+ OC_setDebugFlag2();
break;
case 0x4D:
OC_waitForEvent();
@@ -619,7 +625,7 @@ static const OpCode opCodes2[] = {
/* 0x06 */ { "OC_getComputedVariantSpeechIfMute", 4, kGetValue1, kImmediateValue, kImmediateValue, kImmediateValue, kNone }, // pb
/* 0x07 */ { "OC_startSpeechIfSilent", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone },
/* 0x08 */ { "OC_computeCharacterVariable", 4, kGetValue1, kImmediateValue, kComputeOperation, kImmediateValue, kNone },
-/* 0x09 */ { "OC_getRandom_type2", 3, kGetValue1, kImmediateValue, kImmediateValue, kNone, kNone },
+/* 0x09 */ { "OC_setAttributeToRandom", 3, kGetValue1, kImmediateValue, kImmediateValue, kNone, kNone },
/* 0x0a */ { "OC_setCharacterPosition", 2, kGetValue1, kgetPosFromScript, kNone, kNone, kNone },
/* 0x0b */ { "OC_disableCharacter", 1, kGetValue1, kNone, kNone, kNone, kNone },
/* 0x0c */ { "OC_saveAndQuit", 0, kNone, kNone, kNone, kNone, kNone },
@@ -629,7 +635,7 @@ static const OpCode opCodes2[] = {
/* 0x10 */ { "OC_deleteSavegameAndQuit", 0, kNone, kNone, kNone, kNone, kNone },
/* 0x11 */ { "OC_incScriptForVal", 0, kNone, kNone, kNone, kNone, kNone },
/* 0x12 */ { "OC_ComputeChararacterAttr", 5, kGetValue1, kImmediateValue,kComputeOperation, kGetValue1, kImmediateValue },
-/* 0x13 */ { "OC_setByte18823", 2, kGetValue1, kImmediateValue, kNone, kNone, kNone },
+/* 0x13 */ { "OC_setTextVarNumber", 2, kGetValue1, kImmediateValue, kNone, kNone, kNone },
/* 0x14 */ { "OC_callScript", 2, kImmediateValue, kGetValue1, kNone, kNone, kNone }, // run script
/* 0x15 */ { "OC_callScriptAndReturn", 2, kImmediateValue, kGetValue1, kNone, kNone, kNone }, // run script then stop
/* 0x16 */ { "OC_setCurrentScriptCharacterPos", 1, kgetPosFromScript, kNone, kNone, kNone, kNone },
@@ -651,8 +657,8 @@ static const OpCode opCodes2[] = {
/* 0x26 */ { "OC_setCurrentCharacterPos", 2, kImmediateValue, kgetPosFromScript, kNone, kNone, kNone },
/* 0x27 */ { "OC_setCurrentCharacterBehavior", 1, kImmediateValue, kNone, kNone, kNone, kNone },
/* 0x28 */ { "OC_changeCurrentCharacterSprite", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone },
-/* 0x29 */ { "OC_sub17E99", 4, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue, kNone },
-/* 0x2a */ { "OC_sub17EC5", 4, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue, kNone },
+/* 0x29 */ { "OC_getList", 4, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue, kNone },
+/* 0x2a */ { "OC_setList", 4, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue, kNone },
/* 0x2b */ { "OC_setCharacterDirectionTowardsPos", 1, kgetPosFromScript, kNone, kNone, kNone, kNone },
/* 0x2c */ { "OC_turnCharacterTowardsAnother", 1, kGetValue1, kNone, kNone, kNone, kNone },
/* 0x2d */ { "OC_setSeek", 1, kGetValue1, kNone, kNone, kNone, kNone },
@@ -664,18 +670,18 @@ static const OpCode opCodes2[] = {
/* 0x33 */ { "OC_setCurrentCharacterAttr2", 1, kImmediateValue, kNone, kNone, kNone, kNone },
/* 0x34 */ { "OC_ClearCurrentCharacterAttr2", 0, kNone, kNone, kNone, kNone, kNone },
/* 0x35 */ { "OC_setCharacterProperties", 5, kGetValue1, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue },
-/* 0x36 */ { "OC_sub1805D", 5, kGetValue1, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue },
+/* 0x36 */ { "OC_setMonitoredCharacter", 5, kGetValue1, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue },
/* 0x37 */ { "OC_setNewPose", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone },
/* 0x38 */ { "OC_setCurrentCharacterDirection", 1, kImmediateValue, kNone, kNone, kNone, kNone },
/* 0x39 */ { "OC_setInterfaceHotspot", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone },
/* 0x3a */ { "OC_scrollViewPort", 1, kImmediateValue, kNone, kNone, kNone, kNone },
/* 0x3b */ { "OC_setViewPortPos", 1, kgetPosFromScript, kNone, kNone, kNone, kNone },
/* 0x3c */ { "OC_setCurrentCharacterAltitude", 1, kImmediateValue, kNone, kNone, kNone, kNone },
-/* 0x3d */ { "OC_sub1817F", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone },
-/* 0x3e */ { "OC_sub181BB", 4, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue, kNone },
-/* 0x3f */ { "OC_sub18213", 1, kImmediateValue, kNone, kNone, kNone, kNone },
+/* 0x3d */ { "OC_setModePriority", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone },
+/* 0x3e */ { "OC_setComputedModePriority", 4, kImmediateValue, kImmediateValue, kImmediateValue, kImmediateValue, kNone },
+/* 0x3f */ { "OC_selectBestMode", 1, kImmediateValue, kNone, kNone, kNone, kNone },
/* 0x40 */ { "OC_magicPuffEntrance", 1, kGetValue1, kNone, kNone, kNone, kNone },
-/* 0x41 */ { "OC_sub18260", 2, kGetValue1, kgetPosFromScript, kNone, kNone, kNone }, // TODO
+/* 0x41 */ { "OC_spawnCharacterAtPos", 2, kGetValue1, kgetPosFromScript, kNone, kNone, kNone }, // TODO
/* 0x42 */ { "OC_characterVariableAddOrRemoveFlag", 4, kGetValue1, kImmediateValue, kImmediateValue, kImmediateValue, kNone },
/* 0x43 */ { "OC_paletteFadeOut", 0, kNone, kNone, kNone, kNone, kNone },
/* 0x44 */ { "OC_paletteFadeIn", 0, kNone, kNone, kNone, kNone, kNone },
@@ -686,7 +692,7 @@ static const OpCode opCodes2[] = {
/* 0x49 */ { "OC_enableCharacterScript", 2, kGetValue1, kImmediateValue, kNone, kNone, kNone },
/* 0x4a */ { "OC_setRulesBuffer2Element", 2, kGetValue1, kImmediateValue, kNone, kNone, kNone },
/* 0x4b */ { "OC_setDebugFlag", 0, kNone, kNone, kNone, kNone, kNone },
-/* 0x4c */ { "OC_setByte14837", 0, kNone, kNone, kNone, kNone, kNone },
+/* 0x4c */ { "OC_setDebugFlag2", 0, kNone, kNone, kNone, kNone, kNone },
/* 0x4d */ { "OC_waitForEvent", 0, kNone, kNone, kNone, kNone, kNone },
/* 0x4e */ { "OC_disableInterfaceHotspot", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone }, // TODO
/* 0x4f */ { "OC_loadFileAerial", 1, kNone, kNone, kNone, kNone, kNone },
@@ -930,7 +936,7 @@ void LilliputScript::runScript(ScriptStream script) {
}
void LilliputScript::runMenuScript(ScriptStream script) {
- debugC(1, kDebugScriptTBC, "runMenuScript");
+ debugC(1, kDebugScript, "runMenuScript");
_byte16F05_ScriptHandler = 0;
@@ -1056,7 +1062,7 @@ void LilliputScript::setSequence(int charIdx, int8 seqIdx) {
assert(charIdx < 40);
_characterLastSequence[charIdx] = seqIdx;
- byte *buf = _vm->_rulesChunk1;
+ byte *buf = _vm->_sequencesArr;
if (seqIdx != 0) {
int count = 0;
while (count < seqIdx) {
@@ -1073,7 +1079,7 @@ void LilliputScript::checkSpeechAllowed(bool &forceReturnFl) {
debugC(1, kDebugScript, "checkSpeechAllowed()");
forceReturnFl = false;
- if ((!_vm->_displayMap) && (_vm->_characterRelativePositionX[_vm->_currentScriptCharacter] != -1))
+ if ((!_vm->_displayMap) && (_vm->_characterRelativePos[_vm->_currentScriptCharacter].x != -1))
return;
forceReturnFl = true;
@@ -1117,8 +1123,8 @@ void LilliputScript::formatSpeechString() {
}
}
-void LilliputScript::sub189B8() {
- debugC(2, kDebugScript, "sub189B8()");
+void LilliputScript::showSpeech() {
+ debugC(2, kDebugScript, "showSpeech()");
formatSpeechString();
int index = 0;
@@ -1149,7 +1155,6 @@ void LilliputScript::decodePackedText(char *buf) {
"'s |'t |re|gg|tt|pp|nn|ay|ar|wh|";
_vm->_displayStringIndex = 0;
- _byte1881A = 0;
int index = 0;
byte var1 = 0;
for (;;) {
@@ -1163,7 +1168,7 @@ void LilliputScript::decodePackedText(char *buf) {
var1 = buf[index];
++index;
if (var1 == '#') {
- _vm->numberToString(_byte18823);
+ _vm->numberToString(_textVarNumber);
}
} else {
_vm->addCharToBuf(var1);
@@ -1195,7 +1200,7 @@ void LilliputScript::decodePackedText(char *buf) {
}
}
- sub189B8();
+ showSpeech();
}
int LilliputScript::getPackedStringStartRelativeIndex(int index) {
@@ -1217,7 +1222,7 @@ void LilliputScript::listAllTexts() {
int index = _vm->_packedStringIndex[i];
int variantCount = 0;
while (_vm->_packedStrings[index + variantCount] == 0x5B)
- ++variantCount ;
+ ++variantCount;
/*
int it = 0;
if (variantCount != 0) {
@@ -1231,7 +1236,7 @@ void LilliputScript::listAllTexts() {
}
} else {*/
decodePackedText(&_vm->_packedStrings[index + variantCount]);
- debugC(1, kDebugScriptTBC, "Text 0x%x variant 0 : %s", i, _vm->_displayStringBuf);
+ debugC(1, kDebugScript, "Text 0x%x variant 0 : %s", i, _vm->_displayStringBuf);
/* }*/
}
}
@@ -1297,46 +1302,43 @@ Common::Point LilliputScript::getPosFromScript() {
switch(tmpVal) {
case 0xFF:
assert((_vm->_currentScriptCharacter >= 0) && (_vm->_currentScriptCharacter < 40));
- return Common::Point(_vm->_characterHomePosX[_vm->_currentScriptCharacter], _vm->_characterHomePosY[_vm->_currentScriptCharacter]);
+ return _vm->_characterHomePos[_vm->_currentScriptCharacter];
case 0xFE: {
int8 index = curWord & 0xFF;
assert((index >= 0) && (index < 40));
- return Common::Point(_vm->_characterHomePosX[index], _vm->_characterHomePosY[index]);
+ return _vm->_characterHomePos[index];
}
case 0xFD:
return _vm->_currentScriptCharacterPos;
case 0xFC: {
int8 index = curWord & 0xFF;
assert((index >= 0) && (index < 40));
- int16 x = _vm->_characterPositionX[index] >> 3;
- int16 y = _vm->_characterPositionY[index] >> 3;
+ int16 x = _vm->_characterPos[index].x >> 3;
+ int16 y = _vm->_characterPos[index].y >> 3;
return Common::Point(x, y);
}
case 0xFB: {
int index = _word16F00_characterId;
assert((index >= 0) && (index < 40));
- int16 x = _vm->_characterPositionX[index] >> 3;
- int16 y = _vm->_characterPositionY[index] >> 3;
+ int16 x = _vm->_characterPos[index].x >> 3;
+ int16 y = _vm->_characterPos[index].y >> 3;
return Common::Point(x, y);
}
case 0xFA:
- return Common::Point(_vm->_characterTargetPosX[_vm->_currentScriptCharacter], _vm->_characterTargetPosY[_vm->_currentScriptCharacter]);
+ return _vm->_characterTargetPos[_vm->_currentScriptCharacter];
case 0xF9:
return Common::Point(_vm->_currentCharacterAttributes[4], _vm->_currentCharacterAttributes[5]);
case 0xF8: {
int8 index = curWord & 0xFF;
assert((index >= 0) && (index < 40));
- return _vm->_rulesBuffer12Pos3[index];
+ return _vm->_keyPos[index];
}
case 0xF7: {
int8 index = _vm->_currentCharacterAttributes[6];
assert((index >= 0) && (index < 40));
- int16 x = _vm->_characterPositionX[index] >> 3;
- int16 y = _vm->_characterPositionY[index] >> 3;
-
- return Common::Point(x, y);
+ return Common::Point(_vm->_characterPos[index].x >> 3, _vm->_characterPos[index].y >> 3);
}
case 0xF6:
return _vm->_savedMousePosDivided;
@@ -1448,7 +1450,7 @@ byte LilliputScript::OC_for() {
}
byte LilliputScript::OC_compCurrentSpeechId() {
- debugC(1, kDebugScriptTBC, "OC_compCurrentSpeechId()");
+ debugC(1, kDebugScript, "OC_compCurrentSpeechId()");
int var1 = _currScript->readUint16LE();
@@ -1468,7 +1470,7 @@ byte LilliputScript::OC_checkSaveFlag() {
}
byte LilliputScript::OC_compScriptForVal() {
- debugC(1, kDebugScriptTBC, "OC_compScriptForVal()");
+ debugC(1, kDebugScript, "OC_compScriptForVal()");
uint16 oper = _currScript->readUint16LE();
int16 var2 = _currScript->readUint16LE();
@@ -1571,7 +1573,7 @@ byte LilliputScript::OC_CompareDistanceFromCharacterToPositionWith() {
}
byte LilliputScript::OC_compareRandomCharacterId() {
- debugC(1, kDebugScriptTBC, "OC_compareRandomCharacterId()");
+ debugC(1, kDebugScript, "OC_compareRandomCharacterId()");
byte *tmpArr = getCharacterAttributesPtr();
_lastRandomValue = _vm->_rnd->getRandomNumber(tmpArr[0] + 1);
@@ -1780,7 +1782,7 @@ byte LilliputScript::OC_IsCharacterValid() {
debugC(1, kDebugScript, "OC_IsCharacterValid()");
int index = getValue1();
- if (_vm->_characterPositionX[index] == -1)
+ if (_vm->_characterPos[index].x == -1)
return 0;
return 1;
@@ -1889,7 +1891,7 @@ byte LilliputScript::OC_CompareGameVariables() {
}
byte LilliputScript::OC_skipNextOpcode() {
- debugC(1, kDebugScriptTBC, "OC_skipNextOpcode()");
+ debugC(1, kDebugScript, "OC_skipNextOpcode()");
_currScript->readUint16LE();
return 1;
@@ -1966,13 +1968,13 @@ byte LilliputScript::OC_CheckCurrentCharacterAttr1() {
return 0;
}
-byte LilliputScript::OC_isCurrentCharacterStung() {
- debugC(1, kDebugScript, "OC_isCurrentCharacterStung()");
+byte LilliputScript::OC_isCurrentCharacterSpecial() {
+ debugC(1, kDebugScript, "OC_isCurrentCharacterSpecial()");
if (_vm->_currentScriptCharacterPos == Common::Point(-1, -1))
return 0;
- if (_vm->_stingArray[_vm->_currentScriptCharacter] == 0)
+ if (_vm->_specialCubes[_vm->_currentScriptCharacter] == 0)
return 0;
return 1;
@@ -2032,11 +2034,10 @@ byte LilliputScript::OC_checkDelayedReactivation() {
}
byte LilliputScript::OC_checkTargetReached() {
- debugC(1, kDebugScriptTBC, "OC_checkTargetReached()");
- Common::Point var1 = getPosFromScript();
+ debugC(1, kDebugScript, "OC_checkTargetReached()");
+ Common::Point pos = getPosFromScript();
- if ((_vm->_characterTargetPosX[_vm->_currentScriptCharacter] == var1.x)
- && (_vm->_characterTargetPosY[_vm->_currentScriptCharacter] == var1.y))
+ if (_vm->_characterTargetPos[_vm->_currentScriptCharacter] == pos)
return 1;
return 0;
@@ -2101,7 +2102,7 @@ void LilliputScript::OC_setWord18821() {
}
void LilliputScript::OC_ChangeIsoMap() {
- debugC(1, kDebugScriptTBC, "OC_ChangeIsoMap()");
+ debugC(1, kDebugScript, "OC_ChangeIsoMap()");
Common::Point var1 = getPosFromScript();
int var2 = _currScript->readUint16LE();
@@ -2168,7 +2169,7 @@ void LilliputScript::getSpeechVariant(int speechIndex, int speechVariant) {
}
void LilliputScript::OC_getComputedVariantSpeech() {
- debugC(1, kDebugScriptTBC, "OC_getComputedVariantSpeech()");
+ debugC(1, kDebugScript, "OC_getComputedVariantSpeech()");
int tmpVal1 = getCharacterAttributesPtr()[0];
int tmpVal2 = (_currScript->readUint16LE() & 0xFF);
@@ -2220,7 +2221,7 @@ void LilliputScript::OC_startSpeechIfMute() {
}
void LilliputScript::OC_getComputedVariantSpeechIfMute() {
- debugC(1, kDebugScriptTBC, "OC_getComputedVariantSpeechIfMute()");
+ debugC(1, kDebugScript, "OC_getComputedVariantSpeechIfMute()");
if (_talkingCharacter == -1) {
OC_getComputedVariantSpeech();
@@ -2254,8 +2255,8 @@ void LilliputScript::OC_ComputeCharacterVariable() {
computeOperation(bufPtr, oper, var3);
}
-void LilliputScript::OC_getRandom_type2() {
- debugC(1, kDebugScript, "OC_getRandom_type2()");
+void LilliputScript::OC_setAttributeToRandom() {
+ debugC(1, kDebugScript, "OC_setAttributeToRandom()");
byte *bufPtr = getCharacterAttributesPtr();
int maxVal = _currScript->readUint16LE();
@@ -2267,14 +2268,13 @@ void LilliputScript::OC_setCharacterPosition() {
debugC(1, kDebugScript, "OC_setCharacterPosition()");
int index = getValue1();
+ assert((index >= 0) && (index < 40));
Common::Point tmpVal = getPosFromScript();
- int var2 = (tmpVal.x << 3) + 4;
- int var4 = (tmpVal.y << 3) + 4;
+ int charPosX = (tmpVal.x << 3) + 4;
+ int charPosY = (tmpVal.y << 3) + 4;
- assert((index >= 0) && (index < 40));
- _vm->_characterPositionX[index] = var2;
- _vm->_characterPositionY[index] = var4;
+ _vm->_characterPos[index] = Common::Point(charPosX, charPosY);
}
void LilliputScript::OC_DisableCharacter() {
@@ -2286,13 +2286,12 @@ void LilliputScript::OC_DisableCharacter() {
if (characterIndex == _vm->_host)
_viewportCharacterTarget = -1;
- _vm->_characterPositionX[characterIndex] = -1;
- _vm->_characterPositionY[characterIndex] = -1;
+ _vm->_characterPos[characterIndex] = Common::Point(-1, -1);
}
void LilliputScript::OC_saveAndQuit() {
warning("TODO: OC_saveAndQuit");
- _vm->_soundHandler->contentFct6(); // Kill music
+ _vm->_soundHandler->remove(); // Kill music
// TODO: Save game
_vm->_shouldQuit = true;
}
@@ -2305,7 +2304,7 @@ void LilliputScript::OC_nSkipOpcodes() {
}
void LilliputScript::OC_startSpeech5() {
- debugC(1, kDebugScriptTBC, "OC_startSpeech5()");
+ debugC(1, kDebugScript, "OC_startSpeech5()");
bool forceReturnFl = false;
checkSpeechAllowed(forceReturnFl);
@@ -2317,18 +2316,18 @@ void LilliputScript::OC_startSpeech5() {
}
void LilliputScript::OC_resetHandleOpcodeFlag() {
- debugC(1, kDebugScriptTBC, "OC_resetHandleOpcodeFlag()");
+ debugC(1, kDebugScript, "OC_resetHandleOpcodeFlag()");
_vm->_handleOpcodeReturnCode = 0;
}
void LilliputScript::OC_deleteSavegameAndQuit() {
- warning("OC_deleteSavegameAndQuit");
+ warning("TODO: OC_deleteSavegameAndQuit");
_vm->_shouldQuit = true;
}
void LilliputScript::OC_incScriptForVal() {
- debugC(1, kDebugScriptTBC, "OC_incScriptForVal()");
+ debugC(1, kDebugScript, "OC_incScriptForVal()");
++_scriptForVal;
}
@@ -2342,18 +2341,17 @@ void LilliputScript::OC_computeChararacterAttr() {
computeOperation(tmpArr, oper, var3);
}
-void LilliputScript::OC_setByte18823() {
- debugC(1, kDebugScriptTBC, "OC_setByte18823()");
+void LilliputScript::OC_setTextVarNumber() {
+ debugC(1, kDebugScript, "OC_setTextVarNumber()");
byte *tmpArr = getCharacterAttributesPtr();
- _byte18823 = *tmpArr;
+ _textVarNumber = *tmpArr;
}
void LilliputScript::OC_callScript() {
debugC(1, kDebugScript, "OC_callScript()");
int index = _currScript->readUint16LE();
-
int charIndex = getValue1();
_vm->setCurrentCharacter(charIndex);
@@ -2389,13 +2387,12 @@ void LilliputScript::OC_setCurrentScriptCharacterPos() {
debugC(1, kDebugScript, "OC_setCurrentScriptCharacterPos()");
Common::Point pos = getPosFromScript();
- _vm->_characterTargetPosX[_vm->_currentScriptCharacter] = pos.x;
- _vm->_characterTargetPosY[_vm->_currentScriptCharacter] = pos.y;
- _vm->_characterSubTargetPosX[_vm->_currentScriptCharacter] = -1;
+ _vm->_characterTargetPos[_vm->_currentScriptCharacter] = pos;
+ _vm->_characterSubTargetPos[_vm->_currentScriptCharacter].x = -1;
}
void LilliputScript::OC_initScriptFor() {
- debugC(1, kDebugScriptTBC, "OC_initScriptFor()");
+ debugC(1, kDebugScript, "OC_initScriptFor()");
_scriptForVal = 0;
}
@@ -2451,8 +2448,6 @@ void LilliputScript::OC_setCharacterCarry() {
_vm->_characterCarried[index] = carriedIdx;
_vm->_characterBehindDist[index] = distBehind;
_vm->_characterAboveDist[index] = distAbove;
-
- warning("debug - OC_setCharacterCarry index %d, var1 0x%x var3 0x%x var4 0x%x", index, carriedIdx, distBehind, distAbove);
}
void LilliputScript::OC_dropCarried() {
@@ -2478,7 +2473,7 @@ void LilliputScript::sendSignal(int16 var1, byte var2h, byte characterId, int16
if (_vm->_signalArray[index + 1] == -1) {
_vm->_signalArray[index + 1] = var1;
_vm->_signalArray[index + 2] = (var2h << 8) + characterId;
- _vm->_signalArray[index + 0] = _vm->_word1289D + var4;
+ _vm->_signalArray[index + 0] = _vm->_signalTimer + var4;
return;
}
index += 3;
@@ -2506,10 +2501,10 @@ void LilliputScript::OC_sendHearSignal() {
}
void LilliputScript::OC_sendVarSignal() {
- debugC(1, kDebugScriptTBC, "OC_sendVarSignal()");
+ debugC(1, kDebugScript, "OC_sendVarSignal()");
int16 var4 = _currScript->readSint16LE();
- int16 type = getValue1(); // CHECKME- dubious
+ int16 type = getValue1();
byte var2h = (_currScript->readUint16LE() & 0xFF);
sendSignal(type, var2h, _vm->_currentScriptCharacter, var4);
@@ -2558,7 +2553,7 @@ void LilliputScript::OC_setCurrentCharacterPos() {
}
void LilliputScript::OC_setCurrentCharacterBehavior() {
- debugC(1, kDebugScriptTBC, "OC_setCurrentCharacterBehavior()");
+ debugC(1, kDebugScript, "OC_setCurrentCharacterBehavior()");
uint16 var1 = _currScript->readUint16LE();
_vm->_characterBehaviour[_vm->_currentScriptCharacter] = (var1 - 2000) & 0xFF;
@@ -2581,8 +2576,8 @@ byte *LilliputScript::getCurrentCharacterVarFromScript() {
return &_vm->_currentCharacterAttributes[index];
}
-void LilliputScript::OC_sub17E99() {
- debugC(1, kDebugScript, "OC_sub17E99()");
+void LilliputScript::OC_getList() {
+ debugC(1, kDebugScript, "OC_getList()");
byte *compBuf = getCurrentCharacterVarFromScript();
uint16 oper = _currScript->readUint16LE();
@@ -2590,31 +2585,31 @@ void LilliputScript::OC_sub17E99() {
byte *buf = getCurrentCharacterVarFromScript();
byte var1 = buf[0];
- byte var3 = _vm->_rulesChunk11[var1 + _vm->_rulesChunk10[index]];
+ byte var3 = _vm->_listArr[var1 + _vm->_listIndex[index]];
computeOperation(compBuf, oper, var3);
}
-void LilliputScript::OC_sub17EC5() {
- debugC(1, kDebugScriptTBC, "OC_sub17EC5()");
+void LilliputScript::OC_setList() {
+ debugC(1, kDebugScript, "OC_setList()");
int indexChunk10 = _currScript->readUint16LE();
byte *compBuf = getCurrentCharacterVarFromScript();
- int indexChunk11 = _vm->_rulesChunk10[indexChunk10] + compBuf[0];
+ int indexChunk11 = _vm->_listIndex[indexChunk10] + compBuf[0];
uint16 oper = _currScript->readUint16LE();
byte *tmpBuf = getCurrentCharacterVarFromScript();
int16 var3 = tmpBuf[0];
- computeOperation(&_vm->_rulesChunk11[indexChunk11], oper, var3);
+ computeOperation(&_vm->_listArr[indexChunk11], oper, var3);
}
Common::Point LilliputScript::getCharacterTilePos(int index) {
debugC(2, kDebugScript, "getCharacterTilePos(%d)", index);
- return Common::Point(_vm->_characterPositionX[index] / 8, _vm->_characterPositionY[index] / 8);
+ return Common::Point(_vm->_characterPos[index].x >> 3, _vm->_characterPos[index].y >> 3);
}
void LilliputScript::OC_setCharacterDirectionTowardsPos() {
@@ -2633,8 +2628,8 @@ void LilliputScript::OC_turnCharacterTowardsAnother() {
static const byte _directionsArray[] = { 0, 2, 0, 1, 3, 2, 3, 1 };
- int dx = _vm->_characterPositionX[index] - _vm->_characterPositionX[_vm->_currentScriptCharacter];
- int dy = _vm->_characterPositionY[index] - _vm->_characterPositionY[_vm->_currentScriptCharacter];
+ int dx = _vm->_characterPos[index].x - _vm->_characterPos[_vm->_currentScriptCharacter].x;
+ int dy = _vm->_characterPos[index].y - _vm->_characterPos[_vm->_currentScriptCharacter].y;
int flag = 0;
if (dx < 0) {
@@ -2657,7 +2652,7 @@ void LilliputScript::OC_setSeek() {
int16 var = getValue1();
_characterSeek[_vm->_currentScriptCharacter] = (byte)(var & 0xFF);
- _vm->_characterSubTargetPosX[_vm->_currentScriptCharacter] = -1;
+ _vm->_characterSubTargetPos[_vm->_currentScriptCharacter].x = -1;
}
void LilliputScript::OC_scrollAwayFromCharacter() {
@@ -2687,7 +2682,7 @@ void LilliputScript::OC_scrollAwayFromCharacter() {
}
void LilliputScript::OC_skipNextVal() {
- debugC(1, kDebugScriptTBC, "OC_skipNextVal()");
+ debugC(1, kDebugScript, "OC_skipNextVal()");
_currScript->readUint16LE();
}
@@ -2737,28 +2732,28 @@ void LilliputScript::OC_setCharacterProperties() {
int16 index = getValue1();
- int16 x = _vm->_characterPositionX[index] & 0xFFF8;
+ int16 x = _vm->_characterPos[index].x & 0xFFF8;
x += _currScript->readSint16LE();
- _vm->_characterPositionX[index] = x;
+ _vm->_characterPos[index].x = x;
- int16 y = _vm->_characterPositionY[index] & 0xFFF8;
+ int16 y = _vm->_characterPos[index].y & 0xFFF8;
y += _currScript->readSint16LE();
- _vm->_characterPositionY[index] = y;
+ _vm->_characterPos[index].y = y;
_vm->_characterPosAltitude[index] = (int8)(_currScript->readUint16LE() & 0xFF);
_vm->_characterDirectionArray[index] = _currScript->readUint16LE() & 0xFF;
}
-void LilliputScript::OC_sub1805D() {
- debugC(1, kDebugScriptTBC, "OC_sub1805D()");
+void LilliputScript::OC_setMonitoredCharacter() {
+ debugC(1, kDebugScript, "OC_setMonitoredCharacter()");
- _word129A3 = getValue1();
+ _monitoredCharacter = getValue1();
for (int i = 0; i < 4; i++)
- _array129A5[i] = _currScript->readUint16LE() & 0xFF;
+ _monitoredAttr[i] = _currScript->readUint16LE() & 0xFF;
}
void LilliputScript::OC_setNewPose() {
- debugC(1, kDebugScriptTBC, "OC_setNewPose()");
+ debugC(1, kDebugScript, "OC_setNewPose()");
int var2 = _currScript->readUint16LE();
byte var1 = (_currScript->readUint16LE() & 0xFF);
@@ -2786,7 +2781,7 @@ void LilliputScript::OC_setInterfaceHotspot() {
}
void LilliputScript::OC_scrollViewPort() {
- debugC(1, kDebugScriptTBC, "OC_scrollViewPort()");
+ debugC(1, kDebugScript, "OC_scrollViewPort()");
_viewportCharacterTarget = -1;
@@ -2822,45 +2817,45 @@ void LilliputScript::OC_setCurrentCharacterAltitude() {
_vm->_characterPosAltitude[_vm->_currentScriptCharacter] = (_currScript->readUint16LE() & 0xFF);
}
-void LilliputScript::OC_sub1817F() {
- debugC(1, kDebugScript, "OC_sub1817F()");
+void LilliputScript::OC_setModePriority() {
+ debugC(1, kDebugScript, "OC_setModePriority()");
+
+ EvaluatedMode newMode;
- int8 x = (int8)(_currScript->readUint16LE() & 0xFF);
- int8 y = (int8)(_currScript->readUint16LE() & 0xFF);
+ newMode._mode = _currScript->readUint16LE() & 0xFF;
+ newMode._priority = _currScript->readUint16LE() & 0xFF;
- sub1818B(Common::Point(x, y));
+ setMode(newMode);
}
-void LilliputScript::sub1818B(Common::Point point) {
- debugC(2, kDebugScript, "sub1818B(%d - %d)", point.x, point.y);
+void LilliputScript::setMode(EvaluatedMode newMode) {
+ debugC(2, kDebugScript, "setMode(%d - %d)", newMode._mode, newMode._priority);
- Common::Point pos = point;
- for (int i = 0; i < _vm->_word1817B; i++) {
- if (_array1813BPos[i].x == pos.x) {
- pos.y += _array1813BPos[i].y;
- if (pos.y > 0xFF)
- pos.y = 0xFF;
+ for (int i = 0; i < _vm->_newModesEvaluatedNumber; i++) {
+ if (_newEvaluatedModes[i]._mode == newMode._mode) {
+ int newPriority = newMode._priority + _newEvaluatedModes[i]._priority;
+ newPriority = CLIP(newPriority, 0, 255);
- _array1813BPos[i] = pos;
+ _newEvaluatedModes[i]._priority = newPriority;
return;
}
}
- _array1813BPos[_vm->_word1817B] = pos;
- ++_vm->_word1817B;
+ _newEvaluatedModes[_vm->_newModesEvaluatedNumber] = newMode;
+ ++_vm->_newModesEvaluatedNumber;
}
-void LilliputScript::OC_sub181BB() {
- debugC(1, kDebugScript, "OC_sub181BB()");
+void LilliputScript::OC_setComputedModePriority() {
+ debugC(1, kDebugScript, "OC_setComputedModePriority()");
- int8 x = (int8)(_currScript->readUint16LE() & 0xFF);
+ int8 mode = (int8)(_currScript->readUint16LE() & 0xFF);
byte oper = _currScript->readUint16LE() & 0xFF;
uint16 index = _currScript->readUint16LE();
int16 c = _vm->_currentCharacterAttributes[index];
switch (oper) {
case '-':
- c = - 1 - c;
+ c = -1 - c;
break;
case '>':
c -= 128;
@@ -2877,29 +2872,34 @@ void LilliputScript::OC_sub181BB() {
case '+':
break;
default:
- warning("OC_sub181BB: skipped oper %c", oper);
+ warning("OC_setComputedModePriority: skipped oper %c", oper);
break;
}
if (c > 0xFF)
- warning("OC_sub181BB- Abnormal value c = %d, should put back c &= 0xFF;", c);
+ warning("OC_setComputedModePriority- Abnormal value c = %d, should put back c &= 0xFF;", c);
- int y = (_currScript->readSint16LE() * c) + c;
- y >>= 8;
- sub1818B(Common::Point(x, y));
+ int priority = (_currScript->readSint16LE() * c) + c;
+ priority >>= 8;
+
+ EvaluatedMode newMode;
+ newMode._mode = mode;
+ newMode._priority = priority;
+
+ setMode(newMode);
}
-void LilliputScript::OC_sub18213() {
- debugC(1, kDebugScript, "OC_sub18213()");
+void LilliputScript::OC_selectBestMode() {
+ debugC(1, kDebugScript, "OC_selectBestMode()");
uint16 var1 = _currScript->readUint16LE();
int maxValue = 0;
int maxItem = var1 & 0xFF;
- for (int i = 0; i < _vm->_word1817B; i++) {
- if (_array1813BPos[i].y > maxValue) {
- maxValue = _array1813BPos[i].y;
- maxItem = _array1813BPos[i].x;
+ for (int i = 0; i < _vm->_newModesEvaluatedNumber; i++) {
+ if (_newEvaluatedModes[i]._priority > maxValue) {
+ maxValue = _newEvaluatedModes[i]._priority;
+ maxItem = _newEvaluatedModes[i]._mode;
}
}
enableCharacterScript(_vm->_currentScriptCharacter, maxItem, _vm->_currentCharacterAttributes);
@@ -2914,8 +2914,8 @@ void LilliputScript::OC_magicPuffEntrance() {
_vm->_characterMagicPuffFrame[index] = 4;
}
-void LilliputScript::OC_sub18260() {
- debugC(1, kDebugScriptTBC, "OC_sub18260()");
+void LilliputScript::OC_spawnCharacterAtPos() {
+ debugC(1, kDebugScript, "OC_spawnCharacterAtPos()");
int index = getValue1();
Common::Point var4 = getPosFromScript();
@@ -2943,8 +2943,8 @@ void LilliputScript::OC_sub18260() {
var4 = _word1825E;
}
- _vm->_characterPositionX[index] = (var4.x + _viewportPos.x) * 8;
- _vm->_characterPositionY[index] = (var4.y + _viewportPos.y) * 8;
+ _vm->_characterPos[index].x = (var4.x + _viewportPos.x) * 8;
+ _vm->_characterPos[index].y = (var4.y + _viewportPos.y) * 8;
}
void LilliputScript::OC_CharacterVariableAddOrRemoveFlag() {
@@ -3032,23 +3032,23 @@ void LilliputScript::OC_setRulesBuffer2Element() {
byte var1 = _currScript->readUint16LE() & 0xFF;
assert((index >= 0) && (index < 40));
- _vm->_rulesBuffer2_10[index] = var1;
+ _vm->_characterMobility[index] = var1;
}
void LilliputScript::OC_setDebugFlag() {
- debugC(1, kDebugScriptTBC, "OC_setDebugFlag()");
+ debugC(1, kDebugScript, "OC_setDebugFlag()");
_vm->_debugFlag = 1;
}
-void LilliputScript::OC_setByte14837() {
- debugC(1, kDebugScriptTBC, "OC_setByte14837()");
+void LilliputScript::OC_setDebugFlag2() {
+ debugC(1, kDebugScript, "OC_setDebugFlag2()");
- _vm->_byte14837 = 1;
+ _vm->_debugFlag2 = 1;
}
void LilliputScript::OC_waitForEvent() {
- debugC(1, kDebugScriptTBC, "OC_waitForEvent()");
+ debugC(1, kDebugScript, "OC_waitForEvent()");
_vm->_refreshScreenFlag = true;
while (true) {
@@ -3100,7 +3100,7 @@ void LilliputScript::OC_loadFileAerial() {
}
void LilliputScript::OC_startSpeechIfSoundOff() {
- debugC(1, kDebugScriptTBC, "OC_startSpeechIfSoundOff()");
+ debugC(1, kDebugScript, "OC_startSpeechIfSoundOff()");
// HACK: In the original, OC_startSpeechIfSoundOff() only calls
// OC_startSpeech if sound is off. For the moment, it's always called
@@ -3218,7 +3218,7 @@ void LilliputScript::OC_initGameAreaDisplay() {
OC_PaletteFadeIn();
_vm->_refreshScreenFlag = false;
- _vm->_soundHandler->contentFct5();
+ _vm->_soundHandler->update();
}
void LilliputScript::OC_displayCharacterStatBar() {
@@ -3249,18 +3249,16 @@ void LilliputScript::OC_initSmallAnim() {
void LilliputScript::OC_setCharacterHeroismBar() {
debugC(1, kDebugScript, "OC_setCharacterHeroismBar()");
- _savedBuffer215Ptr = getCharacterAttributesPtr();
+ _barAttrPtr = getCharacterAttributesPtr();
_heroismBarX = _currScript->readUint16LE();
_heroismBarBottomY = _currScript->readUint16LE();
}
void LilliputScript::OC_setCharacterHome() {
- debugC(1, kDebugScriptTBC, "OC_setCharacterHome()");
+ debugC(1, kDebugScript, "OC_setCharacterHome()");
int index = getValue1();
- Common::Point pos = getPosFromScript();
- _vm->_characterHomePosX[index] = pos.x;
- _vm->_characterHomePosY[index] = pos.y;
+ _vm->_characterHomePos[index] = getPosFromScript();
}
void LilliputScript::OC_setViewPortCharacterTarget() {
@@ -3270,16 +3268,16 @@ void LilliputScript::OC_setViewPortCharacterTarget() {
}
void LilliputScript::OC_showObject() {
- debugC(1, kDebugScriptTBC, "OC_showObject()");
+ debugC(1, kDebugScript, "OC_showObject()");
- int var1 = getValue1();
+ int frameIdx = getValue1();
int posX = _currScript->readUint16LE();
int posY = _currScript->readUint16LE();
Common::Point pos = Common::Point(posX, posY);
_vm->fill16x16Rect(16, pos);
- int frame = _vm->_characterFrameArray[var1];
+ int frame = _vm->_characterFrameArray[frameIdx];
byte* buf = _vm->_bufferMen;
if (frame > 240) {
@@ -3298,7 +3296,7 @@ void LilliputScript::OC_playObjectSound() {
Common::Point var4 = Common::Point(0xFF, index & 0xFF);
int soundId = (_currScript->readUint16LE() & 0xFF);
- _vm->_soundHandler->contentFct2(soundId, _viewportPos, _characterTilePos[index], var4);
+ _vm->_soundHandler->play(soundId, _viewportPos, _characterTilePos[index], var4);
}
void LilliputScript::OC_startLocationSound() {
@@ -3309,7 +3307,7 @@ void LilliputScript::OC_startLocationSound() {
Common::Point var2 = _viewportPos;
int var1 = (_currScript->readUint16LE() & 0xFF);
- _vm->_soundHandler->contentFct2(var1, var2, var3, var4);
+ _vm->_soundHandler->play(var1, var2, var3, var4);
}
void LilliputScript::OC_stopObjectSound() {
@@ -3317,7 +3315,7 @@ void LilliputScript::OC_stopObjectSound() {
Common::Point var4 = Common::Point(-1, getValue1() & 0xFF);
- _vm->_soundHandler->contentFct3(var4); // Stop Sound
+ _vm->_soundHandler->stop(var4); // Stop Sound
}
void LilliputScript::OC_stopLocationSound() {
@@ -3325,13 +3323,13 @@ void LilliputScript::OC_stopLocationSound() {
Common::Point var4 = getPosFromScript();
- _vm->_soundHandler->contentFct3(var4);
+ _vm->_soundHandler->stop(var4);
}
void LilliputScript::OC_toggleSound() {
- debugC(1, kDebugScriptTBC, "OC_toggleSound()");
+ debugC(1, kDebugScript, "OC_toggleSound()");
- _vm->_soundHandler->contentFct4();
+ _vm->_soundHandler->toggleOnOff();
}
void LilliputScript::OC_playMusic() {
@@ -3343,13 +3341,13 @@ void LilliputScript::OC_playMusic() {
warning("OC_playMusic: unknown value for var3");
Common::Point var3 = Common::Point(-1, -1);
- _vm->_soundHandler->contentFct2(var1, var2, var3, var4);
+ _vm->_soundHandler->play(var1, var2, var3, var4);
}
void LilliputScript::OC_stopMusic() {
debugC(1, kDebugScript, "OC_stopMusic()");
- _vm->_soundHandler->contentFct6();
+ _vm->_soundHandler->remove();
}
void LilliputScript::OC_setCharacterMapColor() {
diff --git a/engines/lilliput/script.h b/engines/lilliput/script.h
index 2199f51a3b..d75d24e3cf 100644
--- a/engines/lilliput/script.h
+++ b/engines/lilliput/script.h
@@ -53,7 +53,6 @@ enum kValueType {
kgetPosFromScript
};
-
struct OpCode {
const char* _opName;
int _numArgs;
@@ -64,6 +63,11 @@ struct OpCode {
kValueType _arg5;
};
+struct EvaluatedMode {
+ int _mode;
+ int _priority;
+};
+
class LilliputScript {
public:
byte _heroismLevel;
@@ -79,7 +83,7 @@ public:
byte _characterSeek[40];
int16 _interactions[40 * 40];
- byte *_savedBuffer215Ptr;
+ byte *_barAttrPtr;
Common::Point _viewportPos;
int16 _viewportCharacterTarget;
@@ -90,7 +94,7 @@ public:
Common::Point _sequenceArr[640];
byte _characterMapPixelColor[40];
int8 _characterLastSequence[40];
- Common::Point _array1813BPos[32];
+ EvaluatedMode _newEvaluatedModes[32];
LilliputScript(LilliputEngine *vm);
~LilliputScript();
@@ -110,17 +114,16 @@ private:
byte _cubeSet;
byte _lastRandomValue;
byte _scriptForVal;
- byte _byte1881A;
- byte _byte18823;
+ byte _textVarNumber;
byte _speechDisplaySpeed;
int16 _word16F00_characterId;
int _currentSpeechId;
int _word18821;
- int _word129A3;
+ int _monitoredCharacter;
Common::Point _word1825E;
- char _array129A5[4];
+ char _monitoredAttr[4];
int handleOpcode(ScriptStream *script);
byte handleOpcodeType1(int curWord);
@@ -138,7 +141,7 @@ private:
byte *getCurrentCharacterVarFromScript();
void sendSignal(int16 var1, byte var2h, byte characterId, int16 var4);
void getSpeechVariant(int speechIndex, int speechVariant);
- void sub189B8();
+ void showSpeech();
void formatSpeechString();
Common::Point getCharacterTilePos(int index);
int getPackedStringStartRelativeIndex(int index);
@@ -191,7 +194,7 @@ private:
byte OC_IsCurrentCharacterAttr0LessEqualThan();
byte OC_isCarried();
byte OC_CheckCurrentCharacterAttr1();
- byte OC_isCurrentCharacterStung();
+ byte OC_isCurrentCharacterSpecial();
byte OC_CurrentCharacterAttr3Equals1();
byte OC_checkCharacterDirection();
byte OC_checkLastInterfaceHotspotIndex();
@@ -212,7 +215,7 @@ private:
void OC_getComputedVariantSpeechIfMute();
void OC_startSpeechIfSilent();
void OC_ComputeCharacterVariable();
- void OC_getRandom_type2();
+ void OC_setAttributeToRandom();
void OC_setCharacterPosition();
void OC_DisableCharacter();
void OC_saveAndQuit();
@@ -222,7 +225,7 @@ private:
void OC_deleteSavegameAndQuit();
void OC_incScriptForVal();
void OC_computeChararacterAttr();
- void OC_setByte18823();
+ void OC_setTextVarNumber();
void OC_callScript();
void OC_callScriptAndReturn();
void OC_setCurrentScriptCharacterPos();
@@ -244,8 +247,8 @@ private:
void OC_setCurrentCharacterPos();
void OC_setCurrentCharacterBehavior();
void OC_changeCurrentCharacterSprite();
- void OC_sub17E99();
- void OC_sub17EC5();
+ void OC_getList();
+ void OC_setList();
void OC_setCharacterDirectionTowardsPos();
void OC_turnCharacterTowardsAnother();
void OC_setSeek();
@@ -257,19 +260,19 @@ private:
void OC_setCurrentCharacterAttr2();
void OC_clearCurrentCharacterAttr2();
void OC_setCharacterProperties();
- void OC_sub1805D();
+ void OC_setMonitoredCharacter();
void OC_setNewPose();
void OC_setCurrentCharacterDirection();
void OC_setInterfaceHotspot();
void OC_scrollViewPort();
void OC_setViewPortPos();
void OC_setCurrentCharacterAltitude();
- void OC_sub1817F();
- void sub1818B(Common::Point point);
- void OC_sub181BB();
- void OC_sub18213();
+ void OC_setModePriority();
+ void setMode(EvaluatedMode newMode);
+ void OC_setComputedModePriority();
+ void OC_selectBestMode();
void OC_magicPuffEntrance();
- void OC_sub18260();
+ void OC_spawnCharacterAtPos();
void OC_CharacterVariableAddOrRemoveFlag();
void OC_PaletteFadeOut();
void OC_PaletteFadeIn();
@@ -280,7 +283,7 @@ private:
void OC_enableCharacterScript();
void OC_setRulesBuffer2Element();
void OC_setDebugFlag();
- void OC_setByte14837();
+ void OC_setDebugFlag2();
void OC_waitForEvent();
void OC_disableInterfaceHotspot();
void OC_loadFileAerial();
diff --git a/engines/lilliput/sound.cpp b/engines/lilliput/sound.cpp
index d94cf1eb76..55624e74b1 100644
--- a/engines/lilliput/sound.cpp
+++ b/engines/lilliput/sound.cpp
@@ -28,38 +28,116 @@
namespace Lilliput {
LilliputSound::LilliputSound(LilliputEngine *vm) : _vm(vm) {
+ _unpackedFiles = nullptr;
+ _unpackedSizes = nullptr;
}
LilliputSound::~LilliputSound() {
+ if (_unpackedFiles) {
+ for (int i = 0; i < _fileNumb; i++)
+ free(_unpackedFiles[i]);
+ }
+ free(_unpackedFiles);
+ free(_unpackedSizes);
}
-// Used during initialisation
-void LilliputSound::contentFct0() {
- debugC(1, kDebugSound, "contentFct0()");
+byte LilliputSound::readByte(const byte *data, uint32 offset) {
+ uint16 al = data[0x201 + (offset >> 1)];
+ return data[1 + (offset & 1) + (al << 1)];
}
-void LilliputSound::contentFct1() {
- debugC(1, kDebugSound, "contentFct1()");
+uint32 LilliputSound::decode(const byte *src, byte *dst, uint32 len, uint32 start) {
+ uint32 i = start;
+ for (; i < len; ++i) {
+ *dst++ = readByte(src, i);
+ }
+ return i;
}
-void LilliputSound::contentFct2(int var1, Common::Point var2, Common::Point var3, Common::Point var4) {
- debugC(1, kDebugSound, "contentFct2(%d, %d - %d, %d - %d, %d - %d)", var1, var2.x, var2.y, var3.x, var3.y, var4.x, var4.y);
+void LilliputSound::loadMusic(Common::String filename) {
+ debugC(1, kDebugSound, "loadMusic(%s)", filename.c_str());
+
+ Common::File f;
+
+ if (!f.open(filename))
+ error("Missing music file %s", filename.c_str());
+
+ _fileNumb = f.readUint16LE();
+
+ int *fileSizes = new int[_fileNumb + 1];
+ for (int i = 0; i < _fileNumb; ++i)
+ fileSizes[i] = f.readUint16LE();
+ f.seek(0, SEEK_END);
+ fileSizes[_fileNumb] = f.pos();
+
+ _unpackedFiles = new byte *[_fileNumb];
+ _unpackedSizes = new uint16[_fileNumb];
+ int pos = (_fileNumb + 1) * 2; // file number + file sizes
+ for (int i = 0; i < _fileNumb; ++i) {
+ int packedSize = fileSizes[i + 1] - fileSizes[i];
+ byte *srcBuf = new byte[packedSize];
+ f.seek(pos, SEEK_SET);
+ f.read(srcBuf, packedSize);
+ if (srcBuf[0] == 'c' || srcBuf[0] == 'C') {
+ int shift = (srcBuf[0] == 'c') ? 1 : 0;
+ _unpackedSizes[i] = (1 + packedSize - 0x201) * 2 - shift;
+ byte *dstBuf = new byte[_unpackedSizes[i]];
+ decode(srcBuf, dstBuf, _unpackedSizes[i], shift);
+ _unpackedFiles[i] = dstBuf;
+ } else {
+ _unpackedSizes[i] = packedSize;
+ byte *dstBuf = new byte[packedSize];
+ for (int j = 0; j < packedSize; ++j)
+ dstBuf[j] = srcBuf[j];
+ _unpackedFiles[i] = dstBuf;
+ }
+ delete srcBuf;
+ pos += packedSize;
+ }
+
+ delete fileSizes;
+ f.close();
+
+ // Debug code
+ for (int i = 0; i < _fileNumb; ++i) {
+ Common::DumpFile dmp;
+ Common::String name = Common::String::format("dmp%d.mid", i);
+ dmp.open(name);
+ dmp.write(_unpackedFiles[i], _unpackedSizes[i]);
+ dmp.close();
+ }
+ //
+}
+
+// Used during initialization
+void LilliputSound::init() {
+ debugC(1, kDebugSound, "LilliputSound::init()");
+
+ loadMusic("ROBIN.MUS");
+}
+
+void LilliputSound::refresh() {
+ debugC(1, kDebugSound, "LilliputSound::refresh()");
+}
+
+void LilliputSound::play(int var1, Common::Point var2, Common::Point var3, Common::Point var4) {
+ debugC(1, kDebugSound, "LilliputSound::play(%d, %d - %d, %d - %d, %d - %d)", var1, var2.x, var2.y, var3.x, var3.y, var4.x, var4.y);
}
-void LilliputSound::contentFct3(Common::Point pos) {
- debugC(1, kDebugSound, "contentFct3(%d - %d)", pos.x, pos.y);
+void LilliputSound::stop(Common::Point pos) {
+ debugC(1, kDebugSound, "LilliputSound::stop(%d - %d)", pos.x, pos.y);
}
-void LilliputSound::contentFct4() {
- debugC(1, kDebugSound, "contentFct4()");
+void LilliputSound::toggleOnOff() {
+ debugC(1, kDebugSound, "LilliputSound::toggleOnOff()");
}
-void LilliputSound::contentFct5() {
- debugC(1, kDebugSound, "contentFct5()");
+void LilliputSound::update() {
+ debugC(1, kDebugSound, "LilliputSound::update()");
}
-void LilliputSound::contentFct6() {
- debugC(1, kDebugSound, "contentFct6()");
+void LilliputSound::remove() {
+ debugC(1, kDebugSound, "Lilliput::remove()");
}
} // End of namespace
diff --git a/engines/lilliput/sound.h b/engines/lilliput/sound.h
index 6d5bf6f556..9d164a0b80 100644
--- a/engines/lilliput/sound.h
+++ b/engines/lilliput/sound.h
@@ -32,16 +32,25 @@ public:
LilliputSound(LilliputEngine *vm);
~LilliputSound();
- void contentFct0();
- void contentFct1();
- void contentFct2(int var1, Common::Point var2, Common::Point var3, Common::Point var4);
- void contentFct3(Common::Point pos);
- void contentFct4();
- void contentFct5();
- void contentFct6();
+ void init();
+ void refresh();
+ void play(int var1, Common::Point var2, Common::Point var3, Common::Point var4);
+ void stop(Common::Point pos);
+ void toggleOnOff();
+ void update();
+ void remove();
private:
LilliputEngine *_vm;
+
+ int _fileNumb;
+ byte **_unpackedFiles;
+ uint16 *_unpackedSizes;
+
+ uint32 decode(const byte *src, byte *dst, uint32 len, uint32 start);
+ byte readByte(const byte *data, uint32 offset);
+
+ void loadMusic(Common::String filename);
};
} // End of namespace Lilliput
diff --git a/engines/macventure/detection.cpp b/engines/macventure/detection.cpp
index c179647121..5eda420cb2 100644
--- a/engines/macventure/detection.cpp
+++ b/engines/macventure/detection.cpp
@@ -54,7 +54,7 @@ static const PlainGameDescriptor macventureGames[] = {
namespace MacVenture {
-SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot);
+SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot, bool skipThumbnail = true);
class MacVentureMetaEngine : public AdvancedMetaEngine {
public:
@@ -164,7 +164,7 @@ SaveStateDescriptor MacVentureMetaEngine::querySaveMetaInfos(const char *target,
Common::InSaveFile *in = saveFileMan->openForLoading(saveFileName);
if (in) {
- desc = loadMetaData(in, slot);
+ desc = loadMetaData(in, slot, false);
delete in;
return desc;
}
diff --git a/engines/macventure/saveload.cpp b/engines/macventure/saveload.cpp
index 89a6301318..c63b6a6951 100644
--- a/engines/macventure/saveload.cpp
+++ b/engines/macventure/saveload.cpp
@@ -42,7 +42,7 @@ namespace MacVenture {
#define MACVENTURE_SAVE_VERSION 1 //1 BYTE
#define MACVENTURE_DESC_LENGTH 4 //4 BYTE for the metadata length
-SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot) {
+SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot, bool skipThumbnail) {
// Metadata is stored at the end of the file
// |THUMBNAIL |
// | |
@@ -65,8 +65,11 @@ SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot) {
s->seek(-(5 + MACVENTURE_DESC_LENGTH + metaSize), SEEK_END);
// Load the thumbnail
- Graphics::Surface *thumb = Graphics::loadThumbnail(*s);
- desc.setThumbnail(thumb);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*s, thumbnail, skipThumbnail)) {
+ return desc;
+ }
+ desc.setThumbnail(thumbnail);
// Load the description
Common::String name;
diff --git a/engines/mads/detection.cpp b/engines/mads/detection.cpp
index 4fb8b82eb3..8eb3b4eee9 100644
--- a/engines/mads/detection.cpp
+++ b/engines/mads/detection.cpp
@@ -203,11 +203,8 @@ SaveStateList MADSMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- MADS::Game::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- header._thumbnail->free();
- delete header._thumbnail;
+ if (MADS::Game::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
delete in;
}
}
@@ -233,7 +230,10 @@ SaveStateDescriptor MADSMetaEngine::querySaveMetaInfos(const char *target, int s
if (f) {
MADS::MADSSavegameHeader header;
- MADS::Game::readSavegameHeader(f, header);
+ if (!MADS::Game::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
delete f;
// Create the return descriptor
diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp
index 0a6741ba7a..bea0ea3bb4 100644
--- a/engines/mads/game.cpp
+++ b/engines/mads/game.cpp
@@ -485,11 +485,6 @@ void Game::loadGame(int slotNumber) {
if (!readSavegameHeader(_saveFile, header))
error("Invalid savegame");
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
// Load most of the savegame data with the exception of scene specific info
synchronize(s, true);
@@ -527,9 +522,8 @@ void Game::saveGame(int slotNumber, const Common::String &saveName) {
const char *const SAVEGAME_STR = "MADS";
#define SAVEGAME_STR_SIZE 4
-bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header) {
+WARN_UNUSED_RESULT bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -546,9 +540,9 @@ bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header
while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
diff --git a/engines/mads/game.h b/engines/mads/game.h
index 9defb58b1a..b979160f3d 100644
--- a/engines/mads/game.h
+++ b/engines/mads/game.h
@@ -237,7 +237,7 @@ public:
/**
* Read in a savegame header
*/
- static bool readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header, bool skipThumbnail = true);
/**
* Creates a temporary thumbnail for use in saving games
diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp
index 1db5eaea00..99402748b8 100644
--- a/engines/mads/nebular/game_nebular.cpp
+++ b/engines/mads/nebular/game_nebular.cpp
@@ -45,8 +45,9 @@ GameNebular::GameNebular(MADSEngine *vm)
}
ProtectionResult GameNebular::checkCopyProtection() {
- //if (!ConfMan.getBool("copy_protection"))
- // return PROTECTION_SUCCEED;
+ // Only show copy protection dialog if explicitly wanted
+ if (!ConfMan.getBool("copy_protection"))
+ return PROTECTION_SUCCEED;
CopyProtectionDialog *dlg;
bool correctAnswer;
diff --git a/engines/mads/nebular/nebular_scenes4.cpp b/engines/mads/nebular/nebular_scenes4.cpp
index a4c6a3ebe1..8b7eb1a9ec 100644
--- a/engines/mads/nebular/nebular_scenes4.cpp
+++ b/engines/mads/nebular/nebular_scenes4.cpp
@@ -2443,7 +2443,7 @@ void Scene405::step() {
}
if (_game._trigger == 70) {
- _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount ;
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
_game._player._visible = true;
_globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
_scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71);
@@ -2458,7 +2458,7 @@ void Scene405::step() {
}
if (_game._trigger == 75) {
- _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount ;
+ _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount;
_game._player._visible = true;
_scene->_sequences.remove(_globals._sequenceIndexes[1]);
_globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0);
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 9103b03a31..11279ec376 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -262,8 +262,38 @@ void MohawkEngine_Myst::playMovieBlocking(const Common::String &name, MystStack
waitUntilMovieEnds(video);
}
-void MohawkEngine_Myst::playFlybyMovie(const Common::String &name) {
- Common::String filename = wrapMovieFilename(name, kMasterpieceOnly);
+void MohawkEngine_Myst::playFlybyMovie(uint16 stack, uint16 card) {
+ // Play Flyby Entry Movie on Masterpiece Edition.
+ const char *flyby = nullptr;
+
+ switch (stack) {
+ case kSeleniticStack:
+ flyby = "selenitic flyby";
+ break;
+ case kStoneshipStack:
+ flyby = "stoneship flyby";
+ break;
+ // Myst Flyby Movie not used in Original Masterpiece Edition Engine
+ // We play it when first arriving on Myst, and if the user has chosen so.
+ case kMystStack:
+ if (ConfMan.getBool("playmystflyby"))
+ flyby = "myst flyby";
+ break;
+ case kMechanicalStack:
+ flyby = "mech age flyby";
+ break;
+ case kChannelwoodStack:
+ flyby = "channelwood flyby";
+ break;
+ default:
+ break;
+ }
+
+ if (!flyby) {
+ return;
+ }
+
+ Common::String filename = wrapMovieFilename(flyby, kMasterpieceOnly);
VideoEntryPtr video = _video->playMovie(filename, Audio::Mixer::kSFXSoundType);
if (!video) {
error("Failed to open the '%s' movie", filename.c_str());
@@ -486,20 +516,27 @@ void MohawkEngine_Myst::pauseEngineIntern(bool pause) {
void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcSound, uint16 linkDstSound) {
debug(2, "changeToStack(%d)", stack);
- _curStack = stack;
-
// Fill screen with black and empty cursor
_cursor->setCursor(0);
_currentCursor = 0;
+ _sound->stopEffect();
+ _video->stopVideos();
+
+ // In Myst ME, play a fullscreen flyby movie, except when loading saves.
+ // Also play a flyby when first linking to Myst.
+ if (getFeatures() & GF_ME
+ && (_curStack != kIntroStack || (stack == kMystStack && card == 4134))) {
+ playFlybyMovie(stack, card);
+ }
+
+ _sound->stopBackground();
+
if (getFeatures() & GF_ME)
_system->fillScreen(_system->getScreenFormat().RGBToColor(0, 0, 0));
else
_gfx->clearScreenPalette();
- _sound->stopEffect();
- _sound->stopBackground();
- _video->stopVideos();
if (linkSrcSound)
playSoundBlocking(linkSrcSound);
@@ -509,6 +546,8 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
delete _prevStack;
_prevStack = _scriptParser;
+ _curStack = stack;
+
switch (_curStack) {
case kChannelwoodStack:
_gameState->_globals.currentAge = 4;
@@ -576,38 +615,6 @@ void MohawkEngine_Myst::changeToStack(uint16 stack, uint16 card, uint16 linkSrcS
_cache.clear();
_gfx->clearCache();
- if (getFeatures() & GF_ME) {
- // Play Flyby Entry Movie on Masterpiece Edition.
- const char *flyby = nullptr;
-
- switch (_curStack) {
- case kSeleniticStack:
- flyby = "selenitic flyby";
- break;
- case kStoneshipStack:
- flyby = "stoneship flyby";
- break;
- // Myst Flyby Movie not used in Original Masterpiece Edition Engine
- // We play it when first arriving on Myst, and if the user has chosen so.
- case kMystStack:
- if (ConfMan.getBool("playmystflyby") && card == 4134)
- flyby = "myst flyby";
- break;
- case kMechanicalStack:
- flyby = "mech age flyby";
- break;
- case kChannelwoodStack:
- flyby = "channelwood flyby";
- break;
- default:
- break;
- }
-
- if (flyby) {
- playFlybyMovie(flyby);
- }
- }
-
changeToCard(card, kTransitionCopy);
if (linkDstSound)
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 379110fbc4..2758b7fdca 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -229,7 +229,7 @@ public:
VideoEntryPtr playMovie(const Common::String &name, MystStack stack);
VideoEntryPtr findVideo(const Common::String &name, MystStack stack);
void playMovieBlocking(const Common::String &name, MystStack stack, uint16 x, uint16 y);
- void playFlybyMovie(const Common::String &name);
+ void playFlybyMovie(uint16 stack, uint16 card);
void waitUntilMovieEnds(const VideoEntryPtr &video);
void playSoundBlocking(uint16 id);
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 70923e93d5..4b22a94d0c 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -625,6 +625,8 @@ void MystScriptParser::o_copyImageToBackBuffer(uint16 var, const ArgumentsArray
}
void MystScriptParser::o_changeBackgroundSound(uint16 var, const ArgumentsArray &args) {
+ soundWaitStop();
+
// Used on Stoneship Card 2080
// Used on Channelwood Card 3225 with argc = 8 i.e. Conditional Sound List
Common::MemoryWriteStreamDynamic writeStream = Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
@@ -787,12 +789,16 @@ void MystScriptParser::o_soundWaitStop(uint16 var, const ArgumentsArray &args) {
// Used on Selenitic Card 1191 (Maze Runner)
// Used on Mechanical Card 6267 (Code Lock)
// Used when Button is pushed...
- while (_vm->_sound->isEffectPlaying())
+ soundWaitStop();
+}
+
+void MystScriptParser::soundWaitStop() const {
+ while (_vm->_sound->isEffectPlaying() && !Engine::shouldQuit())
_vm->doFrame();
}
void MystScriptParser::o_quit(uint16 var, const ArgumentsArray &args) {
- _vm->quitGame();
+ Engine::quitGame();
}
void MystScriptParser::showMap() {
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index 3ef8663324..a7a840b9d3 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -87,6 +87,7 @@ public:
void showMap();
void animatedUpdate(const ArgumentsArray &args, uint16 delay);
+ void soundWaitStop() const;
// Common opcodes
DECLARE_OPCODE(o_toggleVar);
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index bbecebbb66..c63f908bda 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -633,25 +633,41 @@ uint16 Myst::getVar(uint16 var) {
return 10;
case 79: // Stellar Observatory Date - Year #4 (Right)
return (_state.observatoryYearSetting / 1) % 10;
- case 80: // Stellar Observatory Hour #1 - Left ( Number 1 (0) or Blank (10))
+ case 80: // Stellar Observatory Hour #1 - Left ( Hour digits can be 10 (Blank), or 0-2)
+ uint32 observatoryLeftMinutes;
if (!observatoryIsDDMMYYYY2400()) {
- if (_state.observatoryTimeSetting % (12 * 60) < (10 * 60))
+ // 12 Hour Format
+ observatoryLeftMinutes = _state.observatoryTimeSetting % (12 * 60);
+ if (observatoryLeftMinutes > 59 && observatoryLeftMinutes < (10 * 60))
return 10;
else
return 1;
} else {
- if (_state.observatoryTimeSetting < (10 * 60))
- return 10;
- else if (_state.observatoryTimeSetting < (20 * 60))
+ // 24 Hour Format
+ observatoryLeftMinutes = _state.observatoryTimeSetting;
+ if (observatoryLeftMinutes < (10 * 60))
+ return 0;
+ else if (observatoryLeftMinutes < (20 * 60))
return 1;
else
return 2;
}
case 81: // Stellar Observatory Hour #2 - Right
- if (!observatoryIsDDMMYYYY2400())
- return ((_state.observatoryTimeSetting % (12 * 60)) / 60) % 10;
- else
- return (_state.observatoryTimeSetting / 60) % 10;
+ uint32 observatoryRightMinutes,observatoryRightHour;
+ if (!observatoryIsDDMMYYYY2400()) {
+ // 12 Hour Format
+ observatoryRightMinutes = _state.observatoryTimeSetting % (12 * 60);
+ observatoryRightHour = observatoryRightMinutes / 60;
+ if (observatoryRightHour % 12 == 0)
+ return 2;
+ else
+ return observatoryRightHour % 10;
+ } else {
+ // 24 Hour Format
+ observatoryRightMinutes = _state.observatoryTimeSetting;
+ observatoryRightHour = observatoryRightMinutes / 60;
+ return observatoryRightHour % 10;
+ }
case 82: // Stellar Observatory Minutes #1 - Left
return (_state.observatoryTimeSetting % 60) / 10;
case 83: // Stellar Observatory Minutes #2 - Right
@@ -1626,6 +1642,7 @@ void Myst::observatoryIncrementMonth(int16 increment) {
}
_vm->_sound->playEffect(8500);
+ _vm->wait(20);
}
void Myst::observatoryMonthChange_run() {
@@ -1692,6 +1709,7 @@ void Myst::observatoryIncrementDay(int16 increment) {
}
_vm->_sound->playEffect(8500);
+ _vm->wait(20);
}
void Myst::observatoryDayChange_run() {
@@ -1752,6 +1770,7 @@ void Myst::observatoryIncrementYear(int16 increment) {
}
_vm->_sound->playEffect(8500);
+ _vm->wait(20);
}
void Myst::observatoryYearChange_run() {
@@ -1817,6 +1836,7 @@ void Myst::observatoryIncrementTime(int16 increment) {
}
_vm->_sound->playEffect(8500);
+ _vm->wait(20);
}
void Myst::observatoryTimeChange_run() {
@@ -2441,7 +2461,7 @@ void Myst::o_rocketLeverMove(uint16 var, const ArgumentsArray &args) {
uint16 soundId = lever->getList2(0);
if (soundId)
- _vm->_sound->playEffect(soundId);
+ _vm->playSoundBlocking(soundId);
// If rocket correctly powered
if (_state.generatorVoltage == 59 && !_state.generatorBreakers)
@@ -2512,6 +2532,7 @@ void Myst::observatoryUpdateMonth() {
_state.observatoryMonthSetting = month;
_state.observatoryMonthSlider = _observatoryMonthSlider->_pos.y;
_vm->_sound->playEffect(8500);
+ _vm->wait(20);
// Redraw digits
_vm->redrawArea(73);
@@ -2539,6 +2560,7 @@ void Myst::observatoryUpdateDay() {
_state.observatoryDaySetting = day;
_state.observatoryDaySlider = _observatoryDaySlider->_pos.y;
_vm->_sound->playEffect(8500);
+ _vm->wait(20);
// Redraw digits
_vm->redrawArea(75);
@@ -2567,6 +2589,7 @@ void Myst::observatoryUpdateYear() {
_state.observatoryYearSetting = year;
_state.observatoryYearSlider = _observatoryYearSlider->_pos.y;
_vm->_sound->playEffect(8500);
+ _vm->wait(20);
// Redraw digits
_vm->redrawArea(79);
@@ -2597,6 +2620,7 @@ void Myst::observatoryUpdateTime() {
_state.observatoryTimeSetting = time;
_state.observatoryTimeSlider = _observatoryTimeSlider->_pos.y;
_vm->_sound->playEffect(8500);
+ _vm->wait(20);
// Redraw digits
_vm->redrawArea(80);
diff --git a/engines/mohawk/myst_state.cpp b/engines/mohawk/myst_state.cpp
index 213a976413..20b8ec47ae 100644
--- a/engines/mohawk/myst_state.cpp
+++ b/engines/mohawk/myst_state.cpp
@@ -272,7 +272,12 @@ SaveStateDescriptor MystGameState::querySaveMetaInfos(int slot) {
desc.setSaveDate(metadata.saveYear, metadata.saveMonth, metadata.saveDay);
desc.setSaveTime(metadata.saveHour, metadata.saveMinute);
desc.setPlayTime(metadata.totalPlayTime);
- desc.setThumbnail(Graphics::loadThumbnail(*metadataFile));
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*metadataFile, thumbnail)) {
+ delete metadataFile;
+ return SaveStateDescriptor();
+ }
+ desc.setThumbnail(thumbnail);
delete metadataFile;
diff --git a/engines/mohawk/riven_saveload.cpp b/engines/mohawk/riven_saveload.cpp
index 7165166d8f..1d9ae211d9 100644
--- a/engines/mohawk/riven_saveload.cpp
+++ b/engines/mohawk/riven_saveload.cpp
@@ -148,7 +148,11 @@ SaveStateDescriptor RivenSaveLoad::querySaveMetaInfos(const int slot) {
return descriptor;
}
- descriptor.setThumbnail(Graphics::loadThumbnail(*thmbStream));
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*thmbStream, thumbnail)) {
+ return descriptor;
+ }
+ descriptor.setThumbnail(thumbnail);
delete thmbStream;
diff --git a/engines/mortevielle/saveload.cpp b/engines/mortevielle/saveload.cpp
index 3032c96690..078338a0b5 100644
--- a/engines/mortevielle/saveload.cpp
+++ b/engines/mortevielle/saveload.cpp
@@ -92,8 +92,10 @@ bool SavegameManager::loadSavegame(const Common::String &filename) {
if (!strncmp(&buffer[0], &SAVEGAME_ID[0], 4)) {
// Yes, it is, so skip over the savegame header
SavegameHeader header;
- readSavegameHeader(stream, header);
- delete header.thumbnail;
+ if (!readSavegameHeader(stream, header)) {
+ delete stream;
+ return false;
+ }
} else {
stream->seek(0);
}
@@ -208,9 +210,7 @@ void SavegameManager::writeSavegameHeader(Common::OutSaveFile *out, const Common
out->writeSint16LE(td.tm_min);
}
-bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
- header.thumbnail = NULL;
-
+WARN_UNUSED_RESULT bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) {
// Get the savegame version
header.version = in->readByte();
@@ -221,9 +221,9 @@ bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
@@ -263,7 +263,6 @@ SaveStateList SavegameManager::listSaves(const Common::String &target) {
validFlag = readSavegameHeader(in, header);
if (validFlag) {
- delete header.thumbnail;
saveDescription = header.saveName;
}
} else if (file->size() == 497) {
@@ -311,7 +310,10 @@ SaveStateDescriptor SavegameManager::querySaveMetaInfos(const Common::String &fi
} else {
// Get the savegame header information
SavegameHeader header;
- readSavegameHeader(f, header);
+ if (!readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
delete f;
// Create the return descriptor
diff --git a/engines/mortevielle/saveload.h b/engines/mortevielle/saveload.h
index a0de05b920..b401823938 100644
--- a/engines/mortevielle/saveload.h
+++ b/engines/mortevielle/saveload.h
@@ -65,7 +65,7 @@ public:
Common::Error saveGame(int slot);
void writeSavegameHeader(Common::OutSaveFile *out, const Common::String &saveName);
- static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
static SaveStateList listSaves(const Common::String &target);
static SaveStateDescriptor querySaveMetaInfos(const Common::String &fileName);
};
diff --git a/engines/neverhood/detection.cpp b/engines/neverhood/detection.cpp
index 46605bb2f7..920d149659 100644
--- a/engines/neverhood/detection.cpp
+++ b/engines/neverhood/detection.cpp
@@ -271,7 +271,7 @@ SaveStateList NeverhoodMetaEngine::listSaves(const char *target) const {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Neverhood::NeverhoodEngine::readSaveHeader(in, false, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
+ if (Neverhood::NeverhoodEngine::readSaveHeader(in, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
saveList.push_back(SaveStateDescriptor(slotNum, header.description));
}
delete in;
@@ -302,7 +302,7 @@ SaveStateDescriptor NeverhoodMetaEngine::querySaveMetaInfos(const char *target,
Neverhood::NeverhoodEngine::SaveHeader header;
Neverhood::NeverhoodEngine::kReadSaveHeaderError error;
- error = Neverhood::NeverhoodEngine::readSaveHeader(in, true, header);
+ error = Neverhood::NeverhoodEngine::readSaveHeader(in, header, false);
delete in;
if (error == Neverhood::NeverhoodEngine::kRSHENoError) {
diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp
index e3996a2507..b64f4dcdd2 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -291,7 +291,7 @@ void MenuModule::loadSavegameList() {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Neverhood::NeverhoodEngine::readSaveHeader(in, false, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
+ if (Neverhood::NeverhoodEngine::readSaveHeader(in, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
SavegameItem savegameItem;
savegameItem.slotNum = slotNum;
savegameItem.description = header.description;
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 4c5f9c3303..90055eeb9d 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -129,7 +129,7 @@ public:
bool loadgame(const char *filename);
const char *getSavegameFilename(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
- static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
+ WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true);
GameState& gameState() { return _gameState; }
GameModule *gameModule() { return _gameModule; }
diff --git a/engines/neverhood/saveload.cpp b/engines/neverhood/saveload.cpp
index 8fe6c9a155..d7e6f1ebfe 100644
--- a/engines/neverhood/saveload.cpp
+++ b/engines/neverhood/saveload.cpp
@@ -32,7 +32,7 @@ namespace Neverhood {
#define NEVERHOOD_SAVEGAME_VERSION 0
-NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+WARN_UNUSED_RESULT NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) {
header.version = in->readUint32LE();
if (header.version > NEVERHOOD_SAVEGAME_VERSION)
@@ -43,10 +43,8 @@ NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::Se
while (descriptionLen--)
header.description += (char)in->readByte();
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*in);
- } else {
- Graphics::skipThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ return kRSHEIoError;
}
// Not used yet, reserved for future usage
@@ -110,7 +108,7 @@ bool NeverhoodEngine::loadgame(const char *filename) {
SaveHeader header;
- kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
+ kReadSaveHeaderError errorCode = readSaveHeader(in, header);
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
diff --git a/engines/plumbers/plumbers.cpp b/engines/plumbers/plumbers.cpp
index 9904acb33a..5491f81c65 100644
--- a/engines/plumbers/plumbers.cpp
+++ b/engines/plumbers/plumbers.cpp
@@ -90,6 +90,7 @@ static const byte cursorPalette[] = {
Common::Error PlumbersGame::run() {
initGraphics(640, 480);
_console = new Console();
+ _image = new Image::BitmapDecoder();
CursorMan.replaceCursor(MOUSECURSOR_SCI, 11, 16, 0, 0, 0);
CursorMan.replaceCursorPalette(cursorPalette, 0, 3);
@@ -178,17 +179,11 @@ Common::Error PlumbersGame::run() {
void PlumbersGame::loadImage(const Common::String &dirname, const Common::String &filename) {
Common::String name = dirname + "/" + filename;
debugC(1, kDebugGeneral, "%s : %s", __FUNCTION__, name.c_str());
- Common::File *file = new Common::File();
- if (!file->open(name))
+ Common::File file;
+ if (!file.open(name))
error("unable to load image %s", name.c_str());
- if (_image)
- delete _image;
-
- _image = new Image::BitmapDecoder();
- _image->loadStream(*file);
- file->close();
- delete file;
+ _image->loadStream(file);
}
void PlumbersGame::drawScreen() {
@@ -362,7 +357,6 @@ void PlumbersGame::readTables(const Common::String &fileName) {
file.read(buf, kMaxName);
_bitmaps[i]._filename = Common::String(buf);
}
- file.close();
}
int PlumbersGame::getSceneNumb(int sNo) {
diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp
index ce80fe5cab..ef3128ae09 100644
--- a/engines/prince/detection.cpp
+++ b/engines/prince/detection.cpp
@@ -208,10 +208,6 @@ SaveStateList PrinceMetaEngine::listSaves(const char *target) const {
// Valid savegame
if (Prince::PrinceEngine::readSavegameHeader(file, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
}
} else {
// Must be an original format savegame
@@ -239,7 +235,7 @@ SaveStateDescriptor PrinceMetaEngine::querySaveMetaInfos(const char *target, int
f->read(buffer, kSavegameStrSize + 1);
bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) &&
- Prince::PrinceEngine::readSavegameHeader(f, header);
+ Prince::PrinceEngine::readSavegameHeader(f, header, false);
delete f;
if (!hasHeader) {
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index 32e37e0774..c264125895 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -290,7 +290,7 @@ public:
void playVideo(Common::String videoFilename);
- static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
Common::String generateSaveName(int slot);
void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp
index 14f6078910..8832a6d1d2 100644
--- a/engines/prince/saveload.cpp
+++ b/engines/prince/saveload.cpp
@@ -44,9 +44,7 @@ namespace Prince {
class InterpreterFlags;
class Interpreter;
-bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
- header.thumbnail = nullptr;
-
+WARN_UNUSED_RESULT bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) {
// Get the savegame version
header.version = in->readByte();
if (header.version > kSavegameVersion)
@@ -59,9 +57,9 @@ bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &he
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
@@ -416,10 +414,6 @@ bool PrinceEngine::loadGame(int slotNumber) {
delete readStream;
return false;
}
-
- // Delete the thumbnail
- saveHeader.thumbnail->free();
- delete saveHeader.thumbnail;
}
// Get in the savegame
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index 6fe4277c27..fcd78502d9 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -256,7 +256,11 @@ SaveStateDescriptor SagaMetaEngine::querySaveMetaInfos(const char *target, int s
}
if (version >= 6) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ delete in;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
uint32 saveDate = in->readUint32BE();
diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index e6b196c4cd..250d2914b7 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -2804,8 +2804,8 @@ void Interface::mapPanelDrawCrossHair() {
if (screen.contains(mapPosition)) {
_vm->_sprite->draw(_vm->_sprite->_mainSprites,
- _mapPanelCrossHairState? RID_ITE_SPR_CROSSHAIR : RID_ITE_SPR_CROSSHAIR + 1,
- mapPosition, 256);
+ _mapPanelCrossHairState ? RID_ITE_SPR_CROSSHAIR : RID_ITE_SPR_CROSSHAIR + 1,
+ mapPosition, 256);
}
}
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index aa7a63d224..bc7241269d 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -871,7 +871,14 @@ SaveStateDescriptor SciMetaEngine::querySaveMetaInfos(const char *target, int sl
descriptor.setDescription(meta.name);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ // invalid
+ delete in;
+
+ descriptor.setDescription("*Invalid*");
+ return descriptor;
+ }
descriptor.setThumbnail(thumbnail);
int day = (meta.saveDate >> 24) & 0xFF;
diff --git a/engines/scumm/he/moonbase/ai_main.cpp b/engines/scumm/he/moonbase/ai_main.cpp
index c391105658..c5c1f6a8e4 100644
--- a/engines/scumm/he/moonbase/ai_main.cpp
+++ b/engines/scumm/he/moonbase/ai_main.cpp
@@ -2811,9 +2811,9 @@ int AI::simulateBuildingLaunch(int x, int y, int power, int angle, int numSteps,
numSteps = 1;
if (!sXSpeed && !sYSpeed) {
- sZSpeed = (static_cast<int>(.70711 * power)) ;
- sXSpeed = (static_cast<int>(cos(degToRad(angle)) * sZSpeed)) ;
- sYSpeed = (static_cast<int>(sin(degToRad(angle)) * sZSpeed)) ;
+ sZSpeed = (static_cast<int>(.70711 * power));
+ sXSpeed = (static_cast<int>(cos(degToRad(angle)) * sZSpeed));
+ sYSpeed = (static_cast<int>(sin(degToRad(angle)) * sZSpeed));
sZSpeed *= SCALE_Z;
@@ -2959,9 +2959,9 @@ int AI::simulateWeaponLaunch(int x, int y, int power, int angle, int numSteps) {
if (!numSteps) numSteps = 1;
if (!sXSpeed && !sYSpeed) {
- sZSpeed = (static_cast<int>(.70711 * power)) ;
- sXSpeed = (static_cast<int>(cos(degToRad(angle)) * sZSpeed)) ;
- sYSpeed = (static_cast<int>(sin(degToRad(angle)) * sZSpeed)) ;
+ sZSpeed = (static_cast<int>(.70711 * power));
+ sXSpeed = (static_cast<int>(cos(degToRad(angle)) * sZSpeed));
+ sYSpeed = (static_cast<int>(sin(degToRad(angle)) * sZSpeed));
sZSpeed *= SCALE_Z;
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index d04b3bb5ad..84dd16efa6 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -706,7 +706,9 @@ bool ScummEngine::querySaveMetaInfos(const char *target, int slot, int heversion
if (hdr.ver > VER(52)) {
if (Graphics::checkThumbnailHeader(*in)) {
- thumbnail = Graphics::loadThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ return false;
+ }
}
if (hdr.ver > VER(57)) {
diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp
index 9184fd8e88..a0598dcb46 100644
--- a/engines/sherlock/detection.cpp
+++ b/engines/sherlock/detection.cpp
@@ -233,7 +233,10 @@ SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, i
if (f) {
Sherlock::SherlockSavegameHeader header;
- Sherlock::SaveManager::readSavegameHeader(f, header);
+ if (!Sherlock::SaveManager::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
delete f;
// Create the return descriptor
diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp
index c53e537bb8..112655648a 100644
--- a/engines/sherlock/image_file.cpp
+++ b/engines/sherlock/image_file.cpp
@@ -703,7 +703,7 @@ void ImageFile3DO::load3DOCelRoomData(Common::SeekableReadStream &stream) {
error("load3DOCelRoomData: expected cel data, not enough bytes");
// read data into memory
- byte *celDataPtr = new byte[celDataSize];
+ byte *celDataPtr = new byte[celDataSize];
stream.read(celDataPtr, celDataSize);
streamLeft -= celDataSize;
@@ -936,15 +936,15 @@ void ImageFile3DO::loadFont(Common::SeekableReadStream &stream) {
stream.read(bitsTablePtr, bitsTableSize);
// Now extract all characters
- uint16 curChar = 0;
- const byte *curBitsLinePtr = bitsTablePtr;
- const byte *curBitsPtr = NULL;
- byte curBitsLeft = 0;
- uint32 curCharHeightLeft = 0;
- uint32 curCharWidthLeft = 0;
- byte curBits = 0;
- byte curBitsReversed = 0;
- byte curPosX = 0;
+ uint16 curChar = 0;
+ const byte *curBitsLinePtr = bitsTablePtr;
+ const byte *curBitsPtr = NULL;
+ byte curBitsLeft = 0;
+ uint32 curCharHeightLeft = 0;
+ uint32 curCharWidthLeft = 0;
+ byte curBits = 0;
+ byte curBitsReversed = 0;
+ byte curPosX = 0;
assert(bitsTableSize >= (header_maxChar * header_fontHeight * header_bytesPerLine)); // Security
diff --git a/engines/sherlock/music.cpp b/engines/sherlock/music.cpp
index cef7157034..20b811ea98 100644
--- a/engines/sherlock/music.cpp
+++ b/engines/sherlock/music.cpp
@@ -182,8 +182,8 @@ bool MidiParser_SH::loadMusic(byte *musData, uint32 musDataSize) {
_musData = musData;
_musDataSize = musDataSize;
- byte *headerPtr = _musData + 12; // skip over the already checked SPACE header
- byte *pos = headerPtr;
+ byte *headerPtr = _musData + 12; // skip over the already checked SPACE header
+ byte *pos = headerPtr;
uint16 headerSize = READ_LE_UINT16(headerPtr);
assert(headerSize == 0x7F); // Security check
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index 25ccddedbb..6f1148e956 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -470,7 +470,7 @@ struct SceneImage {
int _filesize; // File size
SceneImage();
-} ;
+};
} // End of namespace Sherlock
diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp
index 9d203a6a27..ca27f57a97 100644
--- a/engines/sherlock/saveload.cpp
+++ b/engines/sherlock/saveload.cpp
@@ -103,13 +103,9 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- if (!readSavegameHeader(in, header))
- continue;
+ if (readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- header._thumbnail->free();
- delete header._thumbnail;
delete in;
}
}
@@ -119,9 +115,8 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) {
return saveList;
}
-bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) {
+WARN_UNUSED_RESULT bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -138,9 +133,9 @@ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHea
while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
@@ -212,11 +207,6 @@ void SaveManager::loadGame(int slot) {
if (!readSavegameHeader(saveFile, header))
error("Invalid savegame");
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
// Synchronize the savegame data
Serializer s(saveFile, nullptr);
s.setVersion(header._version);
diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h
index 59b0b26d6e..6348b0f668 100644
--- a/engines/sherlock/saveload.h
+++ b/engines/sherlock/saveload.h
@@ -105,7 +105,7 @@ public:
/**
* Read in the header information for a savegame
*/
- static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header, bool skipThumbnail = true);
/**
* Return the index of the button the mouse is over, if any
diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp
index 2aa6ae8902..fbe025c0b7 100644
--- a/engines/sherlock/scalpel/scalpel.cpp
+++ b/engines/sherlock/scalpel/scalpel.cpp
@@ -258,8 +258,8 @@ void ScalpelEngine::setupGraphics() {
// First try for a 640x400 mode
g_system->beginGFXTransaction();
- initCommonGFX();
- g_system->initSize(640, 400, &pixelFormatRGB565);
+ initCommonGFX();
+ g_system->initSize(640, 400, &pixelFormatRGB565);
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
if (gfxError == OSystem::kTransactionSuccess) {
diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp
index fc3c2e6574..458cc1a9c2 100644
--- a/engines/sherlock/tattoo/tattoo_people.cpp
+++ b/engines/sherlock/tattoo/tattoo_people.cpp
@@ -39,7 +39,7 @@ struct AdjustWalk {
int _xAdjust;
int _flipXAdjust;
int _yAdjust;
-} ;
+};
static const AdjustWalk ADJUST_WALKS[NUM_ADJUSTED_WALKS] = {
{ "TUPRIGHT", -7, -19, 6 },
diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp
index dba5f01694..8195fc53f9 100644
--- a/engines/sludge/builtin.cpp
+++ b/engines/sludge/builtin.cpp
@@ -60,10 +60,8 @@ Variable *launchResult = NULL;
extern int lastFramesPerSecond, thumbWidth, thumbHeight;
extern bool allowAnyFilename;
-extern bool captureAllKeys;
extern VariableStack *noStack;
extern StatusStuff *nowStatus;
-extern ScreenRegion *overRegion;
extern int numBIFNames, numUserFunc;
extern Common::String *allUserFunc;
@@ -197,7 +195,7 @@ builtIn(howFrozen) {
builtIn(setCursor) {
UNUSEDALL
- PersonaAnimation *aa = getAnimationFromVar(fun->stack->thisVar);
+ PersonaAnimation *aa = getAnimationFromVar(fun->stack->thisVar);
g_sludge->_cursorMan->pickAnimCursor(aa);
trimStack(fun->stack);
return BR_CONTINUE;
@@ -402,7 +400,7 @@ builtIn(pasteImage) {
if (!getValueType(x, SVT_INT, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- PersonaAnimation *pp = getAnimationFromVar(fun->stack->thisVar);
+ PersonaAnimation *pp = getAnimationFromVar(fun->stack->thisVar);
trimStack(fun->stack);
if (pp == NULL)
return BR_CONTINUE;
@@ -857,7 +855,7 @@ builtIn(anim) {
}
// First store the frame numbers and take 'em off the stack
- PersonaAnimation *ba = createPersonaAnim(numParams - 1, fun->stack);
+ PersonaAnimation *ba = new PersonaAnimation(numParams - 1, fun->stack);
// Only remaining paramter is the file number
int fileNumber;
@@ -869,7 +867,7 @@ builtIn(anim) {
LoadedSpriteBank *sprBanky = g_sludge->_gfxMan->loadBankForAnim(fileNumber);
if (!sprBanky)
return BR_ERROR; // File not found, fatal done already
- setBankFile(ba, sprBanky);
+ ba->theSprites = sprBanky;
// Return value
newAnimationVariable(fun->reg, ba);
@@ -1312,9 +1310,9 @@ builtIn(skipSpeech) {
builtIn(getOverObject) {
UNUSEDALL
- if (overRegion)
+ if (g_sludge->_regionMan->getOverRegion())
// Return value
- setVariable(fun->reg, SVT_OBJTYPE, overRegion->thisType->objectNum);
+ setVariable(fun->reg, SVT_OBJTYPE, g_sludge->_regionMan->getOverRegion()->thisType->objectNum);
else
// Return value
setVariable(fun->reg, SVT_INT, 0);
@@ -1342,11 +1340,11 @@ builtIn(getObjectX) {
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *pers = findPerson(objectNumber);
+ OnScreenPerson *pers = g_sludge->_peopleMan->findPerson(objectNumber);
if (pers) {
setVariable(fun->reg, SVT_INT, pers->x);
} else {
- ScreenRegion *la = getRegionForObject(objectNumber);
+ ScreenRegion *la = g_sludge->_regionMan->getRegionForObject(objectNumber);
if (la) {
setVariable(fun->reg, SVT_INT, la->sX);
} else {
@@ -1363,11 +1361,11 @@ builtIn(getObjectY) {
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *pers = findPerson(objectNumber);
+ OnScreenPerson *pers = g_sludge->_peopleMan->findPerson(objectNumber);
if (pers) {
setVariable(fun->reg, SVT_INT, pers->y);
} else {
- ScreenRegion *la = getRegionForObject(objectNumber);
+ ScreenRegion *la = g_sludge->_regionMan->getRegionForObject(objectNumber);
if (la) {
setVariable(fun->reg, SVT_INT, la->sY);
} else {
@@ -1404,7 +1402,7 @@ builtIn(addScreenRegion) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- if (addScreenRegion(x1, y1, x2, y2, sX, sY, di, objectNumber))
+ if (g_sludge->_regionMan->addScreenRegion(x1, y1, x2, y2, sX, sY, di, objectNumber))
return BR_CONTINUE;
return BR_ERROR;
@@ -1416,19 +1414,19 @@ builtIn(removeScreenRegion) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- removeScreenRegion(objectNumber);
+ g_sludge->_regionMan->removeScreenRegion(objectNumber);
return BR_CONTINUE;
}
builtIn(showBoxes) {
UNUSEDALL
- showBoxes();
+ g_sludge->_regionMan->showBoxes();
return BR_CONTINUE;
}
builtIn(removeAllScreenRegions) {
UNUSEDALL
- killAllRegions();
+ g_sludge->_regionMan->kill();
return BR_CONTINUE;
}
@@ -1451,7 +1449,7 @@ builtIn(addCharacter) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- if (addPerson(x, y, objectNumber, p))
+ if (g_sludge->_peopleMan->addPerson(x, y, objectNumber, p))
return BR_CONTINUE;
return BR_ERROR;
}
@@ -1462,7 +1460,7 @@ builtIn(hideCharacter) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setShown(false, objectNumber);
+ g_sludge->_peopleMan->setShown(false, objectNumber);
return BR_CONTINUE;
}
@@ -1472,14 +1470,14 @@ builtIn(showCharacter) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setShown(true, objectNumber);
+ g_sludge->_peopleMan->setShown(true, objectNumber);
return BR_CONTINUE;
}
builtIn(removeAllCharacters) {
UNUSEDALL
killSpeechTimers();
- killMostPeople();
+ g_sludge->_peopleMan->killMostPeople();
return BR_CONTINUE;
}
@@ -1492,7 +1490,7 @@ builtIn(setCharacterDrawMode) {
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setDrawMode(di, obj);
+ g_sludge->_peopleMan->setDrawMode(di, obj);
return BR_CONTINUE;
}
builtIn(setCharacterTransparency) {
@@ -1504,7 +1502,7 @@ builtIn(setCharacterTransparency) {
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setPersonTransparency(obj, x);
+ g_sludge->_peopleMan->setPersonTransparency(obj, x);
return BR_CONTINUE;
}
builtIn(setCharacterColourise) {
@@ -1525,7 +1523,7 @@ builtIn(setCharacterColourise) {
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setPersonColourise(obj, r, g, b, mix);
+ g_sludge->_peopleMan->setPersonColourise(obj, r, g, b, mix);
return BR_CONTINUE;
}
@@ -1538,7 +1536,7 @@ builtIn(setScale) {
if (!getValueType(val1, SVT_INT, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setScale((int16)val1, (int16)val2);
+ g_sludge->_peopleMan->setScale((int16)val1, (int16)val2);
return BR_CONTINUE;
}
@@ -1550,7 +1548,7 @@ builtIn(stopCharacter) {
trimStack(fun->stack);
// Return value
- setVariable(fun->reg, SVT_INT, stopPerson(obj));
+ setVariable(fun->reg, SVT_INT, g_sludge->_peopleMan->stopPerson(obj));
return BR_CONTINUE;
}
@@ -1561,7 +1559,7 @@ builtIn(pasteCharacter) {
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *thisPerson = findPerson(obj);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(obj);
if (thisPerson) {
PersonaAnimation *myAnim;
myAnim = thisPerson->myAnim;
@@ -1583,15 +1581,15 @@ builtIn(pasteCharacter) {
builtIn(animate) {
UNUSEDALL
int obj;
- PersonaAnimation *pp = getAnimationFromVar(fun->stack->thisVar);
+ PersonaAnimation *pp = getAnimationFromVar(fun->stack->thisVar);
if (pp == NULL)
return BR_ERROR;
trimStack(fun->stack);
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- animatePerson(obj, pp);
- setVariable(fun->reg, SVT_INT, timeForAnim(pp));
+ g_sludge->_peopleMan->animatePerson(obj, pp);
+ setVariable(fun->reg, SVT_INT, pp->getTotalTime());
return BR_CONTINUE;
}
@@ -1605,7 +1603,7 @@ builtIn(setCostume) {
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- animatePerson(obj, pp);
+ g_sludge->_peopleMan->animatePerson(obj, pp);
return BR_CONTINUE;
}
@@ -1618,7 +1616,7 @@ builtIn(floatCharacter) {
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setVariable(fun->reg, SVT_INT, floatCharacter(di, obj));
+ setVariable(fun->reg, SVT_INT, g_sludge->_peopleMan->floatCharacter(di, obj));
return BR_CONTINUE;
}
@@ -1631,7 +1629,7 @@ builtIn(setCharacterWalkSpeed) {
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setVariable(fun->reg, SVT_INT, setCharacterWalkSpeed(di, obj));
+ setVariable(fun->reg, SVT_INT, g_sludge->_peopleMan->setCharacterWalkSpeed(di, obj));
return BR_CONTINUE;
}
@@ -1644,7 +1642,7 @@ builtIn(turnCharacter) {
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setVariable(fun->reg, SVT_INT, turnPersonToFace(obj, di));
+ setVariable(fun->reg, SVT_INT, g_sludge->_peopleMan->turnPersonToFace(obj, di));
return BR_CONTINUE;
}
@@ -1657,7 +1655,7 @@ builtIn(setCharacterExtra) {
if (!getValueType(obj, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setVariable(fun->reg, SVT_INT, setPersonExtra(obj, di));
+ setVariable(fun->reg, SVT_INT, g_sludge->_peopleMan->setPersonExtra(obj, di));
return BR_CONTINUE;
}
@@ -1667,7 +1665,7 @@ builtIn(removeCharacter) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- removeOneCharacter(objectNumber);
+ g_sludge->_peopleMan->removeOneCharacter(objectNumber);
return BR_CONTINUE;
}
@@ -1687,12 +1685,12 @@ static BuiltReturn moveChr(int numParams, LoadedFunction *fun, bool force, bool
trimStack(fun->stack);
if (force) {
- if (forceWalkingPerson(x, y, objectNumber, fun, -1))
+ if (g_sludge->_peopleMan->forceWalkingPerson(x, y, objectNumber, fun, -1))
return BR_PAUSE;
} else if (immediate) {
- jumpPerson(x, y, objectNumber);
+ g_sludge->_peopleMan->jumpPerson(x, y, objectNumber);
} else {
- if (makeWalkingPerson(x, y, objectNumber, fun, -1))
+ if (g_sludge->_peopleMan->makeWalkingPerson(x, y, objectNumber, fun, -1))
return BR_PAUSE;
}
return BR_CONTINUE;
@@ -1708,17 +1706,17 @@ static BuiltReturn moveChr(int numParams, LoadedFunction *fun, bool force, bool
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- reggie = getRegionForObject(toObj);
+ reggie = g_sludge->_regionMan->getRegionForObject(toObj);
if (reggie == NULL)
return BR_CONTINUE;
if (force) {
- if (forceWalkingPerson(reggie->sX, reggie->sY, objectNumber, fun, reggie->di))
+ if (g_sludge->_peopleMan->forceWalkingPerson(reggie->sX, reggie->sY, objectNumber, fun, reggie->di))
return BR_PAUSE;
} else if (immediate) {
- jumpPerson(reggie->sX, reggie->sY, objectNumber);
+ g_sludge->_peopleMan->jumpPerson(reggie->sX, reggie->sY, objectNumber);
} else {
- if (makeWalkingPerson(reggie->sX, reggie->sY, objectNumber, fun, reggie->di))
+ if (g_sludge->_peopleMan->makeWalkingPerson(reggie->sX, reggie->sY, objectNumber, fun, reggie->di))
return BR_PAUSE;
}
return BR_CONTINUE;
@@ -1945,7 +1943,7 @@ builtIn(isScreenRegion) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- setVariable(fun->reg, SVT_INT, getRegionForObject(objectNumber) != NULL);
+ setVariable(fun->reg, SVT_INT, g_sludge->_regionMan->getRegionForObject(objectNumber) != NULL);
return BR_CONTINUE;
}
@@ -1991,9 +1989,10 @@ builtIn(transitionLevel) {
builtIn(captureAllKeys) {
UNUSEDALL
- captureAllKeys = getBoolean(fun->stack->thisVar);
+ // This built-in function doesn't have any effect any more, we capture all keys by default
+ bool captureAllKeysDeprecated = getBoolean(fun->stack->thisVar);
trimStack(fun->stack);
- setVariable(fun->reg, SVT_INT, captureAllKeys);
+ setVariable(fun->reg, SVT_INT, captureAllKeysDeprecated);
return BR_CONTINUE;
}
@@ -2007,7 +2006,7 @@ builtIn(spinCharacter) {
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *thisPerson = findPerson(objectNumber);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(objectNumber);
if (thisPerson) {
thisPerson->wantAngle = number;
thisPerson->spinning = true;
@@ -2026,7 +2025,7 @@ builtIn(getCharacterDirection) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *thisPerson = findPerson(objectNumber);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(objectNumber);
if (thisPerson) {
setVariable(fun->reg, SVT_INT, thisPerson->direction);
} else {
@@ -2041,7 +2040,7 @@ builtIn(isCharacter) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *thisPerson = findPerson(objectNumber);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(objectNumber);
setVariable(fun->reg, SVT_INT, thisPerson != NULL);
return BR_CONTINUE;
}
@@ -2052,7 +2051,7 @@ builtIn(normalCharacter) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *thisPerson = findPerson(objectNumber);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(objectNumber);
if (thisPerson) {
thisPerson->myAnim = thisPerson->myPersona->animation[thisPerson->direction];
setVariable(fun->reg, SVT_INT, 1);
@@ -2068,7 +2067,7 @@ builtIn(isMoving) {
if (!getValueType(objectNumber, SVT_OBJTYPE, fun->stack->thisVar))
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *thisPerson = findPerson(objectNumber);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(objectNumber);
if (thisPerson) {
setVariable(fun->reg, SVT_INT, thisPerson->walking);
} else {
@@ -2173,7 +2172,7 @@ builtIn(setCharacterSpinSpeed) {
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *thisPerson = findPerson(who);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(who);
if (thisPerson) {
thisPerson->spinSpeed = speed;
@@ -2194,7 +2193,7 @@ builtIn(setCharacterAngleOffset) {
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *thisPerson = findPerson(who);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(who);
if (thisPerson) {
thisPerson->angleOffset = angle;
@@ -2390,7 +2389,7 @@ builtIn(getCharacterScale) {
return BR_ERROR;
trimStack(fun->stack);
- OnScreenPerson *pers = findPerson(objectNumber);
+ OnScreenPerson *pers = g_sludge->_peopleMan->findPerson(objectNumber);
if (pers) {
setVariable(fun->reg, SVT_INT, pers->scale * 100);
} else {
diff --git a/engines/sludge/cursors.cpp b/engines/sludge/cursors.cpp
index 0c7745e9ff..0ec46e2f17 100644
--- a/engines/sludge/cursors.cpp
+++ b/engines/sludge/cursors.cpp
@@ -44,18 +44,24 @@ CursorManager::~CursorManager() {
}
void CursorManager::init() {
- _mouseCursorAnim = makeNullAnim();
+ _mouseCursorAnim = new PersonaAnimation();
_mouseCursorFrameNum = 0;
_mouseCursorCountUp = 0;
}
void CursorManager::kill() {
- deleteAnim(_mouseCursorAnim);
+ if (_mouseCursorAnim) {
+ delete _mouseCursorAnim;
+ _mouseCursorAnim = nullptr;
+ }
_mouseCursorAnim = nullptr;
}
void CursorManager::pickAnimCursor(PersonaAnimation *pp) {
- deleteAnim(_mouseCursorAnim);
+ if (_mouseCursorAnim) {
+ delete _mouseCursorAnim;
+ _mouseCursorAnim = nullptr;
+ }
_mouseCursorAnim = pp;
_mouseCursorFrameNum = 0;
_mouseCursorCountUp = 0;
@@ -107,18 +113,21 @@ void CursorManager::pasteCursor(int x, int y, PersonaAnimation *c) {
void CursorManager::freeze(FrozenStuffStruct *frozenStuff) {
frozenStuff->mouseCursorAnim = _mouseCursorAnim;
frozenStuff->mouseCursorFrameNum = _mouseCursorFrameNum;
- _mouseCursorAnim = makeNullAnim();
+ _mouseCursorAnim = new PersonaAnimation();
_mouseCursorFrameNum = 0;
}
void CursorManager::resotre(FrozenStuffStruct *frozenStuff) {
- deleteAnim(_mouseCursorAnim);
+ if (_mouseCursorAnim) {
+ delete _mouseCursorAnim;
+ _mouseCursorAnim = nullptr;
+ }
_mouseCursorAnim = frozenStuff->mouseCursorAnim;
_mouseCursorFrameNum = frozenStuff->mouseCursorFrameNum;
}
void CursorManager::saveCursor(Common::WriteStream *stream) {
- saveAnim(_mouseCursorAnim, stream);
+ _mouseCursorAnim->save(stream);
stream->writeUint16BE(_mouseCursorFrameNum);
}
@@ -126,7 +135,7 @@ bool CursorManager::loadCursor(Common::SeekableReadStream *stream) {
_mouseCursorAnim = new PersonaAnimation;
if (!checkNew(_mouseCursorAnim))
return false;
- if (!loadAnim(_mouseCursorAnim, stream))
+ if (!_mouseCursorAnim->load(stream))
return false;
_mouseCursorFrameNum = stream->readUint16BE();
return true;
diff --git a/engines/sludge/cursors.h b/engines/sludge/cursors.h
index 4229900a94..f3c71c2560 100644
--- a/engines/sludge/cursors.h
+++ b/engines/sludge/cursors.h
@@ -53,7 +53,7 @@ public:
private:
SludgeEngine *_vm;
- PersonaAnimation *_mouseCursorAnim;
+ PersonaAnimation *_mouseCursorAnim;
int _mouseCursorFrameNum;
int _mouseCursorCountUp;
};
diff --git a/engines/sludge/event.cpp b/engines/sludge/event.cpp
index d5c453bdc1..b553702710 100644
--- a/engines/sludge/event.cpp
+++ b/engines/sludge/event.cpp
@@ -36,8 +36,6 @@ namespace Sludge {
extern Variable *launchResult;
extern VariableStack *noStack;
-extern ScreenRegion *overRegion;
-extern ScreenRegion *lastRegion;
EventManager::EventManager(SludgeEngine *vm) {
_vm = vm;
@@ -152,14 +150,14 @@ void EventManager::checkInput() {
bool EventManager::handleInput() {
static int l = 0;
- if (!g_sludge->launchMe.empty()) {
+ if (!_vm->launchMe.empty()) {
if (l) {
// Still paused because of spawned thingy...
} else {
l = 1;
setVariable(*launchResult, SVT_INT, 0/*launch(launchMe) > 31*/); //TODO:false value
- g_sludge->launchMe.clear();
+ _vm->launchMe.clear();
launchResult = nullptr;
}
return true;
@@ -167,8 +165,8 @@ bool EventManager::handleInput() {
l = 0;
}
- if (!overRegion)
- getOverRegion();
+ if (!_vm->_regionMan->getOverRegion())
+ _vm->_regionMan->updateOverRegion();
if (_input.justMoved) {
if (_currentEvents->func[kMoveMouse]) {
@@ -178,12 +176,13 @@ bool EventManager::handleInput() {
}
_input.justMoved = false;
- if (lastRegion != overRegion && _currentEvents->func[kFocus]) {
+ if (_vm-> _regionMan->isRegionChanged()&& _currentEvents->func[kFocus]) {
VariableStack *tempStack = new VariableStack;
if (!checkNew(tempStack))
return false;
initVarNew(tempStack->thisVar);
+ ScreenRegion *overRegion = _vm->_regionMan->getOverRegion();
if (overRegion) {
setVariable(tempStack->thisVar, SVT_OBJTYPE, overRegion->thisType->objectNum);
} else {
@@ -333,7 +332,7 @@ bool EventManager::handleInput() {
_input.rightRelease = false;
_input.leftRelease = false;
_input.keyPressed = 0;
- lastRegion = overRegion;
+ _vm->_regionMan->updateLastRegion();
return true;
}
diff --git a/engines/sludge/event.h b/engines/sludge/event.h
index 015e9ea1cb..c07f7b87ad 100644
--- a/engines/sludge/event.h
+++ b/engines/sludge/event.h
@@ -69,7 +69,7 @@ public:
int &mouseY() { return _input.mouseY; }
// Events
- void setEventFunction(EventFunctions event, int funcNum) { _currentEvents->func[event] = funcNum; } ;
+ void setEventFunction(EventFunctions event, int funcNum) { _currentEvents->func[event] = funcNum; };
void loadHandlers(Common::SeekableReadStream *stream);
void saveHandlers(Common::WriteStream *stream);
bool freeze(FrozenStuffStruct *frozenStuff);
diff --git a/engines/sludge/freeze.cpp b/engines/sludge/freeze.cpp
index e90f2700d8..9f8c85e828 100644
--- a/engines/sludge/freeze.cpp
+++ b/engines/sludge/freeze.cpp
@@ -41,10 +41,6 @@
namespace Sludge {
-extern OnScreenPerson *allPeople;
-extern ScreenRegion *allScreenRegions;
-extern ScreenRegion *overRegion;
-
void GraphicsManager::freezeGraphics() {
int w = _winWidth;
@@ -87,18 +83,14 @@ bool GraphicsManager::freeze() {
_backdropSurface.copyFrom(_freezeSurface);
_backdropExists = true;
- newFreezer->allPeople = allPeople;
- allPeople = NULL;
+ _vm->_peopleMan->freeze(newFreezer);
- StatusStuff *newStatusStuff = new StatusStuff ;
+ StatusStuff *newStatusStuff = new StatusStuff;
if (!checkNew(newStatusStuff))
return false;
newFreezer->frozenStatus = copyStatusBarStuff(newStatusStuff);
- newFreezer->allScreenRegions = allScreenRegions;
- allScreenRegions = NULL;
- overRegion = NULL;
-
+ _vm->_regionMan->freeze(newFreezer);
_vm->_cursorMan->freeze(newFreezer);
_vm->_speechMan->freeze(newFreezer);
_vm->_evtMan->freeze(newFreezer);
@@ -136,11 +128,8 @@ void GraphicsManager::unfreeze(bool killImage) {
_vm->_evtMan->mouseX() = (int)(_vm->_evtMan->mouseX() / _cameraZoom);
_vm->_evtMan->mouseY() = (int)(_vm->_evtMan->mouseY() / _cameraZoom);
- killAllPeople();
- allPeople = _frozenStuff->allPeople;
-
- killAllRegions();
- allScreenRegions = _frozenStuff->allScreenRegions;
+ g_sludge->_peopleMan->resotre(_frozenStuff);
+ g_sludge->_regionMan->resotre(_frozenStuff);
killLightMap();
@@ -171,7 +160,6 @@ void GraphicsManager::unfreeze(bool killImage) {
_vm->_speechMan->restore(_frozenStuff);
_frozenStuff = _frozenStuff->next;
- overRegion = NULL;
// free current frozen screen struct
if (killMe->backdropSurface.getPixels())
diff --git a/engines/sludge/freeze.h b/engines/sludge/freeze.h
index 830c2d8a72..6dd77db17e 100644
--- a/engines/sludge/freeze.h
+++ b/engines/sludge/freeze.h
@@ -30,14 +30,17 @@ struct OnScreenPerson;
struct PersonaAnimation;
struct ScreenRegion;
struct SpeechStruct;
-struct StatusStuff ;
+struct StatusStuff;
struct EventHandlers;
+struct ScreenRegion;
+
+typedef Common::List<ScreenRegion *> ScreenRegionList;
class Parallax;
struct FrozenStuffStruct {
OnScreenPerson *allPeople;
- ScreenRegion *allScreenRegions;
+ ScreenRegionList *allScreenRegions;
Graphics::Surface backdropSurface;
Graphics::Surface lightMapSurface;
Graphics::Surface *zBufferSprites;
diff --git a/engines/sludge/loadsave.cpp b/engines/sludge/loadsave.cpp
index 4cabbc79da..017be432ab 100644
--- a/engines/sludge/loadsave.cpp
+++ b/engines/sludge/loadsave.cpp
@@ -62,7 +62,6 @@ extern Floor *currentFloor; // In floor.cpp
extern FILETIME fileTime; // In sludger.cpp
extern byte brightnessLevel; // " " "
extern byte fadeMode; // In transition.cpp
-extern bool captureAllKeys;
extern bool allowAnyFilename;
extern uint16 saveEncoding; // in savedata.cpp
@@ -215,11 +214,11 @@ bool saveVariable(Variable *from, Common::WriteStream *stream) {
return saveStackRef(from->varData.theStack, stream);
case SVT_COSTUME:
- saveCostume(from->varData.costumeHandler, stream);
+ from->varData.costumeHandler->save(stream);
return false;
case SVT_ANIM:
- saveAnim(from->varData.animHandler, stream);
+ from->varData.animHandler->save(stream);
return false;
case SVT_NULL:
@@ -254,14 +253,14 @@ bool loadVariable(Variable *to, Common::SeekableReadStream *stream) {
to->varData.costumeHandler = new Persona;
if (!checkNew(to->varData.costumeHandler))
return false;
- loadCostume(to->varData.costumeHandler, stream);
+ to->varData.costumeHandler->load(stream);
return true;
case SVT_ANIM:
- to->varData.animHandler = new PersonaAnimation ;
+ to->varData.animHandler = new PersonaAnimation;
if (!checkNew(to->varData.animHandler))
return false;
- loadAnim(to->varData.animHandler, stream);
+ to->varData.animHandler->load(stream);
return true;
default:
@@ -359,7 +358,7 @@ bool saveGame(const Common::String &fname) {
// DON'T ADD ANYTHING NEW BEFORE THIS POINT!
fp->writeByte(allowAnyFilename);
- fp->writeByte(captureAllKeys);
+ fp->writeByte(false); // deprecated captureAllKeys
fp->writeByte(true);
g_sludge->_txtMan->saveFont(fp);
@@ -375,7 +374,7 @@ bool saveGame(const Common::String &fname) {
g_sludge->_evtMan->saveHandlers(fp);
// Save regions
- saveRegions(fp);
+ g_sludge->_regionMan->saveRegions(fp);
g_sludge->_cursorMan->saveCursor(fp);
@@ -398,7 +397,7 @@ bool saveGame(const Common::String &fname) {
saveVariable(&globalVars[a], fp);
}
- savePeople(fp);
+ g_sludge->_peopleMan->savePeople(fp);
if (currentFloor->numPolygons) {
fp->writeByte(1);
@@ -498,13 +497,12 @@ bool loadGame(const Common::String &fname) {
if (ssgVersion >= VERSION(1, 4)) {
allowAnyFilename = fp->readByte();
}
- captureAllKeys = fp->readByte();
- fp->readByte(); // updateDisplay (part of movie playing)
+ fp->readByte(); // deprecated captureAllKeys
+ fp->readByte(); // updateDisplay (part of movie playing)
g_sludge->_txtMan->loadFont(ssgVersion, fp);
- killAllPeople();
- killAllRegions();
+ g_sludge->_regionMan->kill();
int camerX = fp->readUint16BE();
int camerY = fp->readUint16BE();
@@ -519,7 +517,7 @@ bool loadGame(const Common::String &fname) {
g_sludge->_gfxMan->loadHSI(fp, 0, 0, true);
g_sludge->_evtMan->loadHandlers(fp);
- loadRegions(fp);
+ g_sludge->_regionMan->loadRegions(fp);
if (!g_sludge->_cursorMan->loadCursor(fp)) {
return false;
@@ -541,7 +539,7 @@ bool loadGame(const Common::String &fname) {
loadVariable(&globalVars[a], fp);
}
- loadPeople(fp);
+ g_sludge->_peopleMan->loadPeople(fp);
if (fp->readByte()) {
if (!setFloor(fp->readUint16BE()))
diff --git a/engines/sludge/main_loop.cpp b/engines/sludge/main_loop.cpp
index 905d91d9c2..eac8610cc7 100644
--- a/engines/sludge/main_loop.cpp
+++ b/engines/sludge/main_loop.cpp
@@ -63,7 +63,7 @@ int main_loop(Common::String filename) {
while (!g_sludge->_evtMan->quit()) {
g_sludge->_evtMan->checkInput();
- walkAllPeople();
+ g_sludge->_peopleMan->walkAllPeople();
if (g_sludge->_evtMan->handleInput()) {
runSludge();
}
diff --git a/engines/sludge/people.cpp b/engines/sludge/people.cpp
index 4aec5fa8b7..625f5b7bcb 100644
--- a/engines/sludge/people.cpp
+++ b/engines/sludge/people.cpp
@@ -47,39 +47,35 @@
namespace Sludge {
extern VariableStack *noStack;
-
extern int ssgVersion;
-
-ScreenRegion personRegion;
-extern ScreenRegion *lastRegion;
extern Floor *currentFloor;
-OnScreenPerson *allPeople = NULL;
-int16 scaleHorizon = 75;
-int16 scaleDivide = 150;
-extern ScreenRegion *allScreenRegions;
-
-void setFrames(OnScreenPerson &m, int a) {
- m.myAnim = m.myPersona->animation[(a * m.myPersona->numDirections) + m.direction];
+PersonaAnimation::PersonaAnimation() {
+ theSprites = nullptr;
+ numFrames = 0;
+ frames = nullptr;
}
-PersonaAnimation *createPersonaAnim(int num, VariableStack *&stacky) {
- PersonaAnimation *newP = new PersonaAnimation ;
- checkNew(newP);
-
- newP->numFrames = num;
- newP->frames = new AnimFrame [num];
- checkNew(newP->frames);
+PersonaAnimation::~PersonaAnimation() {
+ if (numFrames) {
+ delete[] frames;
+ frames = nullptr;
+ }
+}
+PersonaAnimation::PersonaAnimation(int num, VariableStack *&stacky) {
+ theSprites = nullptr;
+ numFrames = num;
+ frames = new AnimFrame[num];
int a = num, frameNum, howMany;
while (a) {
a--;
- newP->frames[a].noise = 0;
+ frames[a].noise = 0;
if (stacky->thisVar.varType == SVT_FILE) {
- newP->frames[a].noise = stacky->thisVar.varData.intValue;
+ frames[a].noise = stacky->thisVar.varData.intValue;
} else if (stacky->thisVar.varType == SVT_FUNC) {
- newP->frames[a].noise = -stacky->thisVar.varData.intValue;
+ frames[a].noise = -stacky->thisVar.varData.intValue;
} else if (stacky->thisVar.varType == SVT_STACK) {
getValueType(frameNum, SVT_INT, stacky->thisVar.varData.theStack->first->thisVar);
getValueType(howMany, SVT_INT, stacky->thisVar.varData.theStack->first->next->thisVar);
@@ -88,67 +84,135 @@ PersonaAnimation *createPersonaAnim(int num, VariableStack *&stacky) {
howMany = 1;
}
trimStack(stacky);
- newP->frames[a].frameNum = frameNum;
- newP->frames[a].howMany = howMany;
+ frames[a].frameNum = frameNum;
+ frames[a].howMany = howMany;
}
-
- return newP;
}
-PersonaAnimation *makeNullAnim() {
- PersonaAnimation *newAnim = new PersonaAnimation ;
- if (!checkNew(newAnim))
- return NULL;
-
- newAnim->theSprites = NULL;
- newAnim->numFrames = 0;
- newAnim->frames = NULL;
- return newAnim;
-}
-
-PersonaAnimation *copyAnim(PersonaAnimation *orig) {
+PersonaAnimation::PersonaAnimation(PersonaAnimation *orig) {
int num = orig->numFrames;
- PersonaAnimation *newAnim = new PersonaAnimation ;
- if (!checkNew(newAnim))
- return NULL;
-
// Copy the easy bits...
- newAnim->theSprites = orig->theSprites;
- newAnim->numFrames = num;
+ theSprites = orig->theSprites;
+ numFrames = num;
if (num) {
-
- // Argh!Frames!We need a whole NEW array of AnimFrame structures...
-
- newAnim->frames = new AnimFrame [num];
- if (!checkNew(newAnim->frames))
- return NULL;
+ // Argh! Frames! We need a whole NEW array of AnimFrame structures...
+ frames = new AnimFrame[num];
for (int a = 0; a < num; a++) {
- newAnim->frames[a].frameNum = orig->frames[a].frameNum;
- newAnim->frames[a].howMany = orig->frames[a].howMany;
- newAnim->frames[a].noise = orig->frames[a].noise;
+ frames[a].frameNum = orig->frames[a].frameNum;
+ frames[a].howMany = orig->frames[a].howMany;
+ frames[a].noise = orig->frames[a].noise;
}
} else {
- newAnim->frames = NULL;
+ frames = nullptr;
}
+}
- return newAnim;
+int PersonaAnimation::getTotalTime() {
+ int total = 0;
+ for (int a = 0; a < numFrames; a++) {
+ total += frames[a].howMany;
+ }
+ return total;
}
-void deleteAnim(PersonaAnimation *orig) {
+bool PersonaAnimation::save(Common::WriteStream *stream) {
+ stream->writeUint16BE(numFrames);
+ if (numFrames) {
+ stream->writeUint32LE(theSprites->ID);
- if (orig) {
- if (orig->numFrames) {
- delete[] orig->frames;
+ for (int a = 0; a < numFrames; a++) {
+ stream->writeUint32LE(frames[a].frameNum);
+ stream->writeUint32LE(frames[a].howMany);
+ stream->writeUint32LE(frames[a].noise);
}
- delete orig;
- orig = NULL;
}
+ return true;
}
-void turnMeAngle(OnScreenPerson *thisPerson, int direc) {
+bool PersonaAnimation::load(Common::SeekableReadStream *stream) {
+ numFrames = stream->readUint16BE();
+
+ if (numFrames) {
+ int a = stream->readUint32LE();
+ frames = new AnimFrame [numFrames];
+ if (!checkNew(frames))
+ return false;
+ theSprites = g_sludge->_gfxMan->loadBankForAnim(a);
+
+ for (a = 0; a < numFrames; a++) {
+ frames[a].frameNum = stream->readUint32LE();
+ frames[a].howMany = stream->readUint32LE();
+ if (ssgVersion >= VERSION(2, 0)) {
+ frames[a].noise = stream->readUint32LE();
+ } else {
+ frames[a].noise = 0;
+ }
+ }
+ } else {
+ theSprites = NULL;
+ frames = NULL;
+ }
+ return true;
+}
+
+bool Persona::save(Common::WriteStream *stream) {
+ int a;
+ stream->writeUint16BE(numDirections);
+ for (a = 0; a < numDirections * 3; a++) {
+ if (!animation[a]->save(stream))
+ return false;
+ }
+ return true;
+}
+
+bool Persona::load(Common::SeekableReadStream *stream) {
+ int a;
+ numDirections = stream->readUint16BE();
+ animation = new PersonaAnimation *[numDirections * 3];
+ if (!checkNew(animation))
+ return false;
+ for (a = 0; a < numDirections * 3; a++) {
+ animation[a] = new PersonaAnimation;
+ if (!checkNew(animation[a]))
+ return false;
+
+ if (!animation[a]->load(stream))
+ return false;
+ }
+ return true;
+}
+
+void OnScreenPerson::setFrames(int a) {
+ myAnim = myPersona->animation[(a * myPersona->numDirections) + direction];
+}
+
+void OnScreenPerson::makeTalker() {
+ setFrames(ANI_TALK);
+}
+
+void OnScreenPerson::makeSilent() {
+ setFrames(ANI_STAND);
+}
+
+PeopleManager::PeopleManager(SludgeEngine *vm) {
+ _vm = vm;
+ _allPeople = nullptr;
+ _scaleHorizon = 75;
+ _scaleDivide = 150;
+ _personRegion = new ScreenRegion;
+}
+
+PeopleManager::~PeopleManager() {
+ kill();
+
+ delete _personRegion;
+ _personRegion = nullptr;
+}
+
+void PeopleManager::turnMeAngle(OnScreenPerson *thisPerson, int direc) {
int d = thisPerson->myPersona->numDirections;
thisPerson->angle = direc;
direc += (180 / d) + 180 + thisPerson->angleOffset;
@@ -157,16 +221,14 @@ void turnMeAngle(OnScreenPerson *thisPerson, int direc) {
thisPerson->direction = (direc * d) / 360;
}
-bool initPeople() {
- personRegion.sX = 0;
- personRegion.sY = 0;
- personRegion.di = -1;
- allScreenRegions = NULL;
-
+bool PeopleManager::init() {
+ _personRegion->sX = 0;
+ _personRegion->sY = 0;
+ _personRegion->di = -1;
return true;
}
-void spinStep(OnScreenPerson *thisPerson) {
+void PeopleManager::spinStep(OnScreenPerson *thisPerson) {
int diff = (thisPerson->angle + 360) - thisPerson->wantAngle;
int eachSlice = thisPerson->spinSpeed ? thisPerson->spinSpeed : (360 / thisPerson->myPersona->numDirections);
while (diff > 180) {
@@ -183,7 +245,7 @@ void spinStep(OnScreenPerson *thisPerson) {
}
}
-void rethinkAngle(OnScreenPerson *thisPerson) {
+void PeopleManager::rethinkAngle(OnScreenPerson *thisPerson) {
int d = thisPerson->myPersona->numDirections;
int direc = thisPerson->angle + (180 / d) + 180 + thisPerson->angleOffset;
while (direc >= 360)
@@ -191,7 +253,7 @@ void rethinkAngle(OnScreenPerson *thisPerson) {
thisPerson->direction = (direc * d) / 360;
}
-bool turnPersonToFace(int thisNum, int direc) {
+bool PeopleManager::turnPersonToFace(int thisNum, int direc) {
OnScreenPerson *thisPerson = findPerson(thisNum);
if (thisPerson) {
if (thisPerson->continueAfterWalking)
@@ -200,13 +262,14 @@ bool turnPersonToFace(int thisNum, int direc) {
thisPerson->walking = false;
thisPerson->spinning = false;
turnMeAngle(thisPerson, direc);
- setFrames(*thisPerson, g_sludge->_speechMan->isCurrentTalker(thisPerson) ? ANI_TALK : ANI_STAND);
+ _vm->_speechMan->isCurrentTalker(thisPerson) ?
+ thisPerson->makeTalker() : thisPerson->makeSilent();
return true;
}
return false;
}
-bool setPersonExtra(int thisNum, int extra) {
+bool PeopleManager::setPersonExtra(int thisNum, int extra) {
OnScreenPerson *thisPerson = findPerson(thisNum);
if (thisPerson) {
thisPerson->extra = extra;
@@ -217,20 +280,20 @@ bool setPersonExtra(int thisNum, int extra) {
return false;
}
-void setScale(int16 h, int16 d) {
- scaleHorizon = h;
- scaleDivide = d;
+void PeopleManager::setScale(int16 h, int16 d) {
+ _scaleHorizon = h;
+ _scaleDivide = d;
}
-void moveAndScale(OnScreenPerson &me, float x, float y) {
+void PeopleManager::moveAndScale(OnScreenPerson &me, float x, float y) {
me.x = x;
me.y = y;
- if (!(me.extra & EXTRA_NOSCALE) && scaleDivide)
- me.scale = (me.y - scaleHorizon) / scaleDivide;
+ if (!(me.extra & EXTRA_NOSCALE) && _scaleDivide)
+ me.scale = (me.y - _scaleHorizon) / _scaleDivide;
}
-OnScreenPerson *findPerson(int v) {
- OnScreenPerson *thisPerson = allPeople;
+OnScreenPerson *PeopleManager::findPerson(int v) {
+ OnScreenPerson *thisPerson = _allPeople;
while (thisPerson) {
if (v == thisPerson->thisType->objectNum)
break;
@@ -239,13 +302,13 @@ OnScreenPerson *findPerson(int v) {
return thisPerson;
}
-void movePerson(int x, int y, int objNum) {
+void PeopleManager::movePerson(int x, int y, int objNum) {
OnScreenPerson *moveMe = findPerson(objNum);
if (moveMe)
moveAndScale(*moveMe, x, y);
}
-void setShown(bool h, int ob) {
+void PeopleManager::setShown(bool h, int ob) {
OnScreenPerson *moveMe = findPerson(ob);
if (moveMe)
moveMe->show = h;
@@ -275,7 +338,7 @@ enum drawModes {
numDrawModes
};
-void setMyDrawMode(OnScreenPerson *moveMe, int h) {
+void PeopleManager::setMyDrawMode(OnScreenPerson *moveMe, int h) {
switch (h) {
case drawModeTransparent3:
moveMe->r = moveMe->g = moveMe->b = 0;
@@ -381,7 +444,7 @@ void setMyDrawMode(OnScreenPerson *moveMe, int h) {
}
-void setDrawMode(int h, int ob) {
+void PeopleManager::setDrawMode(int h, int ob) {
OnScreenPerson *moveMe = findPerson(ob);
if (!moveMe)
return;
@@ -389,7 +452,7 @@ void setDrawMode(int h, int ob) {
setMyDrawMode(moveMe, h);
}
-void setPersonTransparency(int ob, byte x) {
+void PeopleManager::setPersonTransparency(int ob, byte x) {
OnScreenPerson *moveMe = findPerson(ob);
if (!moveMe)
return;
@@ -399,7 +462,7 @@ void setPersonTransparency(int ob, byte x) {
moveMe->transparency = x;
}
-void setPersonColourise(int ob, byte r, byte g, byte b, byte colourmix) {
+void PeopleManager::setPersonColourise(int ob, byte r, byte g, byte b, byte colourmix) {
OnScreenPerson *moveMe = findPerson(ob);
if (!moveMe)
return;
@@ -410,13 +473,11 @@ void setPersonColourise(int ob, byte r, byte g, byte b, byte colourmix) {
moveMe->colourmix = colourmix;
}
-extern ScreenRegion *overRegion;
-
-void shufflePeople() {
- OnScreenPerson **thisReference = &allPeople;
+void PeopleManager::shufflePeople() {
+ OnScreenPerson **thisReference = &_allPeople;
OnScreenPerson *A, *B;
- if (!allPeople)
+ if (!_allPeople)
return;
while ((*thisReference)->next) {
@@ -440,12 +501,12 @@ void shufflePeople() {
}
}
-void drawPeople() {
+void PeopleManager::drawPeople() {
shufflePeople();
- OnScreenPerson *thisPerson = allPeople;
- PersonaAnimation *myAnim = NULL;
- overRegion = NULL;
+ OnScreenPerson *thisPerson = _allPeople;
+ PersonaAnimation *myAnim = NULL;
+ _vm->_regionMan->resetOverRegion();
while (thisPerson) {
if (thisPerson->show) {
@@ -455,7 +516,7 @@ void drawPeople() {
thisPerson->frameNum = 0;
thisPerson->frameTick = myAnim->frames[0].howMany;
if (myAnim->frames[thisPerson->frameNum].noise > 0) {
- g_sludge->_soundMan->startSound(myAnim->frames[thisPerson->frameNum].noise, false);
+ _vm->_soundMan->startSound(myAnim->frames[thisPerson->frameNum].noise, false);
thisPerson->frameNum++;
thisPerson->frameNum %= thisPerson->myAnim->numFrames;
thisPerson->frameTick = thisPerson->myAnim->frames[thisPerson->frameNum].howMany;
@@ -476,13 +537,13 @@ void drawPeople() {
}
if (m != 2) {
bool r = false;
- r = g_sludge->_gfxMan->scaleSprite(myAnim->theSprites->bank.sprites[fNum], myAnim->theSprites->bank.myPalette, thisPerson, m);
+ r = _vm->_gfxMan->scaleSprite(myAnim->theSprites->bank.sprites[fNum], myAnim->theSprites->bank.myPalette, thisPerson, m);
if (r) {
if (!thisPerson->thisType->screenName.empty()) {
- if (personRegion.thisType != thisPerson->thisType)
- lastRegion = NULL;
- personRegion.thisType = thisPerson->thisType;
- overRegion = &personRegion;
+ if (_personRegion->thisType != thisPerson->thisType)
+ _vm->_regionMan->resetLastRegion();
+ _personRegion->thisType = thisPerson->thisType;
+ _vm->_regionMan->setOverRegion(_personRegion);
}
}
}
@@ -493,7 +554,7 @@ void drawPeople() {
thisPerson->frameTick = thisPerson->myAnim->frames[thisPerson->frameNum].howMany;
if (thisPerson->show && myAnim && myAnim->frames) {
if (myAnim->frames[thisPerson->frameNum].noise > 0) {
- g_sludge->_soundMan->startSound(myAnim->frames[thisPerson->frameNum].noise, false);
+ _vm->_soundMan->startSound(myAnim->frames[thisPerson->frameNum].noise, false);
thisPerson->frameNum++;
thisPerson->frameNum %= thisPerson->myAnim->numFrames;
thisPerson->frameTick = thisPerson->myAnim->frames[thisPerson->frameNum].howMany;
@@ -510,38 +571,22 @@ void drawPeople() {
}
}
-void makeTalker(OnScreenPerson &me) {
- setFrames(me, ANI_TALK);
-}
-
-void makeSilent(OnScreenPerson &me) {
- setFrames(me, ANI_STAND);
-}
-
-bool handleClosestPoint(int &setX, int &setY, int &setPoly) {
+bool PeopleManager::handleClosestPoint(int &setX, int &setY, int &setPoly) {
int gotX = 320, gotY = 200, gotPoly = -1, i, j, xTest1, yTest1, xTest2, yTest2, closestX, closestY, oldJ, currentDistance = 0xFFFFF, thisDistance;
-// FILE * dbug = fopen ("debug_closest.txt", "at");
-// fprintf (dbug, "\nGetting closest point to %i, %i\n", setX, setY);
-
for (i = 0; i < currentFloor->numPolygons; i++) {
oldJ = currentFloor->polygon[i].numVertices - 1;
for (j = 0; j < currentFloor->polygon[i].numVertices; j++) {
-// fprintf (dbug, "Polygon %i, line %i... ", i, j);
xTest1 = currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].x;
yTest1 = currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].y;
xTest2 = currentFloor->vertex[currentFloor->polygon[i].vertexID[oldJ]].x;
yTest2 = currentFloor->vertex[currentFloor->polygon[i].vertexID[oldJ]].y;
closestPointOnLine(closestX, closestY, xTest1, yTest1, xTest2, yTest2, setX, setY);
-// fprintf (dbug, "closest point is %i, %i... ", closestX, closestY);
xTest1 = setX - closestX;
yTest1 = setY - closestY;
thisDistance = xTest1 * xTest1 + yTest1 * yTest1;
-// fprintf (dbug, "Distance squared %i\n", thisDistance);
if (thisDistance < currentDistance) {
-// fprintf (dbug, "** We have a new winner!**\n");
-
currentDistance = thisDistance;
gotX = closestX;
gotY = closestY;
@@ -550,7 +595,6 @@ bool handleClosestPoint(int &setX, int &setY, int &setPoly) {
oldJ = j;
}
}
-// fclose (dbug);
if (gotPoly == -1)
return false;
@@ -561,7 +605,7 @@ bool handleClosestPoint(int &setX, int &setY, int &setPoly) {
return true;
}
-bool doBorderStuff(OnScreenPerson *moveMe) {
+bool PeopleManager::doBorderStuff(OnScreenPerson *moveMe) {
if (moveMe->inPoly == moveMe->walkToPoly) {
moveMe->inPoly = -1;
moveMe->thisStepX = moveMe->walkToX;
@@ -627,11 +671,11 @@ bool doBorderStuff(OnScreenPerson *moveMe) {
moveMe->spinning = true;
}
- setFrames(*moveMe, ANI_WALK);
+ moveMe->setFrames(ANI_WALK);
return true;
}
-bool walkMe(OnScreenPerson *thisPerson, bool move = true) {
+bool PeopleManager::walkMe(OnScreenPerson *thisPerson, bool move) {
float xDiff, yDiff, maxDiff, s;
for (;;) {
@@ -646,7 +690,7 @@ bool walkMe(OnScreenPerson *thisPerson, bool move = true) {
if (ABS(maxDiff) > s) {
if (thisPerson->spinning) {
spinStep(thisPerson);
- setFrames(*thisPerson, ANI_WALK);
+ thisPerson->setFrames(ANI_WALK);
}
s = maxDiff / s;
if (move)
@@ -667,12 +711,12 @@ bool walkMe(OnScreenPerson *thisPerson, bool move = true) {
}
thisPerson->walking = false;
- setFrames(*thisPerson, ANI_STAND);
+ thisPerson->setFrames(ANI_STAND);
moveAndScale(*thisPerson, thisPerson->walkToX, thisPerson->walkToY);
return false;
}
-bool makeWalkingPerson(int x, int y, int objNum, LoadedFunction *func, int di) {
+bool PeopleManager::makeWalkingPerson(int x, int y, int objNum, LoadedFunction *func, int di) {
if (x == 0 && y == 0)
return false;
if (currentFloor->numPolygons == 0)
@@ -711,7 +755,7 @@ bool makeWalkingPerson(int x, int y, int objNum, LoadedFunction *func, int di) {
}
}
-bool stopPerson(int o) {
+bool PeopleManager::stopPerson(int o) {
OnScreenPerson *moveMe = findPerson(o);
if (moveMe)
if (moveMe->continueAfterWalking) {
@@ -719,13 +763,13 @@ bool stopPerson(int o) {
moveMe->continueAfterWalking = NULL;
moveMe->walking = false;
moveMe->spinning = false;
- setFrames(*moveMe, ANI_STAND);
+ moveMe->setFrames(ANI_STAND);
return true;
}
return false;
}
-bool forceWalkingPerson(int x, int y, int objNum, LoadedFunction *func, int di) {
+bool PeopleManager::forceWalkingPerson(int x, int y, int objNum, LoadedFunction *func, int di) {
if (x == 0 && y == 0)
return false;
OnScreenPerson *moveMe = findPerson(objNum);
@@ -755,7 +799,7 @@ bool forceWalkingPerson(int x, int y, int objNum, LoadedFunction *func, int di)
}
}
-void jumpPerson(int x, int y, int objNum) {
+void PeopleManager::jumpPerson(int x, int y, int objNum) {
if (x == 0 && y == 0)
return;
OnScreenPerson *moveMe = findPerson(objNum);
@@ -769,7 +813,7 @@ void jumpPerson(int x, int y, int objNum) {
moveAndScale(*moveMe, x, y);
}
-bool floatCharacter(int f, int objNum) {
+bool PeopleManager::floatCharacter(int f, int objNum) {
OnScreenPerson *moveMe = findPerson(objNum);
if (!moveMe)
return false;
@@ -777,7 +821,7 @@ bool floatCharacter(int f, int objNum) {
return true;
}
-bool setCharacterWalkSpeed(int f, int objNum) {
+bool PeopleManager::setCharacterWalkSpeed(int f, int objNum) {
if (f <= 0)
return false;
OnScreenPerson *moveMe = findPerson(objNum);
@@ -787,15 +831,15 @@ bool setCharacterWalkSpeed(int f, int objNum) {
return true;
}
-void walkAllPeople() {
- OnScreenPerson *thisPerson = allPeople;
+void PeopleManager::walkAllPeople() {
+ OnScreenPerson *thisPerson = _allPeople;
while (thisPerson) {
if (thisPerson->walking) {
walkMe(thisPerson);
} else if (thisPerson->spinning) {
spinStep(thisPerson);
- setFrames(*thisPerson, ANI_STAND);
+ thisPerson->setFrames(ANI_STAND);
}
if ((!thisPerson->walking) && (!thisPerson->spinning) && thisPerson->continueAfterWalking) {
restartFunction(thisPerson->continueAfterWalking);
@@ -805,13 +849,13 @@ void walkAllPeople() {
}
}
-bool addPerson(int x, int y, int objNum, Persona *p) {
+bool PeopleManager::addPerson(int x, int y, int objNum, Persona *p) {
OnScreenPerson *newPerson = new OnScreenPerson;
if (!checkNew(newPerson))
return false;
// EASY STUFF
- newPerson->thisType = g_sludge->_objMan->loadObjectType(objNum);
+ newPerson->thisType = _vm->_objMan->loadObjectType(objNum);
newPerson->scale = 1;
newPerson->extra = 0;
newPerson->continueAfterWalking = NULL;
@@ -839,7 +883,7 @@ bool addPerson(int x, int y, int objNum, Persona *p) {
newPerson->lastUsedAnim = 0;
newPerson->frameTick = 0;
- setFrames(*newPerson, ANI_STAND);
+ newPerson->setFrames(ANI_STAND);
// HEIGHT (BASED ON 1st FRAME OF 1st ANIMATION... INC. SPECIAL CASES)
int fNumSigned = p->animation[0]->frames[0].frameNum;
@@ -855,7 +899,7 @@ bool addPerson(int x, int y, int objNum, Persona *p) {
}
// NOW ADD IT IN THE RIGHT PLACE
- OnScreenPerson **changethat = &allPeople;
+ OnScreenPerson **changethat = &_allPeople;
while (((*changethat) != NULL) && ((*changethat)->y < y))
changethat = &((*changethat)->next);
@@ -866,15 +910,7 @@ bool addPerson(int x, int y, int objNum, Persona *p) {
return (bool)(newPerson->thisType != NULL);
}
-int timeForAnim(PersonaAnimation *fram) {
- int total = 0;
- for (int a = 0; a < fram->numFrames; a++) {
- total += fram->frames[a].howMany;
- }
- return total;
-}
-
-void animatePerson(int obj, PersonaAnimation *fram) { // Set a new SINGLE animation
+void PeopleManager::animatePerson(int obj, PersonaAnimation *fram) { // Set a new SINGLE animation
OnScreenPerson *moveMe = findPerson(obj);
if (moveMe) {
if (moveMe->continueAfterWalking)
@@ -886,7 +922,7 @@ void animatePerson(int obj, PersonaAnimation *fram) { // Set a new SINGLE anima
}
}
-void animatePerson(int obj, Persona *per) { // Set a new costume
+void PeopleManager::animatePerson(int obj, Persona *per) { // Set a new costume
OnScreenPerson *moveMe = findPerson(obj);
if (moveMe) {
// if (moveMe->continueAfterWalking) abortFunction (moveMe->continueAfterWalking);
@@ -896,29 +932,29 @@ void animatePerson(int obj, Persona *per) { // Set a new costume
moveMe->myPersona = per;
rethinkAngle(moveMe);
if (moveMe->walking) {
- setFrames(*moveMe, ANI_WALK);
+ moveMe->setFrames(ANI_WALK);
} else {
- setFrames(*moveMe, ANI_STAND);
+ moveMe->setFrames(ANI_STAND);
}
}
}
-void killAllPeople() {
+void PeopleManager::kill() {
OnScreenPerson *killPeople;
- while (allPeople) {
- if (allPeople->continueAfterWalking)
- abortFunction(allPeople->continueAfterWalking);
- allPeople->continueAfterWalking = NULL;
- killPeople = allPeople;
- allPeople = allPeople->next;
- g_sludge->_objMan->removeObjectType(killPeople->thisType);
+ while (_allPeople) {
+ if (_allPeople->continueAfterWalking)
+ abortFunction(_allPeople->continueAfterWalking);
+ _allPeople->continueAfterWalking = NULL;
+ killPeople = _allPeople;
+ _allPeople = _allPeople->next;
+ _vm->_objMan->removeObjectType(killPeople->thisType);
delete killPeople;
}
}
-void killMostPeople() {
+void PeopleManager::killMostPeople() {
OnScreenPerson *killPeople;
- OnScreenPerson **lookyHere = &allPeople;
+ OnScreenPerson **lookyHere = &_allPeople;
while (*lookyHere) {
if ((*lookyHere)->extra & EXTRA_NOREMOVE) {
@@ -933,18 +969,19 @@ void killMostPeople() {
if (killPeople->continueAfterWalking)
abortFunction(killPeople->continueAfterWalking);
killPeople->continueAfterWalking = NULL;
- g_sludge->_objMan->removeObjectType(killPeople->thisType);
+ _vm->_objMan->removeObjectType(killPeople->thisType);
delete killPeople;
}
}
}
-void removeOneCharacter(int i) {
+void PeopleManager::removeOneCharacter(int i) {
OnScreenPerson *p = findPerson(i);
if (p) {
- if (overRegion == &personRegion && overRegion->thisType == p->thisType) {
- overRegion = NULL;
+ ScreenRegion *overRegion = _vm->_regionMan->getOverRegion();
+ if (overRegion == _personRegion && overRegion->thisType == p->thisType) {
+ overRegion = nullptr;
}
if (p->continueAfterWalking)
@@ -952,91 +989,22 @@ void removeOneCharacter(int i) {
p->continueAfterWalking = NULL;
OnScreenPerson **killPeople;
- for (killPeople = &allPeople; *killPeople != p; killPeople = &((*killPeople)->next)) {
+ for (killPeople = &_allPeople; *killPeople != p; killPeople = &((*killPeople)->next)) {
;
}
*killPeople = p->next;
- g_sludge->_objMan->removeObjectType(p->thisType);
+ _vm->_objMan->removeObjectType(p->thisType);
delete p;
}
}
-bool saveAnim(PersonaAnimation *p, Common::WriteStream *stream) {
- stream->writeUint16BE(p->numFrames);
- if (p->numFrames) {
- stream->writeUint32LE(p->theSprites->ID);
-
- for (int a = 0; a < p->numFrames; a++) {
- stream->writeUint32LE(p->frames[a].frameNum);
- stream->writeUint32LE(p->frames[a].howMany);
- stream->writeUint32LE(p->frames[a].noise);
- }
- }
- return true;
-}
-
-bool loadAnim(PersonaAnimation *p, Common::SeekableReadStream *stream) {
- p->numFrames = stream->readUint16BE();
-
- if (p->numFrames) {
- int a = stream->readUint32LE();
- p->frames = new AnimFrame [p->numFrames];
- if (!checkNew(p->frames))
- return false;
- p->theSprites = g_sludge->_gfxMan->loadBankForAnim(a);
-
- for (a = 0; a < p->numFrames; a++) {
- p->frames[a].frameNum = stream->readUint32LE();
- p->frames[a].howMany = stream->readUint32LE();
- if (ssgVersion >= VERSION(2, 0)) {
- p->frames[a].noise = stream->readUint32LE();
- } else {
- p->frames[a].noise = 0;
- }
- }
- } else {
- p->theSprites = NULL;
- p->frames = NULL;
- }
- return true;
-}
-
-bool saveCostume(Persona *cossy, Common::WriteStream *stream) {
- int a;
- stream->writeUint16BE(cossy->numDirections);
- for (a = 0; a < cossy->numDirections * 3; a++) {
- if (!saveAnim(cossy->animation[a], stream))
- return false;
- }
-// debugCostume ("Saved", cossy);
- return true;
-}
-
-bool loadCostume(Persona *cossy, Common::SeekableReadStream *stream) {
- int a;
- cossy->numDirections = stream->readUint16BE();
- cossy->animation = new PersonaAnimation *[cossy->numDirections * 3];
- if (!checkNew(cossy->animation))
- return false;
- for (a = 0; a < cossy->numDirections * 3; a++) {
- cossy->animation[a] = new PersonaAnimation ;
- if (!checkNew(cossy->animation[a]))
- return false;
-
- if (!loadAnim(cossy->animation[a], stream))
- return false;
- }
-// debugCostume ("Loaded", cossy);
- return true;
-}
-
-bool savePeople(Common::WriteStream *stream) {
- OnScreenPerson *me = allPeople;
+bool PeopleManager::savePeople(Common::WriteStream *stream) {
+ OnScreenPerson *me = _allPeople;
int countPeople = 0, a;
- stream->writeSint16LE(scaleHorizon);
- stream->writeSint16LE(scaleDivide);
+ stream->writeSint16LE(_scaleHorizon);
+ stream->writeSint16LE(_scaleDivide);
while (me) {
countPeople++;
@@ -1045,14 +1013,14 @@ bool savePeople(Common::WriteStream *stream) {
stream->writeUint16BE(countPeople);
- me = allPeople;
+ me = _allPeople;
for (a = 0; a < countPeople; a++) {
stream->writeFloatLE(me->x);
stream->writeFloatLE(me->y);
- saveCostume(me->myPersona, stream);
- saveAnim(me->myAnim, stream);
+ me->myPersona->save(stream);
+ me->myAnim->save(stream);
stream->writeByte(me->myAnim == me->lastUsedAnim);
stream->writeFloatLE(me->scale);
@@ -1091,24 +1059,26 @@ bool savePeople(Common::WriteStream *stream) {
stream->writeByte(me->colourmix);
stream->writeByte(me->transparency);
- g_sludge->_objMan->saveObjectRef(me->thisType, stream);
+ _vm->_objMan->saveObjectRef(me->thisType, stream);
me = me->next;
}
return true;
}
-bool loadPeople(Common::SeekableReadStream *stream) {
- OnScreenPerson **pointy = &allPeople;
+bool PeopleManager::loadPeople(Common::SeekableReadStream *stream) {
+ kill();
+
+ OnScreenPerson **pointy = &_allPeople;
OnScreenPerson *me;
- scaleHorizon = stream->readSint16LE();
- scaleDivide = stream->readSint16LE();
+ _scaleHorizon = stream->readSint16LE();
+ _scaleDivide = stream->readSint16LE();
int countPeople = stream->readUint16BE();
int a;
- allPeople = NULL;
+ _allPeople = NULL;
for (a = 0; a < countPeople; a++) {
me = new OnScreenPerson;
if (!checkNew(me))
@@ -1118,15 +1088,15 @@ bool loadPeople(Common::SeekableReadStream *stream) {
if (!checkNew(me->myPersona))
return false;
- me->myAnim = new PersonaAnimation ;
+ me->myAnim = new PersonaAnimation;
if (!checkNew(me->myAnim))
return false;
me->x = stream->readFloatLE();
me->y = stream->readFloatLE();
- loadCostume(me->myPersona, stream);
- loadAnim(me->myAnim, stream);
+ me->myPersona->load(stream);
+ me->myAnim->load(stream);
me->lastUsedAnim = stream->readByte() ? me->myAnim : NULL;
@@ -1173,7 +1143,7 @@ bool loadPeople(Common::SeekableReadStream *stream) {
} else {
setMyDrawMode(me, stream->readUint16BE());
}
- me->thisType = g_sludge->_objMan->loadObjectRef(stream);
+ me->thisType = _vm->_objMan->loadObjectRef(stream);
// Anti-aliasing settings
if (ssgVersion >= VERSION(1, 6)) {
@@ -1189,8 +1159,17 @@ bool loadPeople(Common::SeekableReadStream *stream) {
*pointy = me;
pointy = &(me->next);
}
-// db ("End of loadPeople");
return true;
}
+void PeopleManager::freeze(FrozenStuffStruct *frozenStuff) {
+ frozenStuff->allPeople = _allPeople;
+ _allPeople = nullptr;
+}
+
+void PeopleManager::resotre(FrozenStuffStruct *frozenStuff) {
+ kill();
+ _allPeople = frozenStuff->allPeople;
+}
+
} // End of namespace Sludge
diff --git a/engines/sludge/people.h b/engines/sludge/people.h
index 95b8e923b6..60ad672ef7 100644
--- a/engines/sludge/people.h
+++ b/engines/sludge/people.h
@@ -26,6 +26,10 @@
namespace Sludge {
+struct FrozenStuffStruct;
+struct LoadedSpriteBank;
+struct ScreenRegion;
+
struct AnimFrame {
int frameNum, howMany;
int noise;
@@ -41,14 +45,30 @@ struct AnimFrame {
#define EXTRA_RECTANGULAR 64
struct PersonaAnimation {
- struct LoadedSpriteBank *theSprites;
- AnimFrame *frames;
+ LoadedSpriteBank *theSprites;
+ AnimFrame *frames;
int numFrames;
+
+ PersonaAnimation();
+ PersonaAnimation(int num, struct VariableStack *&stacky);
+ PersonaAnimation(PersonaAnimation *orig);
+ ~PersonaAnimation();
+
+ // Setter & getter
+ int getTotalTime();
+
+ // Save & load
+ bool save(Common::WriteStream *stream);
+ bool load(Common::SeekableReadStream *stream);
};
struct Persona {
- PersonaAnimation **animation;
+ PersonaAnimation **animation;
int numDirections;
+
+ // Save & load
+ bool save(Common::WriteStream *stream);
+ bool load(Common::SeekableReadStream *stream);
};
struct OnScreenPerson {
@@ -59,8 +79,8 @@ struct OnScreenPerson {
int walkToX, walkToY, thisStepX, thisStepY, inPoly, walkToPoly;
bool walking, spinning;
struct LoadedFunction *continueAfterWalking;
- PersonaAnimation *myAnim;
- PersonaAnimation *lastUsedAnim;
+ PersonaAnimation *myAnim;
+ PersonaAnimation *lastUsedAnim;
Persona *myPersona;
int frameNum, frameTick, angle, wantAngle, angleOffset;
bool show;
@@ -68,64 +88,84 @@ struct OnScreenPerson {
struct ObjectType *thisType;
int extra, spinSpeed;
byte r, g, b, colourmix, transparency;
+
+ void makeTalker();
+ void makeSilent();
+ void setFrames(int a);
};
-// Initialisation and creation
-bool initPeople();
-bool addPerson(int x, int y, int objNum, Persona *p);
-
-// Draw to screen and to backdrop
-void drawPeople();
-void freezePeople(int, int);
-
-// Removalisationisms
-void killAllPeople();
-void killMostPeople();
-void removeOneCharacter(int i);
-
-// Things which affect or use all characters
-OnScreenPerson *findPerson(int v);
-void setScale(int16 h, int16 d);
-
-// Things which affect one character
-void makeTalker(OnScreenPerson &me);
-void makeSilent(OnScreenPerson &me);
-void setShown(bool h, int ob);
-void setDrawMode(int h, int ob);
-void setPersonTransparency(int ob, byte x);
-void setPersonColourise(int ob, byte r, byte g, byte b, byte colourmix);
-
-// Moving 'em
-void movePerson(int x, int y, int objNum);
-bool makeWalkingPerson(int x, int y, int objNum, struct LoadedFunction *func, int di);
-bool forceWalkingPerson(int x, int y, int objNum, struct LoadedFunction *func, int di);
-void jumpPerson(int x, int y, int objNum);
-void walkAllPeople();
-bool turnPersonToFace(int thisNum, int direc);
-bool stopPerson(int o);
-bool floatCharacter(int f, int objNum);
-bool setCharacterWalkSpeed(int f, int objNum);
-
-// Animating 'em
-void animatePerson(int obj, PersonaAnimation *);
-void animatePerson(int obj, Persona *per);
-PersonaAnimation *createPersonaAnim(int num, struct VariableStack *&stacky);
-inline void setBankFile(PersonaAnimation *newP, LoadedSpriteBank *sB) {
- newP->theSprites = sB;
-}
-bool setPersonExtra(int f, int newSetting);
-int timeForAnim(PersonaAnimation *fram);
-PersonaAnimation *copyAnim(PersonaAnimation *orig);
-PersonaAnimation *makeNullAnim();
-void deleteAnim(PersonaAnimation *orig);
-
-// Loading and saving
-bool saveAnim(PersonaAnimation *p, Common::WriteStream *stream);
-bool loadAnim(PersonaAnimation *p, Common::SeekableReadStream *stream);
-bool savePeople(Common::WriteStream *stream);
-bool loadPeople(Common::SeekableReadStream *stream);
-bool saveCostume(Persona *cossy, Common::WriteStream *stream);
-bool loadCostume(Persona *cossy, Common::SeekableReadStream *stream);
+class PeopleManager {
+public:
+ PeopleManager(SludgeEngine *vm);
+ ~PeopleManager();
+
+ // Initialisation and creation
+ bool init();
+ bool addPerson(int x, int y, int objNum, Persona *p);
+
+ // Draw to screen and to backdrop
+ void drawPeople();
+ void freezePeople(int, int);
+
+ // Removalisationisms
+ void kill();
+ void killMostPeople();
+ void removeOneCharacter(int i);
+
+ // Things which affect or use all characters
+ OnScreenPerson *findPerson(int v);
+ void setScale(int16 h, int16 d);
+
+ // Things which affect one character
+ void setShown(bool h, int ob);
+ void setDrawMode(int h, int ob);
+ void setPersonTransparency(int ob, byte x);
+ void setPersonColourise(int ob, byte r, byte g, byte b, byte colourmix);
+
+ // Moving 'em
+ void movePerson(int x, int y, int objNum);
+ bool makeWalkingPerson(int x, int y, int objNum, struct LoadedFunction *func, int di);
+ bool forceWalkingPerson(int x, int y, int objNum, struct LoadedFunction *func, int di);
+ void jumpPerson(int x, int y, int objNum);
+ void walkAllPeople();
+ bool turnPersonToFace(int thisNum, int direc);
+ bool stopPerson(int o);
+ bool floatCharacter(int f, int objNum);
+ bool setCharacterWalkSpeed(int f, int objNum);
+
+ // Animating 'em
+ void animatePerson(int obj, PersonaAnimation *);
+ void animatePerson(int obj, Persona *per);
+ bool setPersonExtra(int f, int newSetting);
+
+ // Loading and saving
+ bool savePeople(Common::WriteStream *stream);
+ bool loadPeople(Common::SeekableReadStream *stream);
+
+ // Freeze
+ void freeze(FrozenStuffStruct *frozenStuff);
+ void resotre(FrozenStuffStruct *frozenStuff);
+
+private:
+ ScreenRegion *_personRegion;
+ OnScreenPerson *_allPeople;
+ int16 _scaleHorizon;
+ int16 _scaleDivide;
+
+ SludgeEngine *_vm;
+
+ void shufflePeople();
+ bool handleClosestPoint(int &setX, int &setY, int &setPoly);
+
+ // OnScreenPerson manipulation
+ void turnMeAngle(OnScreenPerson *thisPerson, int direc);
+ void spinStep(OnScreenPerson *thisPerson);
+ void rethinkAngle(OnScreenPerson *thisPerson);
+ void moveAndScale(OnScreenPerson &me, float x, float y);
+ void setMyDrawMode(OnScreenPerson *moveMe, int h);
+ bool doBorderStuff(OnScreenPerson *moveMe);
+ bool walkMe(OnScreenPerson *thisPerson, bool move = true);
+};
} // End of namespace Sludge
diff --git a/engines/sludge/region.cpp b/engines/sludge/region.cpp
index 7593fe4aee..4410951057 100644
--- a/engines/sludge/region.cpp
+++ b/engines/sludge/region.cpp
@@ -33,75 +33,65 @@
namespace Sludge {
-ScreenRegion *allScreenRegions = nullptr;
-ScreenRegion *overRegion = nullptr;
-ScreenRegion *lastRegion = nullptr;
-
-void showBoxes() {
- ScreenRegion*huntRegion = allScreenRegions;
-
- while (huntRegion) {
- g_sludge->_gfxMan->drawVerticalLine(huntRegion->x1, huntRegion->y1, huntRegion->y2);
- g_sludge->_gfxMan->drawVerticalLine(huntRegion->x2, huntRegion->y1, huntRegion->y2);
- g_sludge->_gfxMan->drawHorizontalLine(huntRegion->x1, huntRegion->y1, huntRegion->x2);
- g_sludge->_gfxMan->drawHorizontalLine(huntRegion->x1, huntRegion->y2, huntRegion->x2);
- huntRegion = huntRegion->next;
- }
+RegionManager::RegionManager(SludgeEngine *vm)
+{
+ _vm = vm;
+ _allScreenRegions = new ScreenRegionList;
+ _allScreenRegions->clear();
+ _lastRegion = nullptr;
+ _overRegion = nullptr;
+}
+
+RegionManager::~RegionManager() {
+ kill();
+
+ delete _allScreenRegions;
+ _allScreenRegions = nullptr;
}
-void removeScreenRegion(int objectNum) {
- ScreenRegion **huntRegion = &allScreenRegions;
- ScreenRegion *killMe;
+void RegionManager::showBoxes() {
+ for (ScreenRegionList::iterator it = _allScreenRegions->begin(); it != _allScreenRegions->end(); ++it) {
+ g_sludge->_gfxMan->drawVerticalLine((*it)->x1, (*it)->y1, (*it)->y2);
+ g_sludge->_gfxMan->drawVerticalLine((*it)->x2, (*it)->y1, (*it)->y2);
+ g_sludge->_gfxMan->drawHorizontalLine((*it)->x1, (*it)->y1, (*it)->x2);
+ g_sludge->_gfxMan->drawHorizontalLine((*it)->x1, (*it)->y2, (*it)->x2);
+ }
+}
- while (*huntRegion) {
- if ((*huntRegion)->thisType->objectNum == objectNum) {
- killMe = *huntRegion;
- *huntRegion = killMe->next;
+void RegionManager::removeScreenRegion(int objectNum) {
+ for (ScreenRegionList::iterator it = _allScreenRegions->begin(); it != _allScreenRegions->end(); ++it) {
+ if ((*it)->thisType->objectNum == objectNum) {
+ ScreenRegion *killMe = *it;
g_sludge->_objMan->removeObjectType(killMe->thisType);
- if (killMe == overRegion)
- overRegion = NULL;
+ if (killMe == _overRegion)
+ _overRegion = nullptr;
delete killMe;
- killMe = NULL;
- } else {
- huntRegion = &((*huntRegion)->next);
+ killMe = nullptr;
+ _allScreenRegions->reverse_erase(it);
}
}
}
-void saveRegions(Common::WriteStream *stream) {
- int numRegions = 0;
- ScreenRegion *thisRegion = allScreenRegions;
- while (thisRegion) {
- thisRegion = thisRegion->next;
- numRegions++;
- }
+void RegionManager::saveRegions(Common::WriteStream *stream) {
+ uint numRegions = _allScreenRegions->size();
stream->writeUint16BE(numRegions);
- thisRegion = allScreenRegions;
- while (thisRegion) {
- stream->writeUint16BE(thisRegion->x1);
- stream->writeUint16BE(thisRegion->y1);
- stream->writeUint16BE(thisRegion->x2);
- stream->writeUint16BE(thisRegion->y2);
- stream->writeUint16BE(thisRegion->sX);
- stream->writeUint16BE(thisRegion->sY);
- stream->writeUint16BE(thisRegion->di);
- g_sludge->_objMan->saveObjectRef(thisRegion->thisType, stream);
-
- thisRegion = thisRegion->next;
+ for (ScreenRegionList::iterator it = _allScreenRegions->begin(); it != _allScreenRegions->end(); ++it) {
+ stream->writeUint16BE((*it)->x1);
+ stream->writeUint16BE((*it)->y1);
+ stream->writeUint16BE((*it)->x2);
+ stream->writeUint16BE((*it)->y2);
+ stream->writeUint16BE((*it)->sX);
+ stream->writeUint16BE((*it)->sY);
+ stream->writeUint16BE((*it)->di);
+ g_sludge->_objMan->saveObjectRef((*it)->thisType, stream);
}
}
-void loadRegions(Common::SeekableReadStream *stream) {
+void RegionManager::loadRegions(Common::SeekableReadStream *stream) {
int numRegions = stream->readUint16BE();
-
- ScreenRegion *newRegion;
- ScreenRegion **pointy = &allScreenRegions;
-
while (numRegions--) {
- newRegion = new ScreenRegion;
- *pointy = newRegion;
- pointy = &(newRegion->next);
-
+ ScreenRegion *newRegion = new ScreenRegion;
+ _allScreenRegions->push_back(newRegion);
newRegion->x1 = stream->readUint16BE();
newRegion->y1 = stream->readUint16BE();
newRegion->x2 = stream->readUint16BE();
@@ -111,22 +101,20 @@ void loadRegions(Common::SeekableReadStream *stream) {
newRegion->di = stream->readUint16BE();
newRegion->thisType = g_sludge->_objMan->loadObjectRef(stream);
}
- *pointy = NULL;
}
-void killAllRegions() {
- ScreenRegion *killRegion;
- while (allScreenRegions) {
- killRegion = allScreenRegions;
- allScreenRegions = allScreenRegions->next;
+void RegionManager::kill() {
+ for (ScreenRegionList::iterator it = _allScreenRegions->begin(); it != _allScreenRegions->end(); ++it) {
+ ScreenRegion *killRegion = (*it);
g_sludge->_objMan->removeObjectType(killRegion->thisType);
delete killRegion;
}
- overRegion = nullptr;
- lastRegion = nullptr;
+ _allScreenRegions->clear();
+ _overRegion = nullptr;
+ _lastRegion = nullptr;
}
-bool addScreenRegion(int x1, int y1, int x2, int y2, int sX, int sY, int di,
+bool RegionManager::addScreenRegion(int x1, int y1, int x2, int y2, int sX, int sY, int di,
int objectNum) {
ScreenRegion *newRegion = new ScreenRegion;
if (!checkNew(newRegion))
@@ -139,40 +127,51 @@ bool addScreenRegion(int x1, int y1, int x2, int y2, int sX, int sY, int di,
newRegion->sX = sX;
newRegion->sY = sY;
newRegion->thisType = g_sludge->_objMan->loadObjectType(objectNum);
- newRegion->next = allScreenRegions;
- allScreenRegions = newRegion;
- return (bool) (newRegion->thisType != NULL);
+ _allScreenRegions->push_front(newRegion);
+ return (bool) (newRegion->thisType != nullptr);
}
-void getOverRegion() {
+void RegionManager::updateOverRegion() {
int cameraX = g_sludge->_gfxMan->getCamX();
int cameraY = g_sludge->_gfxMan->getCamY();
- ScreenRegion *thisRegion = allScreenRegions;
- while (thisRegion) {
- if ((g_sludge->_evtMan->mouseX() >= thisRegion->x1 - cameraX)
- && (g_sludge->_evtMan->mouseY() >= thisRegion->y1 - cameraY)
- && (g_sludge->_evtMan->mouseX() <= thisRegion->x2 - cameraX)
- && (g_sludge->_evtMan->mouseY() <= thisRegion->y2 - cameraY)) {
- overRegion = thisRegion;
+ for (ScreenRegionList::iterator it = _allScreenRegions->begin(); it != _allScreenRegions->end(); ++it) {
+ if ((g_sludge->_evtMan->mouseX() >= (*it)->x1 - cameraX)
+ && (g_sludge->_evtMan->mouseY() >= (*it)->y1 - cameraY)
+ && (g_sludge->_evtMan->mouseX() <= (*it)->x2 - cameraX)
+ && (g_sludge->_evtMan->mouseY() <= (*it)->y2 - cameraY)) {
+ _overRegion = (*it);
return;
}
- thisRegion = thisRegion->next;
}
- overRegion = NULL;
+ _overRegion = nullptr;
return;
}
-ScreenRegion *getRegionForObject(int obj) {
- ScreenRegion *thisRegion = allScreenRegions;
-
- while (thisRegion) {
- if (obj == thisRegion->thisType->objectNum) {
- return thisRegion;
+ScreenRegion *RegionManager::getRegionForObject(int obj) {
+ for (ScreenRegionList::iterator it = _allScreenRegions->begin(); it != _allScreenRegions->end(); ++it) {
+ if (obj == (*it)->thisType->objectNum) {
+ return (*it);
}
- thisRegion = thisRegion->next;
}
- return NULL;
+ return nullptr;
+}
+
+void RegionManager::freeze(FrozenStuffStruct *frozenStuff) {
+ frozenStuff->allScreenRegions = _allScreenRegions;
+ _allScreenRegions = new ScreenRegionList;
+ _overRegion = nullptr;
+}
+
+void RegionManager::resotre(FrozenStuffStruct *frozenStuff) {
+ // kill
+ kill();
+ delete _allScreenRegions;
+ _allScreenRegions = nullptr;
+
+ // restore
+ _allScreenRegions = frozenStuff->allScreenRegions;
+ _overRegion = nullptr;
}
} // End of namespace Sludge
diff --git a/engines/sludge/region.h b/engines/sludge/region.h
index 74294814f6..5f307cc9d0 100644
--- a/engines/sludge/region.h
+++ b/engines/sludge/region.h
@@ -23,24 +23,56 @@
#define SLUDGE_REGION_H
#include "sludge/objtypes.h"
+#include "sludge/freeze.h"
namespace Sludge {
struct ScreenRegion {
int x1, y1, x2, y2, sX, sY, di;
ObjectType *thisType;
- ScreenRegion *next;
};
+typedef Common::List<ScreenRegion *> ScreenRegionList;
-bool addScreenRegion(int x1, int y1, int x2, int y2, int, int, int, int objectNum);
-void getOverRegion();
-ScreenRegion *getRegionForObject(int obj);
-void removeScreenRegion(int objectNum);
-void loadRegions(Common::SeekableReadStream *stream);
-void saveRegions(Common::WriteStream *stream);
-void killAllRegions();
+class RegionManager {
+public:
+ RegionManager(SludgeEngine *vm);
+ ~RegionManager();
-void showBoxes();
+ // Kill
+ void kill();
+
+ // Add & remove region
+ bool addScreenRegion(int x1, int y1, int x2, int y2, int, int, int, int objectNum);
+ void removeScreenRegion(int objectNum);
+
+ // Save & load
+ void loadRegions(Common::SeekableReadStream *stream);
+ void saveRegions(Common::WriteStream *stream);
+
+ // Draw
+ void showBoxes();
+
+ // Setter & getter
+ ScreenRegion *getRegionForObject(int obj);
+ ScreenRegion *getOverRegion() const { return _overRegion; }
+ void setOverRegion(ScreenRegion *newRegion) { _overRegion = newRegion; }
+ void updateOverRegion();
+ bool isRegionChanged() const { return _lastRegion != _overRegion; }
+ void updateLastRegion() { _lastRegion = _overRegion; }
+ void resetOverRegion() { _overRegion = nullptr; }
+ void resetLastRegion() { _lastRegion = nullptr; }
+
+ // Freeze
+ void freeze(FrozenStuffStruct *frozenStuff);
+ void resotre(FrozenStuffStruct *frozenStuff);
+
+private:
+ SludgeEngine *_vm;
+
+ ScreenRegionList *_allScreenRegions;
+ ScreenRegion *_overRegion;
+ ScreenRegion *_lastRegion;
+};
} // End of namespace Sludge
diff --git a/engines/sludge/sludge.cpp b/engines/sludge/sludge.cpp
index d14f92202f..38fe12a4a6 100644
--- a/engines/sludge/sludge.cpp
+++ b/engines/sludge/sludge.cpp
@@ -29,6 +29,8 @@
#include "sludge/event.h"
#include "sludge/fonttext.h"
#include "sludge/graphics.h"
+#include "sludge/people.h"
+#include "sludge/region.h"
#include "sludge/sludge.h"
#include "sludge/sound.h"
#include "sludge/speech.h"
@@ -73,6 +75,7 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
fatalInfo = "Initialisation error! Something went wrong before we even got started!";
// Init managers
+ _peopleMan = new PeopleManager(this);
_resMan = new ResourceManager();
_languageMan = new LanguageManager();
_objMan = new ObjectManager(this);
@@ -82,6 +85,7 @@ SludgeEngine::SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc)
_txtMan = new TextManager();
_cursorMan = new CursorManager(this);
_speechMan = new SpeechManager(this);
+ _regionMan = new RegionManager(this);
}
SludgeEngine::~SludgeEngine() {
@@ -122,6 +126,10 @@ SludgeEngine::~SludgeEngine() {
_resMan = nullptr;
delete _speechMan;
_speechMan = nullptr;
+ delete _regionMan;
+ _regionMan = nullptr;
+ delete _peopleMan;
+ _peopleMan = nullptr;
}
Common::Error SludgeEngine::run() {
diff --git a/engines/sludge/sludge.h b/engines/sludge/sludge.h
index 83c6359f52..66a443e32a 100644
--- a/engines/sludge/sludge.h
+++ b/engines/sludge/sludge.h
@@ -41,6 +41,8 @@ extern SludgeEngine *g_sludge;
class CursorManager;
class EventManager;
class GraphicsManager;
+class PeopleManager;
+class RegionManager;
class SoundManager;
class SpeechManager;
class TextManager;
@@ -88,6 +90,8 @@ public:
TextManager *_txtMan;
CursorManager *_cursorMan;
SpeechManager *_speechMan;
+ RegionManager *_regionMan;
+ PeopleManager *_peopleMan;
SludgeEngine(OSystem *syst, const SludgeGameDescription *gameDesc);
virtual ~SludgeEngine();
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp
index 9526ddf4df..4f5f204d92 100644
--- a/engines/sludge/sludger.cpp
+++ b/engines/sludge/sludger.cpp
@@ -67,7 +67,6 @@ int selectedLanguage = 0;
int gameVersion;
FILETIME fileTime;
-bool captureAllKeys = false;
byte brightnessLevel = 255;
@@ -79,7 +78,6 @@ Variable *globalVars;
int numGlobals = 0;
-extern SpritePalette pastePalette;
extern Variable *launchResult;
extern int lastFramesPerSecond, thumbWidth, thumbHeight;
@@ -149,7 +147,7 @@ void initSludge() {
g_sludge->_languageMan->init();
g_sludge->_gfxMan->init();
g_sludge->_resMan->init();
- initPeople();
+ g_sludge->_peopleMan->init();
initFloor();
g_sludge->_objMan->init();
g_sludge->_speechMan->init();
@@ -171,7 +169,6 @@ void initSludge() {
lastFramesPerSecond = -1;
thumbWidth = thumbHeight = 0;
allowAnyFilename = true;
- captureAllKeys = false;
noStack = nullptr;
numBIFNames = numUserFunc = 0;
allUserFunc = allBIFNames = nullptr;
@@ -182,8 +179,8 @@ void initSludge() {
void killSludge() {
killAllFunctions();
- killAllPeople();
- killAllRegions();
+ g_sludge->_peopleMan->kill();
+ g_sludge->_regionMan->kill();
setFloorNull();
g_sludge->_speechMan->kill();
g_sludge->_languageMan->kill();
@@ -333,7 +330,7 @@ void displayBase() {
g_sludge->_gfxMan->clear(); // Clear screen
g_sludge->_gfxMan->drawBackDrop();// Draw Backdrop
g_sludge->_gfxMan->drawZBuffer(g_sludge->_gfxMan->getCamX(), g_sludge->_gfxMan->getCamY(), false);
- drawPeople();// Then add any moving characters...
+ g_sludge->_peopleMan->drawPeople();// Then add any moving characters...
g_sludge->_gfxMan->displaySpriteLayers();
}
diff --git a/engines/sludge/speech.cpp b/engines/sludge/speech.cpp
index b3fedac70e..cac4a5e705 100644
--- a/engines/sludge/speech.cpp
+++ b/engines/sludge/speech.cpp
@@ -61,8 +61,8 @@ void SpeechManager::kill() {
}
if (_speech->currentTalker) {
- makeSilent(*(_speech->currentTalker));
- _speech->currentTalker = NULL;
+ _speech->currentTalker->makeSilent();
+ _speech->currentTalker = nullptr;
}
SpeechLine *killMe;
@@ -176,7 +176,7 @@ int SpeechManager::wrapSpeechPerson(const Common::String &theText, OnScreenPerso
- thePerson.thisType->speechGap,
thePerson.thisType->wrapSpeech, sampleFile);
if (animPerson) {
- makeTalker(thePerson);
+ thePerson.makeTalker();
_speech->currentTalker = &thePerson;
}
return i;
@@ -188,12 +188,12 @@ int SpeechManager::wrapSpeech(const Common::String &theText, int objT, int sampl
int cameraY = g_sludge->_gfxMan->getCamY();
_speech->lookWhosTalking = objT;
- OnScreenPerson *thisPerson = findPerson(objT);
+ OnScreenPerson *thisPerson = g_sludge->_peopleMan->findPerson(objT);
if (thisPerson) {
setObjFontColour(thisPerson->thisType);
i = wrapSpeechPerson(theText, *thisPerson, sampleFile, animPerson);
} else {
- ScreenRegion *thisRegion = getRegionForObject(objT);
+ ScreenRegion *thisRegion = g_sludge->_regionMan->getRegionForObject(objT);
if (thisRegion) {
setObjFontColour(thisRegion->thisType);
i = wrapSpeechXY(theText,
@@ -274,7 +274,7 @@ bool SpeechManager::load(Common::SeekableReadStream *stream) {
_speech->lookWhosTalking = stream->readUint16BE();
if (stream->readByte()) {
- _speech->currentTalker = findPerson(stream->readUint16BE());
+ _speech->currentTalker = g_sludge->_peopleMan->findPerson(stream->readUint16BE());
} else {
_speech->currentTalker = NULL;
}
diff --git a/engines/sludge/statusba.cpp b/engines/sludge/statusba.cpp
index 04fa18e957..fc0f065ea9 100644
--- a/engines/sludge/statusba.cpp
+++ b/engines/sludge/statusba.cpp
@@ -37,8 +37,8 @@ namespace Sludge {
SpritePalette verbLinePalette;
SpritePalette litVerbLinePalette;
-StatusStuff mainStatus;
-StatusStuff *nowStatus = & mainStatus;
+StatusStuff mainStatus;
+StatusStuff *nowStatus = & mainStatus;
void setLitStatus(int i) {
nowStatus->litStatus = i;
@@ -144,7 +144,7 @@ StatusStuff *copyStatusBarStuff(StatusStuff *here) {
here->litStatus = -1;
here->firstStatusBar = NULL;
- StatusStuff *old = nowStatus;
+ StatusStuff *old = nowStatus;
nowStatus = here;
return old;
diff --git a/engines/sludge/variable.cpp b/engines/sludge/variable.cpp
index 9cbb9f49f8..5537377869 100644
--- a/engines/sludge/variable.cpp
+++ b/engines/sludge/variable.cpp
@@ -65,7 +65,10 @@ void unlinkVar(Variable &thisVar) {
break;
case SVT_ANIM:
- deleteAnim(thisVar.varData.animHandler);
+ if (thisVar.varData.animHandler) {
+ delete thisVar.varData.animHandler;
+ thisVar.varData.animHandler = nullptr;
+ }
break;
default:
@@ -85,12 +88,12 @@ void newAnimationVariable(Variable &thisVar, PersonaAnimation *i) {
thisVar.varData.animHandler = i;
}
-PersonaAnimation *getAnimationFromVar(Variable &thisVar) {
+PersonaAnimation *getAnimationFromVar(Variable &thisVar) {
if (thisVar.varType == SVT_ANIM)
- return copyAnim(thisVar.varData.animHandler);
+ return new PersonaAnimation(thisVar.varData.animHandler);
if (thisVar.varType == SVT_INT && thisVar.varData.intValue == 0)
- return makeNullAnim();
+ return new PersonaAnimation();
fatal("Expecting an animation variable; found Variable of type", typeName[thisVar.varType]);
return NULL;
@@ -116,7 +119,7 @@ Persona *getCostumeFromVar(Variable &thisVar) {
return NULL;
for (int iii = 0; iii < 3; iii++)
- p->animation[iii] = copyAnim(thisVar.varData.animHandler);
+ p->animation[iii] = new PersonaAnimation(thisVar.varData.animHandler);
break;
@@ -370,7 +373,7 @@ bool copyMain(const Variable &from, Variable &to) {
return true;
case SVT_ANIM:
- to.varData.animHandler = copyAnim(from.varData.animHandler);
+ to.varData.animHandler = new PersonaAnimation(from.varData.animHandler);
return true;
case SVT_NULL:
diff --git a/engines/sludge/variable.h b/engines/sludge/variable.h
index 005eb1cd05..a3cc57d911 100644
--- a/engines/sludge/variable.h
+++ b/engines/sludge/variable.h
@@ -24,6 +24,8 @@
namespace Sludge {
+struct Persona;
+struct PersonaAnimation;
struct Variable;
struct VariableStack;
@@ -58,8 +60,8 @@ union VariableData {
signed int intValue;
const char *theString;
StackHandler *theStack;
- struct PersonaAnimation *animHandler;
- struct Persona *costumeHandler;
+ PersonaAnimation *animHandler;
+ Persona *costumeHandler;
FastArrayHandler *fastArray;
};
diff --git a/engines/supernova/detection.cpp b/engines/supernova/detection.cpp
index 8e9db14db4..b172b7fa49 100644
--- a/engines/supernova/detection.cpp
+++ b/engines/supernova/detection.cpp
@@ -32,7 +32,7 @@
static const PlainGameDescriptor supernovaGames[] = {
{"msn1", "Mission Supernova 1"},
{"msn2", "Mission Supernova 2"},
- {NULL, NULL}
+ {nullptr, nullptr}
};
namespace Supernova {
@@ -40,7 +40,7 @@ static const ADGameDescription gameDescriptions[] = {
// Mission Supernova 1
{
"msn1",
- NULL,
+ nullptr,
AD_ENTRY1s("msn_data.000", "f64f16782a86211efa919fbae41e7568", 24163),
Common::DE_DEU,
Common::kPlatformDOS,
@@ -49,7 +49,7 @@ static const ADGameDescription gameDescriptions[] = {
},
{
"msn1",
- NULL,
+ nullptr,
AD_ENTRY1s("msn_data.000", "f64f16782a86211efa919fbae41e7568", 24163),
Common::EN_ANY,
Common::kPlatformDOS,
@@ -60,13 +60,22 @@ static const ADGameDescription gameDescriptions[] = {
// Mission Supernova 2
{
"msn2",
- NULL,
+ nullptr,
AD_ENTRY1s("ms2_data.000", "e595610cba4a6d24a763e428d05cc83f", 24805),
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO1(GUIO_NONE)
},
+ {
+ "msn2",
+ nullptr,
+ AD_ENTRY1s("ms2_data.000", "e595610cba4a6d24a763e428d05cc83f", 24805),
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_UNSTABLE,
+ GUIO1(GUIO_NONE)
+ },
AD_TABLE_END_MARKER
};
@@ -122,7 +131,7 @@ bool SupernovaMetaEngine::createInstance(OSystem *syst, Engine **engine, const A
*engine = new Supernova::SupernovaEngine(syst);
}
- return desc != NULL;
+ return desc != nullptr;
}
SaveStateList SupernovaMetaEngine::listSaves(const char *target) const {
@@ -200,7 +209,11 @@ SaveStateDescriptor SupernovaMetaEngine::querySaveMetaInfos(const char *target,
desc.setPlayTime(playTime * 1000);
if (Graphics::checkThumbnailHeader(*savefile)) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*savefile);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*savefile, thumbnail)) {
+ delete savefile;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
}
diff --git a/engines/supernova/graphics.cpp b/engines/supernova/graphics.cpp
index 3a29bacacc..9a05a424ca 100644
--- a/engines/supernova/graphics.cpp
+++ b/engines/supernova/graphics.cpp
@@ -28,13 +28,14 @@
#include "graphics/palette.h"
#include "graphics/surface.h"
-#include "graphics.h"
-#include "msn_def.h"
-#include "supernova.h"
+#include "supernova/graphics.h"
+#include "supernova/msn_def.h"
+#include "supernova/screen.h"
+#include "supernova/supernova.h"
namespace Supernova {
-MSNImageDecoder::MSNImageDecoder() {
+MSNImage::MSNImage() {
_palette = nullptr;
_encodedImage = nullptr;
_filenumber = -1;
@@ -43,11 +44,11 @@ MSNImageDecoder::MSNImageDecoder() {
_numClickFields = 0;
}
-MSNImageDecoder::~MSNImageDecoder() {
+MSNImage::~MSNImage() {
destroy();
}
-bool MSNImageDecoder::init(int filenumber) {
+bool MSNImage::init(int filenumber) {
Common::File file;
if (!file.open(Common::String::format("msn_data.%03d", filenumber))) {
warning("Image data file msn_data.%03d could not be read!", filenumber);
@@ -60,7 +61,7 @@ bool MSNImageDecoder::init(int filenumber) {
return true;
}
-bool MSNImageDecoder::loadFromEngineDataFile() {
+bool MSNImage::loadFromEngineDataFile() {
Common::String name;
if (_filenumber == 1)
name = "IMG1";
@@ -102,7 +103,7 @@ bool MSNImageDecoder::loadFromEngineDataFile() {
return false;
}
-bool MSNImageDecoder::loadStream(Common::SeekableReadStream &stream) {
+bool MSNImage::loadStream(Common::SeekableReadStream &stream) {
destroy();
uint size = 0;
@@ -199,7 +200,7 @@ bool MSNImageDecoder::loadStream(Common::SeekableReadStream &stream) {
return true;
}
-bool MSNImageDecoder::loadSections() {
+bool MSNImage::loadSections() {
bool isNewspaper = _filenumber == 1 || _filenumber == 2;
int imageWidth = isNewspaper ? 640 : 320;
int imageHeight = isNewspaper ? 480 : 200;
@@ -238,14 +239,14 @@ bool MSNImageDecoder::loadSections() {
return true;
}
-void MSNImageDecoder::destroy() {
+void MSNImage::destroy() {
if (_palette) {
delete[] _palette;
- _palette = NULL;
+ _palette = nullptr;
}
if (_encodedImage) {
delete[] _encodedImage;
- _encodedImage = NULL;
+ _encodedImage = nullptr;
}
for (Common::Array<Graphics::Surface *>::iterator it = _sectionSurfaces.begin();
it != _sectionSurfaces.end(); ++it) {
diff --git a/engines/supernova/graphics.h b/engines/supernova/graphics.h
index 2a820c9432..058da45ba8 100644
--- a/engines/supernova/graphics.h
+++ b/engines/supernova/graphics.h
@@ -36,10 +36,10 @@ struct Surface;
namespace Supernova {
-class MSNImageDecoder : public Image::ImageDecoder {
+class MSNImage : public Image::ImageDecoder {
public:
- MSNImageDecoder();
- virtual ~MSNImageDecoder();
+ MSNImage();
+ virtual ~MSNImage();
virtual void destroy();
virtual bool loadStream(Common::SeekableReadStream &stream);
diff --git a/engines/supernova/imageid.h b/engines/supernova/imageid.h
new file mode 100644
index 0000000000..7cfa08370e
--- /dev/null
+++ b/engines/supernova/imageid.h
@@ -0,0 +1,654 @@
+/* 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 SUPERNOVA_IMAGEID_H
+#define SUPERNOVA_IMAGEID_H
+
+namespace Supernova {
+
+enum ImageId {
+ // file 0
+ kAxacussanShipBackground,
+ kAxacussanShipCenterMouthOpen,
+ kAxacussanShipRightMouthOpen,
+ // file 1
+ kNewspaper1,
+ // file 2
+ kNewspaper2,
+ // file 3
+ kElevatorBackground,
+ kElevatorGreenButton,
+ kElevatorRedButton,
+ kElevatorDoorAnimation1,
+ kElevatorDoorAnimation2,
+ kElevatorDoorAnimation3,
+ kElevatorDoorAnimation4,
+ kElevatorDoorAnimation5,
+ kElevatorDummy1,
+ kElevatorDummy2,
+ kElevatorDummy3,
+ kElevatorDummy4,
+ // file 4
+ kShipSpaceBackground,
+ kShipSpaceRope,
+ kShipSpaceDummy1,
+ kShipSpaceDummy2,
+ // file 5
+ kBusStationBackground,
+ kBusStationArrived,
+ kBusStationPlantAnimation1,
+ kBusStationPlantAnimation2,
+ kBusStationPlantAnimation3,
+ kBusStationPlantAnimation4,
+ kBusStationPlantAnimation5,
+ kBusStationPlantAnimation6,
+ kBusStationPlantAnimation7,
+ kBusStationDoorOpened,
+ // file 6
+ kOfficesBackground,
+ kOfficesDoorOpenTopLeft,
+ kOfficesDoorOpenBottomLeft,
+ kOfficesDoorOpenTopRight,
+ kOfficesDoorOpenBottomRight,
+ kOfficesAlienCorridorAnimation1,
+ kOfficesAlienCorridorAnimation2,
+ kOfficesAlienCorridorAnimation3,
+ kOfficesAlienCorridorAnimation4,
+ kOfficesAlienCorridorAnimation5,
+ kOfficesAlienCorridorAnimation6,
+ kOfficesAlienTopOfficeAnimation1,
+ kOfficesAlienTopOfficeAnimation2,
+ kOfficesAlienTopOfficeAnimation3,
+ kOfficesAlienTopOfficeAnimation4,
+ kOfficesAlienTopOfficeAnimation5,
+ kOfficesAlienBottomOfficeAnimation1,
+ kOfficesAlienBottomOfficeAnimation2,
+ kOfficesAlienBottomOfficeAnimation3,
+ kOfficesAlienBottomOfficeAnimation4,
+ kOfficesAlienBottomOfficeAnimation5,
+ kOfficesAlienBottom,
+ // file 7
+ kOfficeLeftBackground,
+ kOfficeLeftDecoration,
+ kOfficeLeftMemo,
+ kOfficeLeftGraffiti,
+ kOfficeLeftTerminalSmashed,
+ kOfficeLeftDrawerMoney,
+ kOfficeLeftSafeOpen,
+ kOfficeLeftSafeClosed,
+ kOfficeLeftSafeMoney,
+ kOfficeLeftDoorOpen,
+ kOfficeLeftAlienShootAnimation1,
+ kOfficeLeftAlienShootAnimation2,
+ kOfficeLeftAlienShootAnimation3,
+ kOfficeLeftAlienShootAnimation4,
+ kOfficeLeftAlienShootAnimation5,
+ kOfficeLeftAlienShootAnimation6,
+ kOfficeLeftTerminalText,
+ kOfficeLeftDoorClosed,
+ kOfficeLeftDummy1,
+ kOfficeLeftDummy2,
+ kOfficeLeftDummy3,
+ kOfficeLeftDummy4,
+ kOfficeLeftDummy5,
+ // file 8
+ kOfficeRightBackground,
+ kOfficeRightDecorationPictures,
+ kOfficeRightDecorationPlants,
+ kOfficeRightDoorOpen,
+ kOfficeRightTerminalSmashed,
+ kOfficeRightAlienShootAnimation1,
+ kOfficeRightAlienShootAnimation2,
+ kOfficeRightAlienShootAnimation3,
+ kOfficeRightAlienTalking,
+ kOfficeRightDummy1,
+ kOfficeRightDummy2,
+ kOfficeRightDummy3,
+ kOfficeRightDummy4,
+ // file 9
+ kShipCockpitBackground,
+ kShipCockpitPilotAnimation1,
+ kShipCockpitPilotAnimation2,
+ kShipCockpitPilotAnimation3,
+ kShipCockpitPilotAnimation4,
+ kShipCockpitPilotAnimation5,
+ kShipCockpitPilotAnimation6,
+ kShipCockpitPilotAnimation7,
+ kShipCockpitPilotAnimation8,
+ kShipCockpitPilotAnimation9,
+ kShipCockpitPilotAnimation10,
+ kShipCockpitPilotAnimation11,
+ kShipCockpitPilotAnimation12,
+ kShipCockpitPilotAnimation13,
+ kShipCockpitPilotAnimation14,
+ kShipCockpitPilotAnimation15,
+ kShipCockpitPilotAnimation16,
+ kShipCockpitPilotAnimation17,
+ kShipCockpitPilotAnimation18,
+ kShipCockpitPilotAnimation19,
+ kShipCockpitPilotAnimation20,
+ kShipCockpitDisplayStatusAnimation1,
+ kShipCockpitDisplayStatusAnimation2,
+ kShipCockpitWindowRocks,
+ // file 10
+ kRestaurantEntranceBackground,
+ kRestaurantEntrancePorterAnimation1,
+ kRestaurantEntrancePorterAnimation2,
+ kRestaurantEntrancePorterAnimation3,
+ kRestaurantEntrancePorterAnimation4,
+ kRestaurantEntranceBathroomDoorAnimation1,
+ kRestaurantEntranceBathroomDoorAnimation2,
+ kRestaurantEntranceBathroomDoorAnimation3,
+ kRestaurantEntranceBathroomDoorAnimation4,
+ kRestaurantEntranceBathroomDoorAnimation5,
+ kRestaurantEntranceGreenCandy,
+ kRestaurantEntranceBlueCandy,
+ kRestaurantEntrancePinkCandy,
+ kRestaurantEntranceWhiteCandy,
+ kRestaurantEntranceBlackCandy,
+ kRestaurantEntraceDummy1,
+ kRestaurantEntraceDummy2,
+ // file 11
+ kDeathScreen,
+ // file 12
+ kRocksBackground,
+ kRocksRockAnimation1,
+ kRocksRockAnimation2,
+ kRocksRockAnimation3,
+ // file 13
+ kBluePlanetBackground,
+ kBluePlanetShipAnimation1,
+ kBluePlanetShipAnimation2,
+ kBluePlanetShipAnimation3,
+ kBluePlanetShipAnimation4,
+ kBluePlanetShipAnimation5,
+ kBluePlanetShipAnimation6,
+ kBluePlanetShipAnimation7,
+ kBluePlanetShipAnimation8,
+ kBluePlanetShipAnimation9,
+ kBluePlanetShipAnimation10,
+ kBluePlanetShipAnimation11,
+ kBluePlanetShipAnimation12,
+ kBluePlanetShipAnimation13,
+ // file 14
+ kRogerCrashBackground,
+ kRogerCrashAnimation1,
+ kRogerCrashAnimation2,
+ kRogerCrashAnimation3,
+ kRogerCrashAnimation4,
+ kRogerCrashAnimation5,
+ kRogerCrashAnimation6,
+ kRogerCrashAnimation7,
+ kRogerCrashAnimation8,
+ kRogerCrashAnimation9,
+ kRogerCrashAnimation10,
+ kRogerCrashAnimation11,
+ kRogerCrashAnimation12,
+ kRogerCrashAnimation13,
+ kRogerCrashAnimation14,
+ kRogerCrashAnimation15,
+ kRogerCrashAnimation16,
+ kRogerCrashAnimation17,
+ kRogerCrashAnimation18,
+ kRogerCrashAnimation19,
+ // file 15
+ kShipCorridorBackground,
+ kShipCorridorCockpitDoorOpen,
+ kShipCorridorSleepCabinDoorAnimation1,
+ kShipCorridorSleepCabinDoorAnimation2,
+ kShipCorridorSleepCabinDoorAnimation3,
+ kShipCorridorDummy1,
+ // file 16
+ kAxacussCorridorTileWalled,
+ kAxacussCorridorToLeft,
+ kAxacussCorridorToRight,
+ kAxacussCorridorToTop,
+ kAxacussCorridorToBottom,
+ kAxacussCorridorTile,
+ kAxacussCorridorDoorClosed,
+ kAxacussCorridorDoorOpen,
+ kAxacussCorridorDesk,
+ kAxacussCorridorLaptop,
+ kAxacussCorridorStuff10,
+ kAxacussCorridorStuff11,
+ kAxacussCorridorStuff12,
+ kAxacussCorridorStuff13,
+ kAxacussCorridorStuff14,
+ kAxacussCorridorStuff15,
+ kAxacussCorridorStuff16,
+ kAxacussCorridorStuff17,
+ kAxacussCorridorStuff18,
+ kAxacussCorridorStuff19,
+ kAxacussCorridorStuff21,
+ kAxacussCorridorStuff22,
+ kAxacussCorridorStuff23,
+ kAxacussCorridorStuff24,
+ kAxacussCorridorStuff25,
+ kAxacussCorridorStuff26,
+ kAxacussCorridorStuff27,
+ kAxacussCorridorStuff28,
+ kAxacussCorridorAlarmStatus,
+ kAxacussCorridorAlienRight,
+ kAxacussCorridorAlienLeft,
+ kAxacussCorridorAlienBottom,
+ kAxacussCorridorAlienTop,
+ kAxacussCorridorDummy1,
+ // file 17
+ kShipCorridorCabinBackground,
+ kShipCorridorCabinL1Open,
+ kShipCorridorCabinL2Open,
+ kShipCorridorCabinL3Open,
+ kShipCorridorCabinR1Open,
+ kShipCorridorCabinR2Open,
+ kShipCorridorCabinR3Open,
+ kShipCorridorCabinAirlockDoorAnimation1,
+ kShipCorridorCabinAirlockDoorAnimation2,
+ kShipCorridorCabinAirlockDoorAnimation3,
+ kShipCorridorCabinDummy1,
+ kShipCorridorCabinDummy2,
+ kShipCorridorCabinDummy3,
+ kShipCorridorCabinDummy4,
+ kShipCorridorCabinDummy5,
+ kShipCorridorCabinDummy6,
+ // file 18
+ kShipGeneratorBackground,
+ kShipGeneratorHatchOpen,
+ kShipGeneratorJunctionBoxOpen,
+ kShipGeneratorJunctionBoxOffline,
+ kShipGeneratorJunctionBoxDisplay,
+ kShipGeneratorKeycard,
+ kShipGeneratorSpoolFloating,
+ kShipGeneratorSpoolOnGround,
+ kShipGeneratorCableUnplugged,
+ kShipGeneratorCablePluggedIn,
+ kShipGeneratorHatchRocks,
+ kShipGeneratorRopeRocks,
+ kShipGeneratorRopeSpace,
+ kShipGeneratorRopeFloor,
+ kShipGeneratorDummy1,
+ kShipGeneratorDummy2,
+ kShipGeneratorDummy3,
+ kShipGeneratorDummy4,
+ kShipGeneratorDummy5,
+ kShipGeneratorDummy6,
+ kShipGeneratorDummy7,
+ kShipGeneratorDummy8,
+ // file 19
+ kRogerShipBackground,
+ kRogerShipButtonPressed1,
+ kRogerShipButtonPressed2,
+ kRogerShipButtonPressed3,
+ kRogerShipButtonPressed4,
+ kRogerShipCardInSlot,
+ kRogerShipCompartmentOpen,
+ kRogerShipUnknown7,
+ kRogerShipDisplayLeftOn,
+ kRogerShipGreenDisplayAnimation1,
+ kRogerShipGreenDisplayAnimation2,
+ kRogerShipGreenDisplayAnimation3,
+ kRogerShipGreenDisplayAnimation4,
+ kRogerShipGreenDisplayAnimation5,
+ kRogerShipGreenDisplayAnimation6,
+ kRogerShipGreenDisplayAnimation7,
+ kRogerShipBlueDisplayAnimation1,
+ kRogerShipBlueDisplayAnimation2,
+ kRogerShipBlueDisplayAnimation3,
+ kRogerShipBlueDisplayAnimation4,
+ kRogerShipBlueDisplayAnimation5,
+ kRogerShipBlueDisplayAnimation6,
+ kRogerShipBlueDisplayAnimation7,
+ kRogerShipUnknown23,
+ kRogerShipDisplaySinewaveAnimation1,
+ kRogerShipDisplaySinewaveAnimation2,
+ kRogerShipDisplaySinewaveAnimation3,
+ kRogerShipDisplaySinewaveAnimation4,
+ kRogerShipDisplaySinewaveAnimation5,
+ kRogerShipDisplaySinewaveAnimation6,
+ kRogerShipDisplaySinewaveAnimation7,
+ kRogerShipDisplaySinewaveAnimation8,
+ kRogerShipDisplaySinewaveAnimation9,
+ kRogerShipDisplaySinewaveAnimation10,
+ kRogerShipDisplaySinewaveAnimation11,
+ kRogerShipDisplaySinewaveAnimation12,
+ kRogerShipDisplaySinewaveAnimation13,
+ kRogerShipDisplaySinewaveAnimation14,
+ kRogerShipCompartmentContent,
+ kRogerShipDummy1,
+ kRogerShipDummy2,
+ // file 20
+ kHelpScreen,
+ // file 21
+ kShipCabinLeftBackground,
+ kShipCabinLeftPaintingSunset,
+ kShipCabinLeftPaintingLandscape,
+ kShipCabinLeftPaintingAbstract,
+ kShipCabinLeftTableStuff1,
+ kShipCabinLeftCeilingPencil,
+ kShipCabinLeft3Decoration,
+ kShipCabinLeftSocketPluggedIn,
+ kShipCabinLeftVinyl,
+ kShipCabinLeftTurntable,
+ kShipCabinLeftSocketUnplugged,
+ kShipCabinLeftTurntableCableCut,
+ kShipCabinLeftTurntableCable,
+ kShipCabinLeftTurntableAnimation1,
+ kShipCabinLeftTurntableAnimation2,
+ kShipCabinLeftTurntableAnimation3,
+ kShipCabinLeftTableStuff2,
+ kShipCabinLeftLockerOpen,
+ kShipCabinLeftLockerBooksOpen,
+ kShipCabinLeftLockerSpoolOpen,
+ kShipCabinLeftLockerPistolRemoved,
+ kShipCabinLeftLockerSpoolRemoved,
+ kShipCabinLeftBedSafeOpen,
+ kShipCabinLeftBedSafeEmpty,
+ kShipCabinLeftDoorClosed,
+ kShipCabinLeftTurntableCableSparks,
+ kShipCabinLeftTurntableCableCutEnd,
+ kShipCabinLeftDummy1,
+ kShipCabinLeftDummy2,
+ kShipCabinLeftDummy3,
+ kShipCabinLeftDummy4,
+ kShipCabinLeftDummy5,
+ kShipCabinLeftDummy6,
+ kShipCabinLeftDummy7,
+ kShipCabinLeftDummy8,
+ kShipCabinLeftDummy9,
+ kShipCabinLeftDummy10,
+ kShipCabinLeftDummy11,
+ kShipCabinLeftDummy12,
+ // file 22
+ kShipCabinRightBackground,
+ kShipCabinRightPosterSnowman,
+ kShipCabinRightTableStuff,
+ kShipCabinRightCeilingChess,
+ kShipCabinRightTennisRacket,
+ kShipCabinRightTennisBallsFloating,
+ kShipCabinRightTennisBallsOnGround,
+ kShipCabinRightTableChess,
+ kShipCabinRight2Bed,
+ kShipCabinRightLockerBooksOpen,
+ kShipCabinRightLockerRopeOpen,
+ kShipCabinRightLockerOpen,
+ kShipCabinRightLockerRopeRemoved,
+ kShipCabinRightBedSafeOpen,
+ kShipCabinRightBedSafeEmpty,
+ kShipCabinRightDoorClosed,
+ kShipCabinRightLockerDiscmanRemoved,
+ kShipCabinRightDummy1,
+ kShipCabinRightDummy2,
+ // file 23
+ kShipBathroomBackground,
+ // file 24
+ kShipHoldBackgroundFloating,
+ kShipHoldBackgroundOnGround,
+ kShipHoldLandingModuleDoorOpen,
+ kShipHoldGeneratorHatchOpen,
+ kShipHoldLandingModuleSpool,
+ kShipHoldCableToGeneratorUnplugged,
+ kShipHoldCableToGeneratorPluggedIn,
+ kShipHoldDummy1,
+ kShipHoldDummy2,
+ // file 25
+ kShipLandingModuleBackground,
+ kShipLandingModuleDoorClosed,
+ kShipLandingModuleDisplayLeftOn,
+ kShipLandingModuleCablePluggedIn,
+ kShipLandingModuleCableSpoolConnected,
+ kShipLandingModuleCableToHold,
+ kShipLandingModuleDisplayRightOn,
+ kShipLandingModuleDisplayTop1On,
+ kShipLandingModuleDisplayTop2On,
+ kShipLandingModuleDisplayTop3On,
+ kShipLandingModuleCableWithTerminalStrip,
+ kShipLandingModuleDummy1,
+ kShipLandingModuleDummy2,
+ kShipLandingModuleDummy3,
+ kShipLandingModuleDummy4,
+ kShipLandingModuleDummy5,
+ kShipLandingModuleDummy6,
+ kShipLandingModuleDummy7,
+ kShipLandingModuleDummy8,
+ // file 26
+ kArsanoStar,
+ // file 27
+ kSaveLoadScreen,
+ // file 28
+ kRestaurantBackground,
+ kRestaurantAnimation1,
+ kRestaurantAnimation2,
+ kRestaurantAnimation3,
+ kRestaurantAnimation4,
+ kRestaurantAnimation5,
+ kRestaurantAnimation6,
+ kRestaurantAnimation7,
+ kRestaurantAnimation8,
+ kRestaurantAnimation9,
+ kRestaurantAnimation10,
+ kRestaurantAnimation11,
+ kRestaurantAnimation12,
+ kRestaurantAnimation13,
+ kRestaurantAnimation14,
+ kRestaurantAnimation15,
+ kRestaurantAnimation16,
+ kRestaurantAnimation17,
+ kRestaurantAnimation18,
+ kRestaurantAnimation19,
+ kRestaurantAnimation20,
+ kRestaurantAnimation21,
+ kRestaurantAnimation22,
+ // file 29
+ kRestaurantRogerBackground,
+ kRestaurantRogerEyes1Closed,
+ kRestaurantRogerMouthOpen,
+ kRestaurantRogerPlayingChess,
+ kRestaurantRogerWalletRemoved,
+ kRestaurantRogerHandAnimation1,
+ kRestaurantRogerHandAnimation2,
+ kRestaurantRogerHandAnimation3,
+ kRestaurantRogerHandAnimation4,
+ kRestaurantRogerHandAnimation5,
+ kRestaurantRogerEyes2Closed,
+ kRestaurantRogerChessBoard,
+ kRestaurantRogerEyes2Open,
+ kRestaurantRogerDummy1,
+ // file 30
+ kRogerOutsideBackground,
+ kRogerOutsideMouthOpen,
+ // file 31
+ kIntroScreenBackground,
+ kIntroScreenShipAnimation1,
+ kIntroScreenShipAnimation2,
+ kIntroScreenShipAnimation3,
+ kIntroScreenShipAnimation4,
+ kIntroScreenShipAnimation5,
+ kIntroScreenShipAnimation6,
+ // file 32
+ kBusStationSignBackground,
+ kBusStationSignPrice,
+ kBusStationSignPleaseWait,
+ kBusStationSignPleasantFlight,
+ // file 33
+ kShipSleepCabinBackground,
+ kShipSleepCabinTerminalWarning,
+ kShipSleepCabinTerminal1,
+ kShipSleepCabinTerminal2,
+ kShipSleepCabinStatusLight,
+ kShipSleepCabinTerminal3,
+ // file 34
+ kShipAirlockBackground,
+ kShipAirlockDoorLeftAnimation1,
+ kShipAirlockDoorLeftAnimation2,
+ kShipAirlockDoorLeftAnimation3,
+ kShipAirlockDoorRightAnimation1,
+ kShipAirlockDoorRightAnimation2,
+ kShipAirlockDoorRightAnimation3,
+ kShipAirlockHelmetRemoved,
+ kShipAirlockSpacesuitRemoved,
+ kShipAirlockSupplyRemoved,
+ kShipAirlockDoorLeftButton,
+ kShipAirlockDoorRightButton,
+ kShipAirlockManometerAnimation1,
+ kShipAirlockManometerAnimation2,
+ kShipAirlockManometerAnimation3,
+ kShipAirlockManometerAnimation4,
+ kShipAirlockManometerAnimation5,
+ kShipAirlockManometerAnimation6,
+ // file 35
+ kAxacussSpaceBackground,
+ kAxacussSpaceShipAnimation1,
+ kAxacussSpaceShipAnimation2,
+ kAxacussSpaceShipAnimation3,
+ kAxacussSpaceShipAnimation4,
+ kAxacussSpaceShipAnimation5,
+ kAxacussSpaceShipAnimation6,
+ kAxacussSpaceShipAnimation7,
+ kAxacussSpaceBusAnimation1,
+ kAxacussSpaceBusAnimation2,
+ kAxacussSpaceBusAnimation3,
+ kAxacussSpaceBusAnimation4,
+ kAxacussSpaceBusAnimation5,
+ kAxacussSpaceBusAnimation6,
+ kAxacussSpaceBusAnimation7,
+ kAxacussSpaceBusAnimation8,
+ kAxacussSpaceBusAnimation9,
+ kAxacussSpaceBusAnimation10,
+ kAxacussSpaceBusAnimation11,
+ kAxacussSpaceBusAnimation12,
+ kAxacussSpaceBusAnimation13,
+ kAxacussSpaceBusAnimation14,
+ // file 36
+ kAxacussanCapsuleBackground,
+ kAxacussanCapsuleRobotAnimation1,
+ kAxacussanCapsuleRobotAnimation2,
+ kAxacussanCapsuleRobotAnimation3,
+ kAxacussanCapsuleRobotAnimation4,
+ kAxacussanCapsuleDummy1,
+ // file 37
+ kArsanoMeetupBackground,
+ kArsanoMeetupRestaurantLightAnimation1,
+ kArsanoMeetupRestaurantLightAnimation2,
+ kArsanoMeetupRestaurantLightAnimation3,
+ kArsanoMeetupRestaurantLightAnimation4,
+ kArsanoMeetupRestaurantLightAnimation5,
+ kArsanoMeetupRestaurantDoorAnimation1,
+ kArsanoMeetupRestaurantDoorAnimation2,
+ kArsanoMeetupRestaurantDoorSignAnimation1,
+ kArsanoMeetupRestaurantDoorSignAnimation2,
+ kArsanoMeetupRestaurantDoorSignAnimation3,
+ kArsanoMeetupRestaurantDoorSignAnimation4,
+ kArsanoMeetupRestaurantDoorSignAnimation5,
+ kArsanoMeetupRestaurantSignAnimation1,
+ kArsanoMeetupRestaurantSignAnimation2,
+ kArsanoMeetupRestaurantSignAnimation3,
+ kArsanoMeetupRestaurantSignAnimation4,
+ kArsanoMeetupRestaurantSignAnimation5,
+ kArsanoMeetupRestaurantSignAnimation6,
+ kArsanoMeetupRestaurantSignAnimation7,
+ kArsanoMeetupRestaurantSignAnimation8,
+ kArsanoMeetupRestaurantSignAnimation9,
+ kArsanoMeetupRestaurantSignAnimation10,
+ kArsanoMeetupRestaurantSignAnimation11,
+ kArsanoMeetupRestaurantSignAnimation12,
+ kArsanoMeetupRestaurantSignAnimation13,
+ kArsanoMeetupRestaurantSignAnimation14,
+ // file 38
+ kArsanoAfterNovaBackground,
+ kArsanoAfterNovaRogerShipAnimation1,
+ kArsanoAfterNovaRogerShipAnimation2,
+ kArsanoAfterNovaRogerShipAnimation3,
+ kArsanoAfterNovaRogerShipAnimation4,
+ kArsanoAfterNovaRogerShipAnimation5,
+ kArsanoAfterNovaRogerShipAnimation6,
+ kArsanoAfterNovaRogerShipAnimation7,
+ kArsanoAfterNovaRogerShipAnimation8,
+ kArsanoAfterNovaRogerShipAnimation9,
+ kArsanoAfterNovaRogerShipAnimation10,
+ kArsanoAfterNovaRogerShipAnimation11,
+ kArsanoAfterNovaRoger,
+ // file 39
+ kArsanoDesolate,
+ // file 40
+ kIntersectionBackground,
+ kIntersectionGuardRemoved,
+ kIntersectionGuardMouthOpen,
+ kIntersectionGuardShootAnimation1,
+ kIntersectionGuardShootAnimation2,
+ kIntersectionGuardMouthClosed,
+ kIntersectionDoorOpen,
+ kIntersectoinKeycard,
+ // file 41
+ kInformationDeskBackground,
+ kInformationDeskAlienMouthOpen,
+ kInformationDeskAlienHandMoved,
+ kInformationDeskAlienShoot,
+ // file 42
+ kArtGalleryBackground,
+ kArtGalleryAlienShootAnimation1,
+ kArtGalleryAlienShootAnimation2,
+ kArtGalleryAlienShootAnimation3,
+ kArtGalleryThrowingBlockAnimation1,
+ kArtGalleryThrowingBlockAnimation2,
+ kArtGalleryThrowingBlockAnimation3,
+ kArtGalleryThrowingBlockAnimation4,
+ kArtGalleryThrowingBlockAnimation5,
+ kArtGalleryThrowingBlockAnimation6,
+ kArtGalleryThrowingBlockAnimation7,
+ kArtGalleryDummy1,
+ // file 43
+ kCellBackground,
+ kCellCablePluggedIn,
+ kCellCableUnplugged,
+ kCellCableCutUnplugged,
+ kCellCableCutPluggedIn,
+ kCellCableCutTableUnplugged,
+ kCellCableCutTablePluggedIn,
+ kCellTableTablet,
+ kCellRobotComesAnimation1,
+ kCellRobotComesAnimation2,
+ kCellRobotComesAnimation3,
+ kCellRobotComesAnimation4,
+ kCellRobotComesAnimation5,
+ kCellRobotComesAnimation6,
+ kCellRobotComesAnimation7,
+ kCellRobotComesAnimation8,
+ kCellRobotComesAnimation9,
+ kCellRobotComesAnimation10,
+ kCellRobotComesAnimation11,
+ kCellRobotLeavesAnimation1,
+ kCellRobotLeavesAnimation2,
+ kCellRobotLeavesAnimation3,
+ kCellRobotLeavesAnimation4,
+ kCellRobotLeavesAnimation5,
+ kCellRobotLeavesAnimation6,
+ kCellRobotLeavesAnimation7,
+ kCellRobotLeavesAnimation8,
+ kCellRobotLeavesAnimation9,
+ kCellRobotSparks,
+ kCellRobotBroken,
+ kCellDoorClosed,
+ kCellDummy1
+};
+
+}
+
+#endif
diff --git a/engines/supernova/module.mk b/engines/supernova/module.mk
index 9baf196c7c..722a230cde 100644
--- a/engines/supernova/module.mk
+++ b/engines/supernova/module.mk
@@ -4,9 +4,12 @@ MODULE_OBJS := \
console.o \
detection.o \
graphics.o \
- supernova.o \
+ resman.o \
rooms.o \
- state.o
+ screen.o \
+ sound.o \
+ state.o \
+ supernova.o
MODULE_DIRS += \
engines/supernova
diff --git a/engines/supernova/msn_def.h b/engines/supernova/msn_def.h
index c18baa068c..6ce16b8283 100644
--- a/engines/supernova/msn_def.h
+++ b/engines/supernova/msn_def.h
@@ -25,10 +25,6 @@
namespace Supernova {
-const int kScreenWidth = 320;
-const int kScreenHeight = 200;
-const int kFontWidth = 5;
-const int kFontHeight = 8;
const int kTextSpeed[] = {19, 14, 10, 7, 4};
const int kMsecPerTick = 55;
@@ -50,266 +46,6 @@ enum MessagePosition {
kMessageTop
};
-enum AudioIndex {
- kAudioFoundLocation, // 44|0
- kAudioCrash, // 45|0
- kAudioVoiceHalt, // 46|0
- kAudioGunShot, // 46|2510
- kAudioSmash, // 46|4020
- kAudioVoiceSupernova, // 47|0
- kAudioVoiceYeah, // 47|24010
- kAudioRobotShock, // 48|0
- kAudioRobotBreaks, // 48|2510
- kAudioShock, // 48|10520
- kAudioTurntable, // 48|13530
- kAudioSiren, // 50|0
- kAudioSnoring, // 50|12786
- kAudioRocks, // 51|0
- kAudioDeath, // 53|0
- kAudioAlarm, // 54|0
- kAudioSuccess, // 54|8010
- kAudioSlideDoor, // 54|24020
- kAudioDoorOpen, // 54|30030
- kAudioDoorClose, // 54|31040
- kAudioNumSamples
-};
-
-enum MusicIndex {
- kMusicIntro = 52,
- kMusicOutro = 49
-};
-
-struct AudioInfo {
- int _filenumber;
- int _offsetStart;
- int _offsetEnd;
-};
-
-const int kColorBlack = 0;
-const int kColorWhite25 = 1;
-const int kColorWhite35 = 2;
-const int kColorWhite44 = 3;
-const int kColorWhite99 = 4;
-const int kColorDarkGreen = 5;
-const int kColorGreen = 6;
-const int kColorDarkRed = 7;
-const int kColorRed = 8;
-const int kColorDarkBlue = 9;
-const int kColorBlue = 10;
-const int kColorWhite63 = 11;
-const int kColorLightBlue = 12;
-const int kColorLightGreen = 13;
-const int kColorLightYellow = 14;
-const int kColorLightRed = 15;
-const int kColorCursorTransparent = kColorWhite25;
-
-const byte mouseNormal[64] = {
- 0xff,0x3f,0xff,0x1f,0xff,0x0f,0xff,0x07,
- 0xff,0x03,0xff,0x01,0xff,0x00,0x7f,0x00,
- 0x3f,0x00,0x1f,0x00,0x0f,0x00,0x0f,0x00,
- 0xff,0x00,0x7f,0x18,0x7f,0x38,0x7f,0xfc,
-
- 0x00,0x00,0x00,0x40,0x00,0x60,0x00,0x70,
- 0x00,0x78,0x00,0x7c,0x00,0x7e,0x00,0x7f,
- 0x80,0x7f,0xc0,0x7f,0xe0,0x7f,0x00,0x7e,
- 0x00,0x66,0x00,0x43,0x00,0x03,0x00,0x00
-};
-
-const byte mouseWait[64] = {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,
- 0x01,0x80,0x01,0x80,0x11,0x88,0x31,0x8c,
- 0x31,0x8c,0x11,0x88,0x01,0x80,0x01,0x80,
- 0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0xfe,0x7f,0xf4,0x2f,0xf4,0x2f,
- 0x14,0x28,0x24,0x24,0x44,0x22,0x84,0x21,
- 0x84,0x21,0xc4,0x23,0xe4,0x27,0x74,0x2e,
- 0x34,0x2c,0x14,0x28,0xfe,0x7f,0x00,0x00
-};
-
-const byte font[][5] = {
- {0x00,0x00,0x00,0xff,0x00},
- {0x5f,0xff,0x00,0x00,0x00},
- {0x03,0x00,0x03,0xff,0x00},
- {0x14,0x7f,0x14,0x7f,0x14},
- {0x24,0x2a,0x7f,0x2a,0x12},
- {0x61,0x10,0x08,0x04,0x43},
- {0x38,0x4e,0x59,0x26,0x50},
- {0x03,0xff,0x00,0x00,0x00},
- {0x3e,0x41,0xff,0x00,0x00},
- {0x41,0x3e,0xff,0x00,0x00},
- {0x10,0x54,0x38,0x54,0x10},
- {0x10,0x10,0x7c,0x10,0x10},
- {0x80,0x40,0xff,0x00,0x00},
- {0x10,0x10,0x10,0x10,0x10},
- {0x40,0xff,0x00,0x00,0x00},
- {0x60,0x10,0x08,0x04,0x03},
-
- {0x3e,0x41,0x41,0x41,0x3e}, /* digits */
- {0x04,0x02,0x7f,0xff,0x00},
- {0x42,0x61,0x51,0x49,0x46},
- {0x22,0x41,0x49,0x49,0x36},
- {0x18,0x14,0x12,0x7f,0x10},
- {0x27,0x45,0x45,0x45,0x39},
- {0x3e,0x49,0x49,0x49,0x32},
- {0x01,0x61,0x19,0x07,0x01},
- {0x36,0x49,0x49,0x49,0x36},
- {0x26,0x49,0x49,0x49,0x3e},
-
- {0x44,0xff,0x00,0x00,0x00},
- {0x80,0x44,0xff,0x00,0x00},
- {0x10,0x28,0x44,0xff,0x00},
- {0x28,0x28,0x28,0x28,0x28},
- {0x44,0x28,0x10,0xff,0x00},
- {0x02,0x01,0x51,0x09,0x06},
- {0x3e,0x41,0x5d,0x5d,0x1e},
-
- {0x7c,0x12,0x11,0x12,0x7c}, /* uppercase letters*/
- {0x7f,0x49,0x49,0x49,0x36},
- {0x3e,0x41,0x41,0x41,0x22},
- {0x7f,0x41,0x41,0x22,0x1c},
- {0x7f,0x49,0x49,0x49,0xff},
- {0x7f,0x09,0x09,0x09,0xff},
- {0x3e,0x41,0x41,0x49,0x3a},
- {0x7f,0x08,0x08,0x08,0x7f},
- {0x41,0x7f,0x41,0xff,0x00},
- {0x20,0x40,0x40,0x3f,0xff},
- {0x7f,0x08,0x14,0x22,0x41},
- {0x7f,0x40,0x40,0x40,0xff},
- {0x7f,0x02,0x04,0x02,0x7f},
- {0x7f,0x02,0x0c,0x10,0x7f},
- {0x3e,0x41,0x41,0x41,0x3e},
- {0x7f,0x09,0x09,0x09,0x06},
- {0x3e,0x41,0x51,0x21,0x5e},
- {0x7f,0x09,0x19,0x29,0x46},
- {0x26,0x49,0x49,0x49,0x32},
- {0x01,0x01,0x7f,0x01,0x01},
- {0x3f,0x40,0x40,0x40,0x3f},
- {0x07,0x18,0x60,0x18,0x07},
- {0x1f,0x60,0x18,0x60,0x1f},
- {0x63,0x14,0x08,0x14,0x63},
- {0x03,0x04,0x78,0x04,0x03},
- {0x61,0x51,0x49,0x45,0x43},
-
- {0x7f,0x41,0x41,0xff,0x00},
- {0x03,0x04,0x08,0x10,0x60},
- {0x41,0x41,0x7f,0xff,0x00},
- {0x02,0x01,0x02,0xff,0x00},
- {0x80,0x80,0x80,0x80,0x80},
- {0x01,0x02,0xff,0x00,0x00},
-
- {0x38,0x44,0x44,0x44,0x7c}, /* lowercase letters */
- {0x7f,0x44,0x44,0x44,0x38},
- {0x38,0x44,0x44,0x44,0x44},
- {0x38,0x44,0x44,0x44,0x7f},
- {0x38,0x54,0x54,0x54,0x58},
- {0x04,0x7e,0x05,0x01,0xff},
- {0x98,0xa4,0xa4,0xa4,0x7c},
- {0x7f,0x04,0x04,0x04,0x78},
- {0x7d,0xff,0x00,0x00,0x00},
- {0x80,0x80,0x7d,0xff,0x00},
- {0x7f,0x10,0x28,0x44,0xff},
- {0x7f,0xff,0x00,0x00,0x00},
- {0x7c,0x04,0x7c,0x04,0x78},
- {0x7c,0x04,0x04,0x04,0x78},
- {0x38,0x44,0x44,0x44,0x38},
- {0xfc,0x24,0x24,0x24,0x18},
- {0x18,0x24,0x24,0x24,0xfc},
- {0x7c,0x08,0x04,0x04,0xff},
- {0x48,0x54,0x54,0x54,0x24},
- {0x04,0x3e,0x44,0x40,0xff},
- {0x7c,0x40,0x40,0x40,0x3c},
- {0x0c,0x30,0x40,0x30,0x0c},
- {0x3c,0x40,0x3c,0x40,0x3c},
- {0x44,0x28,0x10,0x28,0x44},
- {0x9c,0xa0,0xa0,0xa0,0x7c},
- {0x44,0x64,0x54,0x4c,0x44},
-
- {0x08,0x36,0x41,0xff,0x00},
- {0x77,0xff,0x00,0x00,0x00},
- {0x41,0x36,0x08,0xff,0x00},
- {0x02,0x01,0x02,0x01,0xff},
- {0xff,0x00,0x00,0x00,0x00},
-
- {0xfe,0x49,0x49,0x4e,0x30}, /* sharp S */
-
- {0x7c,0x41,0x40,0x41,0x3c}, /* umlauts */
-
- {0x04,0x06,0x7f,0x06,0x04}, /* arrows */
- {0x20,0x60,0xfe,0x60,0x20},
-
- {0x38,0x45,0x44,0x45,0x7c}, /* umlauts */
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0x79,0x14,0x12,0x14,0x79},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0x38,0x45,0x44,0x45,0x38},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0xff,0x00,0x00,0x00,0x00},
- {0x3d,0x42,0x42,0x42,0x3d},
- {0x3d,0x40,0x40,0x40,0x3d},
-};
-
-// Default palette
-const byte initVGAPalette[768] = {
- 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x58, 0x58, 0x58, 0x70, 0x70, 0x70, 0xfc, 0xfc, 0xfc, 0x00, 0xd0, 0x00,
- 0x00, 0xfc, 0x00, 0xd8, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xb0, 0xa0, 0xa0, 0xa0,
- 0x50, 0xc8, 0xfc, 0x28, 0xfc, 0x28, 0xf0, 0xf0, 0x00, 0xfc, 0x28, 0x28, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14,
- 0x20, 0x20, 0x20, 0x2c, 0x2c, 0x2c, 0x38, 0x38, 0x38, 0x44, 0x44, 0x44, 0x50, 0x50, 0x50, 0x60, 0x60, 0x60,
- 0x70, 0x70, 0x70, 0x80, 0x80, 0x80, 0x90, 0x90, 0x90, 0xa0, 0xa0, 0xa0, 0xb4, 0xb4, 0xb4, 0xc8, 0xc8, 0xc8,
- 0xe0, 0xe0, 0xe0, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00, 0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc,
- 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc, 0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00,
- 0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc, 0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x00,
- 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00, 0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc,
- 0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c, 0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc,
- 0xfc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc, 0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c,
- 0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc, 0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0x7c,
- 0x7c, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c, 0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc,
- 0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4, 0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc,
- 0xfc, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc, 0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4,
- 0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc, 0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0xb4,
- 0xb4, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4, 0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc,
- 0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70,
- 0x70, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70, 0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x00, 0x00, 0x70, 0x1c, 0x00,
- 0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70, 0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x00,
- 0x00, 0x70, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70,
- 0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38, 0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70,
- 0x70, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70, 0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38,
- 0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70, 0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x38,
- 0x38, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38, 0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70,
- 0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50, 0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70,
- 0x70, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70, 0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50,
- 0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70, 0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x50,
- 0x50, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50, 0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70,
- 0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x00, 0x00, 0x40, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40,
- 0x40, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40, 0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x00, 0x00, 0x40, 0x10, 0x00,
- 0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40, 0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x00,
- 0x00, 0x40, 0x00, 0x00, 0x40, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40,
- 0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20, 0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40,
- 0x40, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40, 0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20,
- 0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40, 0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x20,
- 0x20, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20, 0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40,
- 0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c, 0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40,
- 0x40, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40, 0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c,
- 0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40, 0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x2c,
- 0x2c, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c, 0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40,
- 0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
enum ObjectType {
NULLTYPE = 0,
TAKE = 1,
@@ -341,7 +77,7 @@ enum Action {
ACTION_GIVE
};
-enum RoomID {
+enum RoomId {
INTRO,CORRIDOR,HALL,SLEEP,COCKPIT,AIRLOCK,
HOLD,LANDINGMODULE,GENERATOR,OUTSIDE,
CABIN_R1,CABIN_R2,CABIN_R3,CABIN_L1,CABIN_L2,CABIN_L3,BATHROOM,
@@ -353,7 +89,7 @@ enum RoomID {
ELEVATOR,STATION,SIGN,OUTRO,NUMROOMS,NULLROOM
};
-enum ObjectID {
+enum ObjectId {
INVALIDOBJECT = -1,
NULLOBJECT = 0,
KEYCARD,KNIFE,WATCH,
@@ -397,7 +133,7 @@ enum ObjectID {
JUNGLE,STATION_SLOT,STATION_SIGN
};
-enum StringID {
+enum StringId {
kNoString = -1,
// 0
kStringCommandGo = 0, kStringCommandLook, kStringCommandTake, kStringCommandOpen, kStringCommandClose,
@@ -568,8 +304,6 @@ ObjectType &operator&=(ObjectType &a, ObjectType b);
ObjectType &operator^=(ObjectType &a, ObjectType b);
struct Object {
- static const Object nullObject;
-
Object()
: _name(kNoString)
, _description(kStringDefaultDescription)
@@ -582,8 +316,8 @@ struct Object {
, _exitRoom(NULLROOM)
, _direction(0)
{}
- Object(byte roomId, StringID name, StringID description, ObjectID id, ObjectType type,
- byte click, byte click2, byte section = 0, RoomID exitRoom = NULLROOM, byte direction = 0)
+ Object(byte roomId, StringId name, StringId description, ObjectId id, ObjectType type,
+ byte click, byte click2, byte section = 0, RoomId exitRoom = NULLROOM, byte direction = 0)
: _name(name)
, _description(description)
, _id(id)
@@ -596,12 +330,6 @@ struct Object {
, _direction(direction)
{}
- static void setObjectNull(Object *&obj) {
- obj = const_cast<Object *>(&nullObject);
- }
- static bool isNullObject(Object *obj) {
- return obj == &nullObject;
- }
void resetProperty(ObjectType type = NULLTYPE) {
_type = type;
}
@@ -618,7 +346,7 @@ struct Object {
return _type & type;
}
- static bool combine(Object &obj1, Object &obj2, ObjectID id1, ObjectID id2) {
+ static bool combine(Object &obj1, Object &obj2, ObjectId id1, ObjectId id2) {
if (obj1.hasProperty(COMBINABLE))
return (((obj1._id == id1) && (obj2._id == id2)) ||
((obj1._id == id2) && (obj2._id == id1)));
@@ -627,14 +355,14 @@ struct Object {
}
byte _roomId;
- StringID _name;
- StringID _description;
- ObjectID _id;
+ StringId _name;
+ StringId _description;
+ ObjectId _id;
ObjectTypes _type;
byte _click;
byte _click2;
byte _section;
- RoomID _exitRoom;
+ RoomId _exitRoom;
byte _direction;
};
diff --git a/engines/supernova/resman.cpp b/engines/supernova/resman.cpp
new file mode 100644
index 0000000000..1c178846ed
--- /dev/null
+++ b/engines/supernova/resman.cpp
@@ -0,0 +1,395 @@
+/* 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 "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+#include "audio/mixer.h"
+#include "audio/mods/protracker.h"
+#include "common/memstream.h"
+#include "common/system.h"
+#include "graphics/cursorman.h"
+#include "graphics/palette.h"
+
+#include "supernova/graphics.h"
+#include "supernova/resman.h"
+#include "supernova/screen.h"
+#include "supernova/supernova.h"
+
+namespace Supernova {
+
+struct AudioInfo {
+ int _filenumber;
+ int _offsetStart;
+ int _offsetEnd;
+};
+
+static Common::MemoryReadStream *convertToMod(const char *filename, int version = 1);
+
+static const AudioInfo audioInfo[kAudioNumSamples] = {
+ {44, 0, -1},
+ {45, 0, -1},
+ {46, 0, 2510},
+ {46, 2510, 4020},
+ {46, 4020, -1},
+ {47, 0, 24010},
+ {47, 24010, -1},
+ {48, 0, 2510},
+ {48, 2510, 10520},
+ {48, 10520, 13530},
+ {48, 13530, -1},
+ {50, 0, 12786},
+ {50, 12786, -1},
+ {51, 0, -1},
+ {53, 0, -1},
+ {54, 0, 8010},
+ {54, 8010, 24020},
+ {54, 24020, 30030},
+ {54, 30030, 31040},
+ {54, 31040, -1}
+};
+
+static const byte mouseNormal[64] = {
+ 0xff,0x3f,0xff,0x1f,0xff,0x0f,0xff,0x07,
+ 0xff,0x03,0xff,0x01,0xff,0x00,0x7f,0x00,
+ 0x3f,0x00,0x1f,0x00,0x0f,0x00,0x0f,0x00,
+ 0xff,0x00,0x7f,0x18,0x7f,0x38,0x7f,0xfc,
+
+ 0x00,0x00,0x00,0x40,0x00,0x60,0x00,0x70,
+ 0x00,0x78,0x00,0x7c,0x00,0x7e,0x00,0x7f,
+ 0x80,0x7f,0xc0,0x7f,0xe0,0x7f,0x00,0x7e,
+ 0x00,0x66,0x00,0x43,0x00,0x03,0x00,0x00
+};
+
+static const byte mouseWait[64] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,
+ 0x01,0x80,0x01,0x80,0x11,0x88,0x31,0x8c,
+ 0x31,0x8c,0x11,0x88,0x01,0x80,0x01,0x80,
+ 0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0xfe,0x7f,0xf4,0x2f,0xf4,0x2f,
+ 0x14,0x28,0x24,0x24,0x44,0x22,0x84,0x21,
+ 0x84,0x21,0xc4,0x23,0xe4,0x27,0x74,0x2e,
+ 0x34,0x2c,0x14,0x28,0xfe,0x7f,0x00,0x00
+};
+
+
+ResourceManager::ResourceManager()
+ : _audioRate(11931) {
+ initSoundFiles();
+ initGraphics();
+}
+
+void ResourceManager::initSoundFiles() {
+ // Sound
+ // Note:
+ // - samples start with a header of 6 bytes: 01 SS SS 00 AD 00
+ // where SS SS (LE uint16) is the size of the sound sample + 2
+ // - samples end with a footer of 4 bytes: 00 00
+ // Skip those in the buffer
+ Common::File file;
+
+ for (int i = 0; i < kAudioNumSamples; ++i) {
+ if (!file.open(Common::String::format("msn_data.%03d", audioInfo[i]._filenumber))) {
+ error("File %s could not be read!", file.getName());
+ }
+
+ int length = 0;
+ byte *buffer = nullptr;
+
+ if (audioInfo[i]._offsetEnd == -1) {
+ file.seek(0, SEEK_END);
+ length = file.pos() - audioInfo[i]._offsetStart - 10;
+ } else {
+ length = audioInfo[i]._offsetEnd - audioInfo[i]._offsetStart - 10;
+ }
+ buffer = new byte[length];
+ file.seek(audioInfo[i]._offsetStart + 6);
+ file.read(buffer, length);
+ file.close();
+
+ byte streamFlag = Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN;
+ _soundSamples[i].reset(Audio::makeRawStream(buffer, length, _audioRate,
+ streamFlag, DisposeAfterUse::YES));
+ }
+
+ _musicIntroBuffer.reset(convertToMod("msn_data.052"));
+ _musicOutroBuffer.reset(convertToMod("msn_data.049"));
+}
+
+void ResourceManager::initGraphics() {
+ Screen::initPalette();
+ initCursorGraphics();
+ initImages();
+}
+
+void ResourceManager::initCursorGraphics() {
+ const uint16 *bufferNormal = reinterpret_cast<const uint16 *>(mouseNormal);
+ const uint16 *bufferWait = reinterpret_cast<const uint16 *>(mouseWait);
+ for (uint i = 0; i < sizeof(mouseNormal) / 4; ++i) {
+ for (uint bit = 0; bit < 16; ++bit) {
+ uint mask = 0x8000 >> bit;
+ uint bitIndex = i * 16 + bit;
+
+ _cursorNormal[bitIndex] = (READ_LE_UINT16(bufferNormal + i) & mask) ?
+ kColorCursorTransparent : kColorBlack;
+ if (READ_LE_UINT16(bufferNormal + i + 16) & mask)
+ _cursorNormal[bitIndex] = kColorLightRed;
+
+ _cursorWait[bitIndex] = (READ_LE_UINT16(bufferWait + i) & mask) ?
+ kColorCursorTransparent : kColorBlack;
+ if (READ_LE_UINT16(bufferWait + i + 16) & mask)
+ _cursorWait[bitIndex] = kColorLightRed;
+ }
+ }
+}
+
+void ResourceManager::initImages() {
+ for (int i = 0; i < kNumImageFiles; ++i) {
+ if (!_images[i].init(i))
+ error("Failed reading image file msn_data.%03d", i);
+ }
+}
+
+Audio::SeekableAudioStream *ResourceManager::getSoundStream(AudioId index) {
+ Audio::SeekableAudioStream *stream = _soundSamples[index].get();
+ stream->rewind();
+
+ return stream;
+}
+
+Audio::AudioStream *ResourceManager::getSoundStream(MusicId index) {
+ switch (index) {
+ case kMusicIntro:
+ _musicIntro.reset(Audio::makeProtrackerStream(_musicIntroBuffer.get()));
+ return _musicIntro.get();
+ case kMusicOutro:
+ _musicOutro.reset(Audio::makeProtrackerStream(_musicOutroBuffer.get()));
+ return _musicOutro.get();
+ default:
+ error("Invalid music constant in playAudio()");
+ }
+}
+
+const MSNImage *ResourceManager::getImage(int filenumber) const {
+ assert(filenumber < kNumImageFiles);
+
+ return &_images[filenumber];
+}
+
+const byte *ResourceManager::getImage(CursorId id) const {
+ switch (id) {
+ case kCursorNormal:
+ return _cursorNormal;
+ case kCursorWait:
+ return _cursorWait;
+ default:
+ return nullptr;
+ }
+}
+
+static Common::MemoryReadStream *convertToMod(const char *filename, int version) {
+ // MSN format
+ struct {
+ uint16 seg;
+ uint16 start;
+ uint16 end;
+ uint16 loopStart;
+ uint16 loopEnd;
+ char volume;
+ char dummy[5];
+ } instr2[22];
+ int nbInstr2; // 22 for version1, 15 for version 2
+ int16 songLength;
+ char arrangement[128];
+ int16 patternNumber;
+ int32 note2[28][64][4];
+
+ nbInstr2 = ((version == 1) ? 22 : 15);
+
+ Common::File msnFile;
+ msnFile.open(filename);
+ if (!msnFile.isOpen()) {
+ warning("Data file '%s' not found", msnFile.getName());
+ return nullptr;
+ }
+
+ for (int i = 0 ; i < nbInstr2 ; ++i) {
+ instr2[i].seg = msnFile.readUint16LE();
+ instr2[i].start = msnFile.readUint16LE();
+ instr2[i].end = msnFile.readUint16LE();
+ instr2[i].loopStart = msnFile.readUint16LE();
+ instr2[i].loopEnd = msnFile.readUint16LE();
+ instr2[i].volume = msnFile.readByte();
+ msnFile.read(instr2[i].dummy, 5);
+ }
+ songLength = msnFile.readSint16LE();
+ msnFile.read(arrangement, 128);
+ patternNumber = msnFile.readSint16LE();
+ for (int p = 0 ; p < patternNumber ; ++p) {
+ for (int n = 0 ; n < 64 ; ++n) {
+ for (int k = 0 ; k < 4 ; ++k) {
+ note2[p][n][k] = msnFile.readSint32LE();
+ }
+ }
+ }
+
+ /* MOD format */
+ struct {
+ char iname[22];
+ uint16 length;
+ char finetune;
+ char volume;
+ uint16 loopStart;
+ uint16 loopLength;
+ } instr[31];
+ int32 note[28][64][4];
+
+ // We can't recover some MOD effects since several of them are mapped to 0.
+ // Assume the MSN effect of value 0 is Arpeggio (MOD effect of value 0).
+ const char invConvEff[8] = {0, 1, 2, 3, 10, 12, 13 ,15};
+
+ // Reminder from convertToMsn
+ // 31 30 29 28 27 26 25 24 - 23 22 21 20 19 18 17 16 - 15 14 13 12 11 10 09 08 - 07 06 05 04 03 02 01 00
+ // h h h h g g g g f f f f e e e e d d d d c c c c b b b b a a a a
+ //
+ // MSN:
+ // hhhh (4 bits) Cleared to 0
+ // dddd c (5 bits) Sample index | after mapping through convInstr
+ // ccc (3 bits) Effect type | after mapping through convEff
+ // bbbb aaaa (8 bits) Effect value | unmodified
+ // gggg ffff eeee (12 bits) Sample period | unmodified
+ //
+ // MS2:
+ // hhhh (4 bits) Cleared to 0
+ // dddd (4 bits) Sample index | after mapping through convInstr
+ // cccc (4 bits) Effect type | unmodified
+ // bbbb aaaa (8 bits) Effect value | unmodified
+ // gggg ffff eeee (12 bits) Sample period | transformed (0xE000 / p) - 256
+ //
+ // MOD:
+ // hhhh dddd (8 bits) Sample index
+ // cccc (4 bits) Effect type for this channel/division
+ // bbbb aaaa (8 bits) Effect value
+ // gggg ffff eeee (12 bits) Sample period
+
+ // Can we recover the instruments mapping? I don't think so as part of the original instrument index is cleared.
+ // And it doesn't really matter as long as we are consistent.
+ // However we need to make sure 31 (or 15 in MS2) is mapped to 0 in MOD.
+ // We just add 1 to all other values, and this means a 1 <-> 1 mapping for the instruments
+ for (int p = 0; p < patternNumber; ++p) {
+ for (int n = 0; n < 64; ++n) {
+ for (int k = 0; k < 4; ++k) {
+ int32* l = &(note[p][n][k]);
+ *l = note2[p][n][k];
+ int32 i = 0;
+ if (nbInstr2 == 22) { // version 1
+ i = ((*l & 0xF800) >> 11);
+ int32 e = ((*l & 0x0700) >> 8);
+ int32 e1 = invConvEff[e];
+ *l &= 0x0FFF00FF;
+ *l |= (e1 << 8);
+ } else { // version 2
+ int32 h = (*l >> 16);
+ i = ((*l & 0xF000) >> 12);
+ *l &= 0x00000FFF;
+ if (h)
+ h = 0xE000 / (h + 256);
+ *l |= (h << 16);
+ if (i == 15)
+ i = 31;
+ }
+
+ // Add back index in note
+ if (i != 31) {
+ ++i;
+ *l |= ((i & 0x0F) << 12);
+ *l |= ((i & 0xF0) << 24);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < 31; ++i) {
+ // iname is not stored in the mod file. Just set it to 'instrument#'
+ // finetune is not stored either. Assume 0.
+ memset(instr[i].iname, 0, 22);
+ sprintf(instr[i].iname, "instrument%d", i+1);
+ instr[i].length = 0;
+ instr[i].finetune = 0;
+ instr[i].volume = 0;
+ instr[i].loopStart = 0;
+ instr[i].loopLength = 0;
+
+ if (i < nbInstr2) {
+ instr[i].length = ((instr2[i].end - instr2[i].start) >> 1);
+ instr[i].loopStart = ((instr2[i].loopStart - instr2[i].start) >> 1);
+ instr[i].loopLength = (( instr2[i].loopEnd - instr2[i].loopStart) >> 1);
+ instr[i].volume = instr2[i].volume;
+ }
+ }
+
+ // The ciaaSpeed is kind of useless and not present in the MSN file.
+ // Traditionally 0x78 in SoundTracker. Was used in NoiseTracker as a restart point.
+ // ProTracker uses 0x7F. FastTracker uses it as a restart point, whereas ScreamTracker 3 uses 0x7F like ProTracker.
+ // You can use this to roughly detect which tracker made a MOD, and detection gets more accurate for more obscure MOD types.
+ char ciaaSpeed = 0x7F;
+
+ // The mark cannot be recovered either. Since we have 4 channels and 31 instrument it can be either ID='M.K.' or ID='4CHN'.
+ // Assume 'M.K.'
+ const char mark[4] = { 'M', '.', 'K', '.' };
+
+ Common::MemoryWriteStreamDynamic buffer(DisposeAfterUse::NO);
+
+ buffer.write(msnFile.getName(), 19);
+ buffer.writeByte(0);
+
+ for (int i = 0 ; i < 31 ; ++i) {
+ buffer.write(instr[i].iname, 22);
+ buffer.writeUint16BE(instr[i].length);
+ buffer.writeByte(instr[i].finetune);
+ buffer.writeByte(instr[i].volume);
+ buffer.writeUint16BE(instr[i].loopStart);
+ buffer.writeUint16BE(instr[i].loopLength);
+ }
+ buffer.writeByte((char)songLength);
+ buffer.writeByte(ciaaSpeed);
+ buffer.write(arrangement, 128);
+ buffer.write(mark, 4);
+
+ for (int p = 0 ; p < patternNumber ; ++p) {
+ for (int n = 0 ; n < 64 ; ++n) {
+ for (int k = 0 ; k < 4 ; ++k) {
+// buffer.writeUint32BE(*((uint32*)(note[p][n]+k)));
+ buffer.writeSint32BE(note[p][n][k]);
+ }
+ }
+ }
+
+ uint nb;
+ char buf[4096];
+ while ((nb = msnFile.read(buf, 4096)) > 0)
+ buffer.write(buf, nb);
+
+ return new Common::MemoryReadStream(buffer.getData(), buffer.size(), DisposeAfterUse::YES);
+}
+
+}
diff --git a/engines/supernova/resman.h b/engines/supernova/resman.h
new file mode 100644
index 0000000000..080ecc5da4
--- /dev/null
+++ b/engines/supernova/resman.h
@@ -0,0 +1,77 @@
+/* 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 SUPERNOVA_RESOURCES_H
+#define SUPERNOVA_RESOURCES_H
+
+#include "audio/audiostream.h"
+#include "common/ptr.h"
+
+#include "supernova/graphics.h"
+#include "supernova/sound.h"
+
+
+namespace Common {
+class MemoryReadStream;
+}
+
+namespace Supernova {
+
+class ResourceManager {
+public:
+ enum CursorId {
+ kCursorNormal,
+ kCursorWait
+ };
+
+public:
+ static const int kNumImageFiles = 44;
+
+public:
+ ResourceManager();
+
+ Audio::SeekableAudioStream *getSoundStream(AudioId index);
+ Audio::AudioStream *getSoundStream(MusicId index);
+ const MSNImage *getImage(int filenumber) const;
+ const byte *getImage(CursorId id) const;
+
+private:
+ void initSoundFiles();
+ void initGraphics();
+ void initCursorGraphics();
+ void initImages();
+
+private:
+ Common::ScopedPtr<Audio::SeekableAudioStream> _soundSamples[kAudioNumSamples];
+ Common::ScopedPtr<Common::MemoryReadStream> _musicIntroBuffer;
+ Common::ScopedPtr<Common::MemoryReadStream> _musicOutroBuffer;
+ Common::ScopedPtr<Audio::AudioStream> _musicIntro;
+ Common::ScopedPtr<Audio::AudioStream> _musicOutro;
+ int _audioRate;
+ MSNImage _images[kNumImageFiles];
+ byte _cursorNormal[256];
+ byte _cursorWait[256];
+};
+
+}
+
+#endif
diff --git a/engines/supernova/rooms.cpp b/engines/supernova/rooms.cpp
index 83147c1630..9360d58aa1 100644
--- a/engines/supernova/rooms.cpp
+++ b/engines/supernova/rooms.cpp
@@ -24,6 +24,7 @@
#include "graphics/palette.h"
#include "graphics/cursorman.h"
+#include "supernova/screen.h"
#include "supernova/supernova.h"
#include "supernova/state.h"
@@ -79,15 +80,15 @@ bool Room::deserialize(Common::ReadStream *in, int version) {
int numObjects = in->readSint32LE();
for (int i = 0; i < numObjects; ++i) {
- _objectState[i]._name = static_cast<StringID>(in->readSint32LE());
- _objectState[i]._description = static_cast<StringID>(in->readSint32LE());
+ _objectState[i]._name = static_cast<StringId>(in->readSint32LE());
+ _objectState[i]._description = static_cast<StringId>(in->readSint32LE());
_objectState[i]._roomId = in->readByte();
- _objectState[i]._id = static_cast<ObjectID>(in->readSint32LE());
+ _objectState[i]._id = static_cast<ObjectId>(in->readSint32LE());
_objectState[i]._type = static_cast<ObjectType>(in->readSint32LE());
_objectState[i]._click = in->readByte();
_objectState[i]._click2 = in->readByte();
_objectState[i]._section = in->readByte();
- _objectState[i]._exitRoom = static_cast<RoomID>(in->readSint32LE());
+ _objectState[i]._exitRoom = static_cast<RoomId>(in->readSint32LE());
_objectState[i]._direction = in->readByte();
}
@@ -147,102 +148,11 @@ void Intro::onEntrance() {
leaveCutscene();
}
-class Marquee {
-public:
- enum MarqueeIndex {
- kMarqueeIntro,
- kMarqueeOutro
- };
-
- Marquee(SupernovaEngine *vm, MarqueeIndex id, const char *text)
- : _text(text)
- , _textBegin(text)
- , _delay(0)
- , _color(kColorLightBlue)
- , _loop(false)
- , _vm(vm)
- {
- if (id == kMarqueeIntro) {
- _y = 191;
- _loop = true;
- } else if (id == kMarqueeOutro) {
- _y = 1;
- }
- _textWidth = _vm->textWidth(_text);
- _x = kScreenWidth / 2 - _textWidth / 2;
- _vm->_textCursorX = _x;
- _vm->_textCursorY = _y;
- _vm->_textColor = _color;
- }
-
- void renderCharacter();
-
-private:
- void clearText();
-
- SupernovaEngine *_vm;
- MarqueeIndex _id;
- const char *const _textBegin;
- const char *_text;
- bool _loop;
- int _delay;
- int _color;
- int _x;
- int _y;
- int _textWidth;
-};
-
-void Marquee::clearText() {
- _vm->renderBox(_x, _y - 1, _textWidth + 1, 9, kColorBlack);
-}
-
-void Marquee::renderCharacter() {
- if (_delay != 0) {
- _delay--;
- return;
- }
-
- switch (*_text) {
- case '\233':
- if (_loop) {
- _loop = false;
- _text = _textBegin;
- clearText();
- _textWidth = _vm->textWidth(_text);
- _x = kScreenWidth / 2 - _textWidth / 2;
- _vm->_textCursorX = _x;
- }
- break;
- case '\0':
- clearText();
- _text++;
- _textWidth = _vm->textWidth(_text);
- _x = kScreenWidth / 2 - _textWidth / 2;
- _vm->_textCursorX = _x;
- _color = kColorLightBlue;
- _vm->_textColor = _color;
- break;
- case '^':
- _color = kColorLightYellow;
- _vm->_textColor = _color;
- _text++;
- break;
- case '#':
- _delay = 50;
- _text++;
- break;
- default:
- _vm->renderText((uint16)*_text++);
- _delay = 1;
- break;
- }
-}
-
void Intro::titleScreen() {
// Newspaper
CursorMan.showMouse(false);
- _vm->_brightness = 0;
- _vm->_menuBrightness = 0;
+ _vm->_screen->setViewportBrightness(0);
+ _vm->_screen->setGuiBrightness(0);
_vm->paletteBrightness();
_vm->setCurrentImage(1);
_vm->renderImage(0);
@@ -254,25 +164,25 @@ void Intro::titleScreen() {
_vm->setCurrentImage(31);
_vm->renderImage(0);
_vm->paletteFadeIn();
- _gm->wait2(1);
+ _gm->wait(1);
_vm->playSound(kAudioVoiceSupernova);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- _gm->wait2(1);
+ while (_vm->_sound->isPlaying())
+ _gm->wait(1);
titleFadeIn();
_vm->renderText(kStringTitleVersion, 295, 190, kColorWhite44);
const Common::String& title1 = _vm->getGameString(kStringTitle1);
const Common::String& title2 = _vm->getGameString(kStringTitle2);
const Common::String& title3 = _vm->getGameString(kStringTitle3);
- _vm->renderText(title1, 78 - _vm->textWidth(title1) / 2, 120, kColorLightBlue);
- _vm->renderText(title2, 78 - _vm->textWidth(title2) / 2, 132, kColorWhite99);
- _vm->renderText(title3, 78 - _vm->textWidth(title3) / 2, 142, kColorWhite99);
- _gm->wait2(1);
+ _vm->_screen->renderText(title1, 78 - Screen::textWidth(title1) / 2, 120, kColorLightBlue);
+ _vm->_screen->renderText(title2, 78 - Screen::textWidth(title2) / 2, 132, kColorWhite99);
+ _vm->_screen->renderText(title3, 78 - Screen::textWidth(title3) / 2, 142, kColorWhite99);
+ _gm->wait(1);
CursorMan.showMouse(true);
- _vm->playSoundMod(kMusicIntro);
+ _vm->playSound(kMusicIntro);
- Marquee marquee(_vm, Marquee::kMarqueeIntro, _introText.c_str());
+ Marquee marquee(_vm->_screen, Marquee::kMarqueeIntro, _introText.c_str());
while (!_vm->shouldQuit()) {
- _vm->updateEvents();
+ _gm->updateEvents();
marquee.renderCharacter();
if (_gm->_mouseClicked || _gm->_keyPressed)
break;
@@ -280,8 +190,8 @@ void Intro::titleScreen() {
g_system->delayMillis(_vm->_delay);
}
_vm->playSound(kAudioVoiceYeah);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- _gm->wait2(1);
+ while (_vm->_sound->isPlaying())
+ _gm->wait(1);
_vm->paletteFadeOut();
}
@@ -319,7 +229,7 @@ bool Intro::animate(int section1, int section2, int duration) {
}
bool Intro::animate(int section1, int section2, int duration,
- MessagePosition position, StringID textId) {
+ MessagePosition position, StringId textId) {
Common::KeyCode key = Common::KEYCODE_INVALID;
const Common::String& text = _vm->getGameString(textId);
_vm->renderMessage(text, position);
@@ -344,7 +254,7 @@ bool Intro::animate(int section1, int section2, int duration,
}
bool Intro::animate(int section1, int section2, int section3, int section4,
- int duration, MessagePosition position, StringID textId) {
+ int duration, MessagePosition position, StringId textId) {
Common::KeyCode key = Common::KEYCODE_INVALID;
const Common::String& text = _vm->getGameString(textId);
_vm->renderMessage(text, position);
@@ -381,11 +291,11 @@ void Intro::cutscene() {
_vm->_system->fillScreen(kColorBlack);
_vm->setCurrentImage(31);
- _vm->_menuBrightness = 255;
+ _vm->_screen->setGuiBrightness(255);
_vm->paletteBrightness();
if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene1))
return;
- _vm->_menuBrightness = 0;
+ _vm->_screen->setGuiBrightness(0);
_vm->paletteBrightness();
exitOnEscape(1);
@@ -423,7 +333,7 @@ void Intro::cutscene() {
exitOnEscape(28);
_vm->removeMessage();
- StringID textCounting[4] =
+ StringId textCounting[4] =
{kStringIntroCutscene7, kStringIntroCutscene8, kStringIntroCutscene9, kStringIntroCutscene10};
_vm->setCurrentImage(31);
_vm->renderImage(0);
@@ -527,15 +437,15 @@ void Intro::cutscene() {
return;
_vm->paletteFadeOut();
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
+ while (_vm->_sound->isPlaying())
exitOnEscape(1);
_vm->_system->fillScreen(kColorBlack);
- _vm->_menuBrightness = 255;
+ _vm->_screen->setGuiBrightness(255);
_vm->paletteBrightness();
if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene25))
return;
- _vm->_menuBrightness = 5;
+ _vm->_screen->setGuiBrightness(5);
_vm->paletteBrightness();
_vm->setCurrentImage(31);
@@ -558,20 +468,20 @@ void Intro::cutscene() {
return;
CursorMan.showMouse(false);
- _vm->_brightness = 0;
+ _vm->_screen->setViewportBrightness(0);
_vm->paletteBrightness();
exitOnEscape(10);
_vm->playSound(kAudioSnoring);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- _gm->wait2(1);
+ while (_vm->_sound->isPlaying())
+ _gm->wait(1);
exitOnEscape(10);
_vm->playSound(kAudioSnoring);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- _gm->wait2(1);
+ while (_vm->_sound->isPlaying())
+ _gm->wait(1);
exitOnEscape(10);
_vm->playSound(kAudioSnoring);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- _gm->wait2(1);
+ while (_vm->_sound->isPlaying())
+ _gm->wait(1);
exitOnEscape(30);
CursorMan.showMouse(true);
@@ -605,7 +515,7 @@ void Intro::cutscene() {
}
void Intro::leaveCutscene() {
- _vm->_brightness = 255;
+ _vm->_screen->setViewportBrightness(255);
_vm->removeMessage();
_gm->changeRoom(CABIN_R3);
_gm->_guiEnabled = true;
@@ -620,19 +530,19 @@ bool ShipCorridor::interact(Action verb, Object &obj1, Object &obj2) {
_objectState[6].disableProperty(OPENED);
_vm->renderImage(8);
setSectionVisible(9, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(7);
setSectionVisible(8, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(7));
} else {
_vm->playSound(kAudioSlideDoor);
_objectState[6].setProperty(OPENED);
_vm->renderImage(7);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(8);
setSectionVisible(7, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(9);
setSectionVisible(8, false);
}
@@ -649,18 +559,18 @@ bool ShipHall::interact(Action verb, Object &obj1, Object &obj2) {
_objectState[2].disableProperty(OPENED);
_vm->renderImage(3);
setSectionVisible(4, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(2);
setSectionVisible(3, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(2));
} else {
_objectState[2].setProperty(OPENED);
_vm->renderImage(2);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(3);
setSectionVisible(2, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(4);
setSectionVisible(3, false);
_gm->great(1);
@@ -727,13 +637,13 @@ bool ShipSleepCabin::interact(Action verb, Object &obj1, Object &obj2) {
if (daysSleep != 0) {
_gm->_state._timeSleep = daysSleep;
_vm->renderText(kStringShipSleepCabin8, 30, 105, kColorWhite99);
- _gm->wait2(18);
+ _gm->wait(18);
setSectionVisible(5, true);
}
} while (daysSleep == 0);
} else {
_vm->renderText(kStringShipSleepCabin9, 100, 125, kColorLightRed);
- _gm->wait2(18);
+ _gm->wait(18);
}
}
}
@@ -813,12 +723,12 @@ bool ShipSleepCabin::interact(Action verb, Object &obj1, Object &obj2) {
_gm->_state._dream = true;
_gm->loadTime();
}
- _gm->wait2(18);
+ _gm->wait(18);
_vm->paletteFadeIn();
if (_gm->_state._arrivalDaysLeft == 0) {
_vm->playSound(kAudioCrash);
_gm->screenShake();
- _gm->wait2(18);
+ _gm->wait(18);
_vm->renderMessage(kStringShipSleepCabin12);
}
}
@@ -860,10 +770,10 @@ void ShipSleepCabin::animation() {
void ShipSleepCabin::onEntrance() {
if (_gm->_state._dream && (_gm->_rooms[CAVE]->getObject(1)->_exitRoom == MEETUP3)) {
_vm->renderMessage(kStringShipSleepCabin14);
- _gm->waitOnInput(_gm->_timer1);
+ _gm->waitOnInput(_gm->_messageDuration);
_vm->removeMessage();
_vm->renderMessage(kStringShipSleepCabin15);
- _gm->waitOnInput(_gm->_timer1);
+ _gm->waitOnInput(_gm->_messageDuration);
_vm->removeMessage();
_vm->renderMessage(kStringShipSleepCabin16);
_gm->_state._dream = false;
@@ -1004,7 +914,7 @@ bool ShipCabinL3::interact(Action verb, Object &obj1, Object &obj2) {
setSectionVisible(15, false);
for (int i = 3; i; i--) {
_vm->playSound(kAudioTurntable);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) {
+ while (_vm->_sound->isPlaying()) {
if (isSectionVisible(13)) {
_vm->renderImage(14);
setSectionVisible(13, false);
@@ -1012,7 +922,7 @@ bool ShipCabinL3::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderImage(13);
setSectionVisible(14, false);
}
- _gm->wait2(3);
+ _gm->wait(3);
}
}
@@ -1037,7 +947,7 @@ bool ShipCabinL3::interact(Action verb, Object &obj1, Object &obj2) {
setSectionVisible(10, false);
getObject(10)->_click = 20;
} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KNIFE, WIRE2))
- _vm->renderMessage(kStringShipCabinL3_4);
+ _vm->renderMessage(kStringShipCabinL3_4); // cutting near plug
else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KNIFE, WIRE)) {
r = _gm->_rooms[AIRLOCK];
if (!isSectionVisible(10) && !r->getObject(5)->hasProperty(WORN)) {
@@ -1125,20 +1035,20 @@ bool ShipAirlock::interact(Action verb, Object &obj1, Object &obj2) {
if (getObject(0)->hasProperty(OPENED)) {
getObject(0)->disableProperty(OPENED);
_vm->renderImage(1);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(2);
setSectionVisible(1, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(3);
setSectionVisible(2, false);
} else {
getObject(0)->setProperty(OPENED);
_vm->renderImage(2);
setSectionVisible(3, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(1);
setSectionVisible(2, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(1));
}
_vm->renderImage(_gm->invertSection(10));
@@ -1150,53 +1060,53 @@ bool ShipAirlock::interact(Action verb, Object &obj1, Object &obj2) {
_vm->playSound(kAudioSlideDoor);
getObject(1)->disableProperty(OPENED);
_vm->renderImage(4);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(5);
setSectionVisible(4, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(6);
setSectionVisible(5, false);
_vm->renderImage(16);
setSectionVisible(17, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(15);
setSectionVisible(16, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(14);
setSectionVisible(15, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(13);
setSectionVisible(14, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(12);
setSectionVisible(13, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(_gm->invertSection(12));
} else {
getObject(1)->setProperty(OPENED);
_vm->renderImage(12);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(13);
setSectionVisible(12, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(14);
setSectionVisible(13, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(15);
setSectionVisible(14, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(16);
setSectionVisible(15, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(17);
setSectionVisible(16, false);
_vm->playSound(kAudioSlideDoor);
_vm->renderImage(5);
setSectionVisible(6, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(4);
setSectionVisible(5, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(4));
r = _gm->_rooms[AIRLOCK];
if (!r->getObject(4)->hasProperty(WORN) ||
@@ -1302,13 +1212,13 @@ bool ShipLandingModule::interact(Action verb, Object &obj1, Object &obj2) {
r = _gm->_rooms[SLEEP];
r->setSectionVisible(1, false);
r->setSectionVisible(2, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(2);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(8);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(9);
- _gm->wait2(1);
+ _gm->wait(1);
_vm->renderImage(10);
}
}
@@ -1529,9 +1439,9 @@ bool ArsanoRocks::interact(Action verb, Object &obj1, Object &obj2) {
if (((verb == ACTION_PULL) || (verb == ACTION_PRESS)) &&
(obj1._id == STONE) && !isSectionVisible(3)) {
_vm->renderImage(1);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(2);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(3);
_vm->playSound(kAudioRocks);
obj1._click = 3;
@@ -1544,10 +1454,10 @@ bool ArsanoRocks::interact(Action verb, Object &obj1, Object &obj2) {
void ArsanoMeetup::onEntrance() {
if (isSectionVisible(7)) {
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(6);
setSectionVisible(7, false);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(_gm->invertSection(6));
}
if (!(_gm->_state._greatFlag & 0x8000)) {
@@ -1591,10 +1501,10 @@ bool ArsanoMeetup::interact(Action verb, Object &obj1, Object &obj2) {
_vm->paletteBrightness();
} else if ((verb == ACTION_WALK) && (obj1._id == DOOR)) {
_vm->renderImage(6);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(7);
setSectionVisible(6, false);
- _gm->wait2(3);
+ _gm->wait(3);
return false;
} else if ((verb == ACTION_LOOK) && (obj1._id == MEETUP_SIGN) && _gm->_state._language) {
@@ -1616,21 +1526,21 @@ bool ArsanoMeetup::interact(Action verb, Object &obj1, Object &obj2) {
}
void ArsanoEntrance::animation() {
- if (!_vm->_messageDisplayed && isSectionVisible(kMaxSection - 5)) {
+ if (!_vm->_screen->isMessageShown() && isSectionVisible(kMaxSection - 5)) {
_gm->animationOff(); // to avoid recursive call
_vm->playSound(kAudioSlideDoor);
_vm->renderImage(8);
setSectionVisible(9, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(7);
setSectionVisible(8, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(6);
setSectionVisible(7, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(5);
setSectionVisible(6, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(5));
getObject(11)->_click = 255;
setSectionVisible(kMaxSection - 5, false);
@@ -1695,7 +1605,7 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
}
} else if ((verb == ACTION_WALK) && (obj1._id == STAIRCASE) && (_gm->_state._shoes != 3)) {
_vm->renderImage(3);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(4);
setSectionVisible(3, false);
if (_gm->_rooms[AIRLOCK]->getObject(4)->hasProperty(WORN))
@@ -1706,7 +1616,7 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
_gm->reply(kStringArsanoEntrance12, 1, _gm->invertSection(1));
_vm->renderImage(3);
setSectionVisible(4, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(3));
if (!_gm->_rooms[AIRLOCK]->getObject(4)->hasProperty(WORN)) {
if (_gm->_state._language) {
@@ -1732,13 +1642,13 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
break;
case 3:
_vm->renderImage(3);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(4);
setSectionVisible(3, false);
_gm->reply(kStringArsanoEntrance16, 1, 1 + 128);
_vm->renderImage(3);
setSectionVisible(4, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(3));
break;
}
@@ -1752,16 +1662,16 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
} else if ((verb == ACTION_PRESS) && (obj1._id == BATHROOM_BUTTON)) {
_vm->playSound(kAudioSlideDoor);
_vm->renderImage(5);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(6);
setSectionVisible(5, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(7);
setSectionVisible(6, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(8);
setSectionVisible(7, false);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(9);
setSectionVisible(8, false);
getObject(11)->_click = 9;
@@ -1782,7 +1692,7 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderMessage(kStringArsanoEntrance20);
else {
_vm->renderMessage(kStringArsanoEntrance21);
- _gm->waitOnInput(_gm->_timer1);
+ _gm->waitOnInput(_gm->_messageDuration);
_vm->removeMessage();
_vm->renderMessage(kStringArsanoEntrance22);
_gm->takeObject(*getObject(16));
@@ -1829,7 +1739,7 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
_gm->_rooms[AIRLOCK]->getObject(4)->setProperty(WORN);
_gm->_rooms[AIRLOCK]->getObject(5)->setProperty(WORN);
_gm->_rooms[AIRLOCK]->getObject(6)->setProperty(WORN);
- _gm->waitOnInput(_gm->_timer1);
+ _gm->waitOnInput(_gm->_messageDuration);
_vm->removeMessage();
}
return false;
@@ -2097,12 +2007,12 @@ bool ArsanoRoger::interact(Action verb, Object &obj1, Object &obj2) {
_vm->paletteFadeOut();
_gm->_inventory.remove(*_gm->_rooms[CABIN_R3]->getObject(0)); // Chess board
g_system->fillScreen(kColorBlack);
- _vm->_menuBrightness = 255;
+ _vm->_screen->setGuiBrightness(255);
_vm->paletteBrightness();
_vm->renderMessage(kStringArsanoRoger39);
- _gm->waitOnInput(_gm->_timer1);
+ _gm->waitOnInput(_gm->_messageDuration);
_vm->removeMessage();
- _vm->_menuBrightness = 0;
+ _vm->_screen->setGuiBrightness(0);
_vm->paletteBrightness();
_gm->_state._time += ticksToMsec(125000); // 2 hours
_gm->_state._alarmOn = (_gm->_state._timeAlarm > _gm->_state._time);
@@ -2117,7 +2027,7 @@ bool ArsanoRoger::interact(Action verb, Object &obj1, Object &obj2) {
getObject(6)->_click = 7;
_vm->paletteFadeIn();
_vm->renderMessage(kStringArsanoRoger40);
- _gm->waitOnInput(_gm->_timer1);
+ _gm->waitOnInput(_gm->_messageDuration);
_vm->removeMessage();
} else
return false;
@@ -2140,7 +2050,7 @@ bool ArsanoGlider::interact(Action verb, Object &obj1, Object &obj2) {
static char l, r;
if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KEYCARD_R, GLIDER_SLOT)) {
_vm->renderImage(5);
- _gm->wait2(7);
+ _gm->wait(7);
_vm->renderImage(8);
getObject(5)->_click = 10;
_gm->_inventory.remove(*_gm->_rooms[ROGER]->getObject(8));
@@ -2192,7 +2102,7 @@ bool ArsanoGlider::interact(Action verb, Object &obj1, Object &obj2) {
}
}
}
- _gm->wait2(4);
+ _gm->wait(4);
_vm->renderImage(_gm->invertSection(i));
} else if ((verb == ACTION_USE) && (obj1._id == GLIDER_BUTTONS))
_vm->renderMessage(kStringArsanoGlider1);
@@ -2264,40 +2174,40 @@ bool ArsanoMeetup2::interact(Action verb, Object &obj1, Object &obj2) {
_vm->setCurrentImage(13);
_vm->renderImage(0);
_vm->paletteBrightness();
- _gm->wait2(36);
+ _gm->wait(36);
for (int i = 1; i <= 13; i++) {
if (i > 1)
_vm->renderImage(_gm->invertSection(i - 1));
_vm->renderImage(i);
- _gm->wait2(2);
+ _gm->wait(2);
}
_vm->renderImage(_gm->invertSection(13));
- _gm->wait2(20);
+ _gm->wait(20);
_vm->setCurrentImage(14);
_vm->renderImage(0);
_vm->paletteBrightness();
- _gm->wait2(36);
+ _gm->wait(36);
for (int i = 1; i <= 13; i++) {
if (i > 1)
_vm->renderImage(_gm->invertSection(i - 1));
_vm->renderImage(i);
- _gm->wait2(2);
+ _gm->wait(2);
}
_vm->renderImage(_gm->invertSection(13));
- _gm->wait2(9);
+ _gm->wait(9);
_vm->playSound(kAudioCrash);
for (int i = 14; i <= 19; i++) {
_vm->renderImage(i);
- _gm->wait2(3);
+ _gm->wait(3);
}
_vm->paletteFadeOut();
_vm->setCurrentImage(11);
_vm->renderImage(0);
_vm->paletteFadeIn();
- _gm->wait2(18);
+ _gm->wait(18);
_vm->renderMessage(kStringArsanoMeetup2_12);
_gm->great(0);
- _gm->waitOnInput(_gm->_timer1);
+ _gm->waitOnInput(_gm->_messageDuration);
_vm->removeMessage();
_vm->paletteFadeOut();
g_system->fillScreen(kColorBlack);
@@ -2321,14 +2231,14 @@ bool ArsanoMeetup2::interact(Action verb, Object &obj1, Object &obj2) {
}
void ArsanoMeetup2::shipStart() {
- _gm->wait2(12);
+ _gm->wait(12);
for (int i = 2; i <= 11; ++i) {
if (i >= 9)
_vm->renderImage(i - 1 + 128);
else
setSectionVisible(i - 1, false);
_vm->renderImage(i);
- _gm->wait2(2);
+ _gm->wait(2);
}
_vm->renderImage(11 + 128);
}
@@ -2354,34 +2264,34 @@ bool ArsanoMeetup3::interact(Action verb, Object &obj1, Object &obj2) {
_vm->paletteBrightness();
_gm->dialog(3, rowsX, _dialogsX, 0);
_vm->renderImage(1);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(2);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(3);
- _gm->wait2(6);
+ _gm->wait(6);
_vm->renderImage(4);
_vm->playSound(kAudioGunShot);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- _gm->wait2(1);
+ while (_vm->_sound->isPlaying())
+ _gm->wait(1);
_vm->renderImage(5);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(4);
_vm->playSound(kAudioGunShot);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- _gm->wait2(1);
+ while (_vm->_sound->isPlaying())
+ _gm->wait(1);
_vm->renderImage(5);
_vm->paletteFadeOut();
- _gm->wait2(12);
+ _gm->wait(12);
_vm->setCurrentImage(0);
_vm->renderImage(0);
_vm->paletteFadeIn();
- _gm->wait2(18);
+ _gm->wait(18);
_gm->reply(kStringArsanoMeetup3_1, 2, 2 + 128);
- _gm->wait2(10);
+ _gm->wait(10);
_gm->reply(kStringArsanoMeetup3_2, 1, 1 + 128);
do {
@@ -2604,8 +2514,8 @@ bool AxacussCell::interact(Action verb, Object &obj1, Object &obj2) {
return false;
_vm->playSound(kAudioGunShot);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- _gm->wait2(1);
+ while (_vm->_sound->isPlaying())
+ _gm->wait(1);
_vm->playSound(kAudioGunShot);
_vm->playSound(kAudioGunShot);
@@ -2693,27 +2603,29 @@ bool AxacussCorridor5::handleMoneyDialog() {
}
switch (_gm->dialog(4, _rows, _dialog3, 2)) {
case 1:
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(1);
_vm->playSound(kAudioVoiceHalt);
_vm->renderImage(_gm->invertSection(1));
- _gm->wait2(5);
+ _gm->wait(5);
_vm->renderImage(2);
- _gm->wait2(2);
+ _gm->wait(2);
_gm->shot(3, _gm->invertSection(3));
break;
- case 3:
- if (_gm->_state._money >= 900) {
- stopInteract(_gm->_state._money);
- return true;
- }
- // fall through
case 2:
if (_gm->_state._money > 1100) {
stopInteract(_gm->_state._money - 200);
return true;
}
_gm->reply(kStringAxacussCorridor5_6, 1, 1 + 128);
+ break;
+ case 3:
+ if (_gm->_state._money >= 900) {
+ stopInteract(_gm->_state._money);
+ return true;
+ }
+ _gm->reply(kStringAxacussCorridor5_6, 1, 1 + 128);
+ break;
}
}
return false;
@@ -2959,7 +2871,7 @@ bool AxacussExit::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderImage(i);
if (i == 11)
_vm->playSound(kAudioSmash); // 046/4020
- _gm->wait2(1);
+ _gm->wait(1);
_vm->renderImage(i + 128);
}
_gm->_state._powerOff = true;
@@ -3176,9 +3088,9 @@ bool AxacussElevator::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderImage(1);
getObject(2)->resetProperty();
_vm->playSound(kAudioSlideDoor);
- _gm->wait2(25);
+ _gm->wait(25);
for (int i = 3; i <= 7; i++) {
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(i);
}
getObject(3)->resetProperty(EXIT);
@@ -3196,10 +3108,10 @@ bool AxacussElevator::interact(Action verb, Object &obj1, Object &obj2) {
getObject(3)->_click = 255;
_vm->playSound(kAudioSlideDoor);
for (int i = 7; i >= 3; i--) {
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(i));
}
- _gm->wait2(25);
+ _gm->wait(25);
_vm->playSound(kAudioSlideDoor);
getObject(2)->resetProperty(EXIT);
_vm->renderImage(_gm->invertSection(2));
@@ -3207,12 +3119,12 @@ bool AxacussElevator::interact(Action verb, Object &obj1, Object &obj2) {
} else if ((verb == ACTION_WALK) && (obj1._id == JUNGLE)) {
_vm->paletteFadeOut();
g_system->fillScreen(kColorBlack);
- _vm->_menuBrightness = 255;
+ _vm->_screen->setGuiBrightness(255);
_vm->paletteBrightness();
_vm->renderMessage(kStringAxacussElevator_3);
- _gm->waitOnInput(_gm->_timer1);
+ _gm->waitOnInput(_gm->_messageDuration);
_vm->removeMessage();
- _vm->_menuBrightness = 0;
+ _vm->_screen->setGuiBrightness(0);
_vm->paletteBrightness();
_gm->_state._time += ticksToMsec(125000); // 2 hours
_gm->_state._alarmOn = (_gm->_state._timeAlarm > _gm->_state._time);
@@ -3281,24 +3193,24 @@ void Outro::onEntrance() {
_vm->renderImage(0);
_vm->renderImage(1);
_vm->paletteFadeIn();
- _gm->wait2(10);
+ _gm->wait(10);
for (int i = 8; i <= 21; i++) {
_vm->renderImage(i);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(_gm->invertSection(i));
}
- _gm->wait2(18);
+ _gm->wait(18);
_vm->renderImage(_gm->invertSection(1));
for (int i = 2; i <= 7; i++) {
_vm->renderImage(i);
- _gm->wait2(3);
+ _gm->wait(3);
_vm->renderImage(_gm->invertSection(i));
}
- _vm->playSoundMod(kMusicOutro);
- Marquee marquee(_vm, Marquee::kMarqueeOutro, _outroText.c_str());
+ _vm->playSound(kMusicOutro);
+ Marquee marquee(_vm->_screen, Marquee::kMarqueeOutro, _outroText.c_str());
while (!_vm->shouldQuit()) {
- _vm->updateEvents();
+ _gm->updateEvents();
marquee.renderCharacter();
if (_gm->_mouseClicked || _gm->_keyPressed)
break;
@@ -3311,7 +3223,7 @@ void Outro::onEntrance() {
_vm->paletteFadeIn();
_gm->getInput();
_vm->paletteFadeOut();
- _vm->_brightness = 1;
+ _vm->_screen->setViewportBrightness(1);
Common::Event event;
event.type = Common::EVENT_RTL;
@@ -3325,9 +3237,9 @@ void Outro::animate(int filenumber, int section1, int section2, int duration) {
_vm->setCurrentImage(filenumber);
while (duration) {
_vm->renderImage(section1);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(section2);
- _gm->wait2(2);
+ _gm->wait(2);
--duration;
}
}
@@ -3340,10 +3252,10 @@ void Outro::animate(int filenumber, int section1, int section2, int duration,
while (delay) {
if (section1)
_vm->renderImage(section1);
- _gm->wait2(2);
+ _gm->wait(2);
if (section2)
_vm->renderImage(section2);
- _gm->wait2(2);
+ _gm->wait(2);
--delay;
}
_vm->removeMessage();
@@ -3359,10 +3271,10 @@ void Outro::animate(int filenumber, int section1, int section2, int section3, in
while(duration) {
_vm->renderImage(section1);
_vm->renderImage(section3);
- _gm->wait2(2);
+ _gm->wait(2);
_vm->renderImage(section2);
_vm->renderImage(section4);
- _gm->wait2(2);
+ _gm->wait(2);
duration--;
}
_vm->removeMessage();
diff --git a/engines/supernova/rooms.h b/engines/supernova/rooms.h
index 3cedc356db..5c9b283dcd 100644
--- a/engines/supernova/rooms.h
+++ b/engines/supernova/rooms.h
@@ -27,6 +27,11 @@
#include "msn_def.h"
+namespace Common {
+class ReadStream;
+class WriteStream;
+}
+
namespace Supernova {
class GameManager;
@@ -52,7 +57,7 @@ public:
int getFileNumber() const {
return _fileNumber;
}
- RoomID getId() const {
+ RoomId getId() const {
return _id;
}
@@ -112,7 +117,7 @@ protected:
bool _shown[kMaxSection];
byte _sentenceRemoved[kMaxDialog];
Object _objectState[kMaxObject];
- RoomID _id;
+ RoomId _id;
SupernovaEngine *_vm;
GameManager *_gm;
@@ -129,9 +134,9 @@ public:
private:
bool animate(int section1, int section2, int duration);
bool animate(int section1, int section2, int duration, MessagePosition position,
- StringID text);
+ StringId text);
bool animate(int section1, int section2, int section3, int section4, int duration,
- MessagePosition position, StringID text);
+ MessagePosition position, StringId text);
void titleScreen();
void titleFadeIn();
@@ -681,9 +686,9 @@ public:
virtual void animation();
private:
- StringID _dialog1[5];
- StringID _dialog2[5];
- StringID _dialog3[5];
+ StringId _dialog1[5];
+ StringId _dialog2[5];
+ StringId _dialog3[5];
byte _eyewitness;
};
class ArsanoRemaining : public Room {
@@ -742,7 +747,7 @@ public:
virtual bool interact(Action verb, Object &obj1, Object &obj2);
private:
- StringID _dialog1[4];
+ StringId _dialog1[4];
byte _eyewitness;
byte _hands;
};
@@ -809,10 +814,10 @@ public:
private:
// TODO: change to 6, fix initialization
- StringID _dialog1[2];
- StringID _dialog2[2];
- StringID _dialog3[4];
- StringID _dialog4[3];
+ StringId _dialog1[2];
+ StringId _dialog2[2];
+ StringId _dialog3[4];
+ StringId _dialog4[3];
bool _found;
bool _flug;
@@ -846,11 +851,11 @@ public:
virtual bool interact(Action verb, Object &obj1, Object &obj2);
private:
- StringID _dialog2[4];
- StringID _dialog3[2];
+ StringId _dialog2[4];
+ StringId _dialog3[2];
// TODO: Hack, to be move away and renamed when the other uses are found
- StringID _dialogsX[6];
+ StringId _dialogsX[6];
//
};
@@ -1025,9 +1030,9 @@ private:
bool handleMoneyDialog();
// TODO: Change to 6, or change struct, and fix initialization
- StringID _dialog1[2];
- StringID _dialog2[2];
- StringID _dialog3[4];
+ StringId _dialog1[2];
+ StringId _dialog2[2];
+ StringId _dialog3[4];
byte _rows[6];
};
@@ -1176,7 +1181,7 @@ public:
virtual bool interact(Action verb, Object &obj1, Object &obj2);
private:
- StringID _dialogsX[6];
+ StringId _dialogsX[6];
};
class AxacussExit : public Room {
@@ -1205,7 +1210,7 @@ public:
virtual bool interact(Action verb, Object &obj1, Object &obj2);
private:
- StringID _dialogsX[6];
+ StringId _dialogsX[6];
};
class AxacussOffice1 : public Room {
public:
diff --git a/engines/supernova/screen.cpp b/engines/supernova/screen.cpp
new file mode 100644
index 0000000000..2c441acf7b
--- /dev/null
+++ b/engines/supernova/screen.cpp
@@ -0,0 +1,636 @@
+/* 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/str.h"
+#include "common/system.h"
+#include "engines/util.h"
+#include "graphics/cursorman.h"
+#include "graphics/palette.h"
+#include "graphics/surface.h"
+
+#include "supernova/imageid.h"
+#include "supernova/resman.h"
+#include "supernova/state.h"
+#include "supernova/screen.h"
+#include "supernova/supernova.h"
+
+#include "supernova/screenstatic.cpp"
+
+namespace Supernova {
+
+ScreenBuffer::ScreenBuffer()
+ : _x(0)
+ , _y(0)
+ , _width(0)
+ , _height(0)
+ , _pixels(nullptr) {
+}
+
+ScreenBufferStack::ScreenBufferStack()
+ : _last(_buffer) {
+}
+
+void ScreenBufferStack::push(int x, int y, int width, int height) {
+ if (_last == ARRAYEND(_buffer))
+ return;
+
+ Graphics::Surface *screenSurface = g_system->lockScreen();
+
+ if (x < 0) {
+ width += x;
+ x = 0;
+ }
+
+ if (x + width > screenSurface->w)
+ width = screenSurface->w - x;
+
+ if (y < 0) {
+ height += y;
+ y = 0;
+ }
+
+ if (y + height > screenSurface->h)
+ height = screenSurface->h - y;
+
+ _last->_pixels = new byte[width * height];
+ byte *pixels = _last->_pixels;
+ const byte *screen = static_cast<const byte *>(screenSurface->getBasePtr(x, y));
+ for (int i = 0; i < height; ++i) {
+ Common::copy(screen, screen + width, pixels);
+ screen += screenSurface->pitch;
+ pixels += width;
+ }
+ g_system->unlockScreen();
+
+ _last->_x = x;
+ _last->_y = y;
+ _last->_width = width;
+ _last->_height = height;
+
+ ++_last;
+}
+
+void ScreenBufferStack::restore() {
+ if (_last == _buffer)
+ return;
+
+ --_last;
+ g_system->lockScreen()->copyRectToSurface(_last->_pixels, _last->_width, _last->_x,
+ _last->_y, _last->_width, _last->_height);
+ g_system->unlockScreen();
+
+ delete[] _last->_pixels;
+}
+
+Marquee::Marquee(Screen *screen, MarqueeId id, const char *text)
+ : _text(text)
+ , _textBegin(text)
+ , _delay(0)
+ , _color(kColorLightBlue)
+ , _loop(false)
+ , _screen(screen) {
+ if (id == kMarqueeIntro) {
+ _y = 191;
+ _loop = true;
+ } else if (id == kMarqueeOutro) {
+ _y = 1;
+ }
+
+ _textWidth = Screen::textWidth(_text);
+ _x = kScreenWidth / 2 - _textWidth / 2;
+ _screen->_textCursorX = _x;
+ _screen->_textCursorY = _y;
+ _screen->_textColor = _color;
+}
+
+void Marquee::clearText() {
+ _screen->renderBox(_x, _y - 1, _textWidth + 1, 9, kColorBlack);
+}
+
+void Marquee::renderCharacter() {
+ if (_delay != 0) {
+ _delay--;
+ return;
+ }
+
+ switch (*_text) {
+ case '\233':
+ if (_loop) {
+ _loop = false;
+ _text = _textBegin;
+ clearText();
+ _textWidth = Screen::textWidth(_text);
+ _x = kScreenWidth / 2 - _textWidth / 2;
+ _screen->_textCursorX = _x;
+ }
+ break;
+ case '\0':
+ clearText();
+ _text++;
+ _textWidth = Screen::textWidth(_text);
+ _x = kScreenWidth / 2 - _textWidth / 2;
+ _screen->_textCursorX = _x;
+ _color = kColorLightBlue;
+ _screen->_textColor = _color;
+ break;
+ case '^':
+ _color = kColorLightYellow;
+ _screen->_textColor = _color;
+ _text++;
+ break;
+ case '#':
+ _delay = 50;
+ _text++;
+ break;
+ default:
+ _screen->renderText((uint16)*_text++);
+ _delay = 1;
+ break;
+ }
+}
+
+Screen::Screen(SupernovaEngine *vm, GameManager *gm, ResourceManager *resMan)
+ : _vm(vm)
+ , _gm(gm)
+ , _resMan(resMan)
+ , _currentImage(nullptr)
+ , _viewportBrightness(255)
+ , _guiBrightness(255)
+ , _screenWidth(320)
+ , _screenHeight(200)
+ , _textColor(kColorBlack)
+ , _textCursorX(0)
+ , _textCursorY(0)
+ , _messageShown(false) {
+
+ CursorMan.replaceCursor(_resMan->getImage(ResourceManager::kCursorNormal),
+ 16, 16, 0, 0, kColorCursorTransparent);
+ CursorMan.replaceCursorPalette(initVGAPalette, 0, 16);
+ CursorMan.showMouse(true);
+}
+
+int Screen::getGuiBrightness() const {
+ return _guiBrightness;
+}
+
+void Screen::setViewportBrightness(int brightness) {
+ _viewportBrightness = brightness;
+}
+
+int Screen::getViewportBrightness() const {
+ return _viewportBrightness;
+}
+
+void Screen::setGuiBrightness(int brightness) {
+ _guiBrightness = brightness;
+}
+
+const MSNImage *Screen::getCurrentImage() const {
+ return _currentImage;
+}
+
+bool Screen::isMessageShown() const {
+ return _messageShown;
+}
+
+Common::Point Screen::getTextCursorPos() {
+ return Common::Point(_textCursorX, _textCursorY);
+}
+
+void Screen::setTextCursorPos(int x, int y) {
+ _textCursorX = x;
+ _textCursorY = y;
+}
+
+byte Screen::getTextCursorColor() {
+ return _textColor;
+}
+
+void Screen::setTextCursorColor(byte color) {
+ _textColor = color;
+}
+
+void Screen::renderMessage(StringId stringId, MessagePosition position,
+ Common::String var1, Common::String var2) {
+ Common::String text = _vm->getGameString(stringId);
+
+ if (!var1.empty()) {
+ if (!var2.empty())
+ text = Common::String::format(text.c_str(), var1.c_str(), var2.c_str());
+ else
+ text = Common::String::format(text.c_str(), var1.c_str());
+ }
+
+ renderMessage(text, position);
+}
+
+void Screen::renderMessage(const Common::String &text, MessagePosition position) {
+ if (!text.empty())
+ renderMessage(text.c_str(), position);
+}
+
+void Screen::renderText(const uint16 character) {
+ char text[2];
+ text[0] = character & 0xFF;
+ text[1] = 0;
+ renderText(text, _textCursorX, _textCursorY, _textColor);
+}
+
+void Screen::renderText(const char *text) {
+ renderText(text, _textCursorX, _textCursorY, _textColor);
+}
+
+void Screen::renderText(StringId stringId) {
+ renderText(_vm->getGameString(stringId));
+}
+
+void Screen::renderText(const Common::String &text) {
+ if (!text.empty())
+ renderText(text.c_str());
+}
+
+void Screen::renderText(const GuiElement &guiElement) {
+ renderText(guiElement.getText(), guiElement.getTextPos().x,
+ guiElement.getTextPos().y, guiElement.getTextColor());
+}
+
+void Screen::renderText(const uint16 character, int x, int y, byte color) {
+ char text[2];
+ text[0] = character & 0xFF;
+ text[1] = 0;
+ renderText(text, x, y, color);
+}
+
+void Screen::renderText(const char *text, int x, int y, byte color) {
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+ byte *cursor = static_cast<byte *>(screen->getBasePtr(x, y));
+ const byte *basePtr = cursor;
+
+ byte c;
+ while ((c = *text++) != '\0') {
+ if (c < 32) {
+ continue;
+ } else if (c == 225) {
+ c = 128;
+ }
+
+ for (uint i = 0; i < 5; ++i) {
+ if (font[c - 32][i] == 0xff) {
+ break;
+ }
+
+ byte *ascentLine = cursor;
+ for (byte j = font[c - 32][i]; j != 0; j >>= 1) {
+ if (j & 1) {
+ *cursor = color;
+ }
+ cursor += kScreenWidth;
+ }
+ cursor = ++ascentLine;
+ }
+ ++cursor;
+ }
+ _vm->_system->unlockScreen();
+
+ uint numChars = cursor - basePtr;
+ uint absPosition = y * kScreenWidth + x + numChars;
+ _textCursorX = absPosition % kScreenWidth;
+ _textCursorY = absPosition / kScreenWidth;
+ _textColor = color;
+}
+
+void Screen::renderText(const Common::String &text, int x, int y, byte color) {
+ if (!text.empty())
+ renderText(text.c_str(), x, y, color);
+}
+
+void Screen::renderText(StringId stringId, int x, int y, byte color) {
+ renderText(_vm->getGameString(stringId), x, y, color);
+}
+
+void Screen::renderImageSection(const MSNImage *image, int section) {
+ // Note: inverting means we are removing the section. So we should get the rect for that
+ // section but draw the background (section 0) instead.
+ bool invert = false;
+ if (section > 128) {
+ section -= 128;
+ invert = true;
+ }
+ if (section > image->_numSections - 1)
+ return;
+
+ Common::Rect sectionRect(image->_section[section].x1,
+ image->_section[section].y1,
+ image->_section[section].x2 + 1,
+ image->_section[section].y2 + 1);
+ if (image->_filenumber == 1 || image->_filenumber == 2) {
+ sectionRect.setWidth(640);
+ sectionRect.setHeight(480);
+ if (_screenWidth != 640) {
+ _screenWidth = 640;
+ _screenHeight = 480;
+ initGraphics(_screenWidth, _screenHeight);
+ }
+ } else {
+ if (_screenWidth != 320) {
+ _screenWidth = 320;
+ _screenHeight = 200;
+ initGraphics(_screenWidth, _screenHeight);
+ }
+ }
+
+ uint offset = 0;
+ int pitch = sectionRect.width();
+ if (invert) {
+ pitch = image->_pitch;
+ offset = image->_section[section].y1 * pitch +
+ image->_section[section].x1;
+ section = 0;
+ }
+
+ void *pixels = image->_sectionSurfaces[section]->getPixels();
+ _vm->_system->copyRectToScreen(static_cast<const byte *>(pixels) + offset,
+ pitch, sectionRect.left, sectionRect.top,
+ sectionRect.width(), sectionRect.height());
+}
+
+void Screen::renderImage(ImageId id, bool removeImage) {
+ ImageInfo info = imageInfo[id];
+ const MSNImage *image = _resMan->getImage(info.filenumber);
+
+ if (_currentImage != image) {
+ _currentImage = image;
+ _vm->_system->getPaletteManager()->setPalette(image->getPalette(), 16, 239);
+ }
+
+ do {
+ if (removeImage)
+ renderImageSection(image, info.section + 128);
+ else
+ renderImageSection(image, info.section);
+
+ info.section = image->_section[info.section].next;
+ } while (info.section != 0);
+}
+
+void Screen::renderImage(int section) {
+ if (!_currentImage)
+ return;
+
+ bool sectionVisible = true;
+
+ if (section > 128) {
+ sectionVisible = false;
+ section -= 128;
+ }
+
+ _gm->_currentRoom->setSectionVisible(section, sectionVisible);
+
+ do {
+ if (sectionVisible)
+ renderImageSection(_currentImage, section);
+ else
+ renderImageSection(_currentImage, section + 128);
+ section = _currentImage->_section[section].next;
+ } while (section != 0);
+}
+
+bool Screen::setCurrentImage(int filenumber) {
+ _currentImage = _resMan->getImage(filenumber);
+ _vm->_system->getPaletteManager()->setPalette(_currentImage->getPalette(), 16, 239);
+ paletteBrightness();
+
+ return true;
+}
+
+void Screen::saveScreen(int x, int y, int width, int height) {
+ _screenBuffer.push(x, y, width, height);
+}
+
+void Screen::saveScreen(const GuiElement &guiElement) {
+ saveScreen(guiElement.left, guiElement.top, guiElement.width(), guiElement.height());
+}
+
+void Screen::restoreScreen() {
+ _screenBuffer.restore();
+}
+
+void Screen::renderRoom(Room &room) {
+ if (room.getId() == INTRO)
+ return;
+
+ if (setCurrentImage(room.getFileNumber())) {
+ for (int i = 0; i < _currentImage->_numSections; ++i) {
+ int section = i;
+ if (room.isSectionVisible(section)) {
+ do {
+ renderImageSection(_currentImage, section);
+ section = _currentImage->_section[section].next;
+ } while (section != 0);
+ }
+ }
+ }
+}
+
+int Screen::textWidth(const uint16 key) {
+ char text[2];
+ text[0] = key & 0xFF;
+ text[1] = 0;
+ return textWidth(text);
+}
+
+int Screen::textWidth(const char *text) {
+ int charWidth = 0;
+ while (*text != '\0') {
+ byte c = *text++;
+ if (c < 32) {
+ continue;
+ } else if (c == 225) {
+ c = 35;
+ }
+
+ for (uint i = 0; i < 5; ++i) {
+ if (font[c - 32][i] == 0xff) {
+ break;
+ }
+ ++charWidth;
+ }
+ ++charWidth;
+ }
+
+ return charWidth;
+}
+
+int Screen::textWidth(const Common::String &text) {
+ return Screen::textWidth(text.c_str());
+}
+
+void Screen::renderMessage(const char *text, MessagePosition position) {
+ Common::String t(text);
+ char *row[20];
+ Common::String::iterator p = t.begin();
+ uint numRows = 0;
+ int rowWidthMax = 0;
+ int x = 0;
+ int y = 0;
+ byte textColor = 0;
+
+ while (*p != '\0') {
+ row[numRows] = p;
+ ++numRows;
+ while ((*p != '\0') && (*p != '|')) {
+ ++p;
+ }
+ if (*p == '|') {
+ *p = '\0';
+ ++p;
+ }
+ }
+ for (uint i = 0; i < numRows; ++i) {
+ int rowWidth = textWidth(row[i]);
+ if (rowWidth > rowWidthMax)
+ rowWidthMax = rowWidth;
+ }
+
+ switch (position) {
+ case kMessageNormal:
+ x = 160 - rowWidthMax / 2;
+ textColor = kColorWhite99;
+ break;
+ case kMessageTop:
+ x = 160 - rowWidthMax / 2;
+ textColor = kColorLightYellow;
+ break;
+ case kMessageCenter:
+ x = 160 - rowWidthMax / 2;
+ textColor = kColorLightRed;
+ break;
+ case kMessageLeft:
+ x = 3;
+ textColor = kColorLightYellow;
+ break;
+ case kMessageRight:
+ x = 317 - rowWidthMax;
+ textColor = kColorLightGreen;
+ break;
+ }
+
+ if (position == kMessageNormal) {
+ y = 70 - ((numRows * 9) / 2);
+ } else if (position == kMessageTop) {
+ y = 5;
+ } else {
+ y = 142;
+ }
+
+ int message_columns = x - 3;
+ int message_rows = y - 3;
+ int message_width = rowWidthMax + 6;
+ int message_height = numRows * 9 + 5;
+ saveScreen(message_columns, message_rows, message_width, message_height);
+ renderBox(message_columns, message_rows, message_width, message_height, kColorWhite35);
+ for (uint i = 0; i < numRows; ++i) {
+ renderText(row[i], x, y, textColor);
+ y += 9;
+ }
+
+ _messageShown = true;
+ _gm->_messageDuration = (Common::strnlen(text, 512) + 20) * _vm->_textSpeed / 10;
+}
+
+void Screen::removeMessage() {
+ if (_messageShown) {
+ restoreScreen();
+ _messageShown = false;
+ }
+}
+
+void Screen::renderBox(int x, int y, int width, int height, byte color) {
+ Graphics::Surface *screen = _vm->_system->lockScreen();
+ screen->fillRect(Common::Rect(x, y, x + width, y + height), color);
+ _vm->_system->unlockScreen();
+}
+
+void Screen::renderBox(const GuiElement &guiElement) {
+ renderBox(guiElement.left, guiElement.top, guiElement.width(),
+ guiElement.height(), guiElement.getBackgroundColor());
+}
+
+void Screen::initPalette() {
+ g_system->getPaletteManager()->setPalette(initVGAPalette, 0, 256);
+}
+
+void Screen::paletteBrightness() {
+ byte palette[768];
+
+ _vm->_system->getPaletteManager()->grabPalette(palette, 0, 255);
+ for (uint i = 0; i < 48; ++i) {
+ palette[i] = (initVGAPalette[i] * _guiBrightness) >> 8;
+ }
+ for (uint i = 0; i < 717; ++i) {
+ const byte *imagePalette;
+ if (_currentImage && _currentImage->getPalette()) {
+ imagePalette = _currentImage->getPalette();
+ } else {
+ imagePalette = palette + 48;
+ }
+ palette[i + 48] = (imagePalette[i] * _viewportBrightness) >> 8;
+ }
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, 255);
+}
+
+void Screen::paletteFadeOut() {
+ while (_guiBrightness > 10) {
+ _guiBrightness -= 10;
+ if (_viewportBrightness > _guiBrightness)
+ _viewportBrightness = _guiBrightness;
+ paletteBrightness();
+ _vm->_system->updateScreen();
+ _vm->_system->delayMillis(_vm->_delay);
+ }
+ _guiBrightness = 0;
+ _viewportBrightness = 0;
+ paletteBrightness();
+ _vm->_system->updateScreen();
+}
+
+void Screen::paletteFadeIn() {
+ while (_guiBrightness < 245) {
+ if (_viewportBrightness < _gm->_roomBrightness)
+ _viewportBrightness += 10;
+ _guiBrightness += 10;
+ paletteBrightness();
+ _vm->_system->updateScreen();
+ _vm->_system->delayMillis(_vm->_delay);
+ }
+ _guiBrightness = 255;
+ _viewportBrightness = _gm->_roomBrightness;
+ paletteBrightness();
+ _vm->_system->updateScreen();
+}
+
+void Screen::setColor63(byte value) {
+ byte color[3] = {value, value, value};
+ _vm->_system->getPaletteManager()->setPalette(color, 63, 1);
+}
+
+}
diff --git a/engines/supernova/screen.h b/engines/supernova/screen.h
new file mode 100644
index 0000000000..d57fb53ed2
--- /dev/null
+++ b/engines/supernova/screen.h
@@ -0,0 +1,197 @@
+/* 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 SUPERNOVA_SCREEN_H
+#define SUPERNOVA_SCREEN_H
+
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/scummsys.h"
+
+#include "supernova/imageid.h"
+#include "supernova/msn_def.h"
+
+namespace Supernova {
+
+class SupernovaEngine;
+class GameManager;
+class ResourceManager;
+class GuiElement;
+class Room;
+class MSNImage;
+class Screen;
+
+const int kScreenWidth = 320;
+const int kScreenHeight = 200;
+const int kFontWidth = 5;
+const int kFontHeight = 8;
+
+enum Color {
+ kColorBlack = 0,
+ kColorWhite25 = 1,
+ kColorWhite35 = 2,
+ kColorWhite44 = 3,
+ kColorWhite99 = 4,
+ kColorDarkGreen = 5,
+ kColorGreen = 6,
+ kColorDarkRed = 7,
+ kColorRed = 8,
+ kColorDarkBlue = 9,
+ kColorBlue = 10,
+ kColorWhite63 = 11,
+ kColorLightBlue = 12,
+ kColorLightGreen = 13,
+ kColorLightYellow = 14,
+ kColorLightRed = 15,
+ kColorCursorTransparent = kColorWhite25
+};
+
+class ScreenBuffer {
+ friend class ScreenBufferStack;
+
+public:
+ ScreenBuffer();
+
+private:
+ byte *_pixels;
+ int _x;
+ int _y;
+ int _width;
+ int _height;
+};
+
+class ScreenBufferStack {
+public:
+ ScreenBufferStack();
+
+ void push(int x, int y, int width, int height);
+ void restore();
+
+private:
+ ScreenBuffer _buffer[8];
+ ScreenBuffer *_last;
+};
+
+class Marquee {
+public:
+ enum MarqueeId {
+ kMarqueeIntro,
+ kMarqueeOutro
+ };
+
+ Marquee(Screen *screen, MarqueeId id, const char *text);
+
+ void renderCharacter();
+
+private:
+ void clearText();
+
+ Screen *_screen;
+ const char *const _textBegin;
+ const char *_text;
+ bool _loop;
+ int _delay;
+ int _color;
+ int _x;
+ int _y;
+ int _textWidth;
+};
+
+class Screen {
+ friend class Marquee;
+
+public:
+ struct ImageInfo {
+ int filenumber;
+ int section;
+ };
+
+public:
+ static void initPalette();
+ static int textWidth(const uint16 key);
+ static int textWidth(const char *text);
+ static int textWidth(const Common::String &text);
+
+public:
+ Screen(SupernovaEngine *vm, GameManager *gm, ResourceManager *resMan);
+
+ int getViewportBrightness() const;
+ void setViewportBrightness(int brightness);
+ int getGuiBrightness() const;
+ void setGuiBrightness(int brightness);
+ const MSNImage *getCurrentImage() const;
+ bool isMessageShown() const;
+ void paletteFadeIn();
+ void paletteFadeOut();
+ void paletteBrightness();
+ void renderImage(ImageId id, bool removeImage = false);
+ void renderImage(int section);
+ bool setCurrentImage(int filenumber);
+ void saveScreen(int x, int y, int width, int height);
+ void saveScreen(const GuiElement &guiElement);
+ void restoreScreen();
+ void renderRoom(Room &room);
+ void renderMessage(const char *text, MessagePosition position = kMessageNormal);
+ void renderMessage(const Common::String &text, MessagePosition position = kMessageNormal);
+ void renderMessage(StringId stringId, MessagePosition position = kMessageNormal,
+ Common::String var1 = "", Common::String var2 = "");
+ void removeMessage();
+ void renderText(const uint16 character);
+ void renderText(const char *text);
+ void renderText(const Common::String &text);
+ void renderText(StringId stringId);
+ void renderText(const uint16 character, int x, int y, byte color);
+ void renderText(const char *text, int x, int y, byte color);
+ void renderText(const Common::String &text, int x, int y, byte color);
+ void renderText(StringId stringId, int x, int y, byte color);
+ void renderText(const GuiElement &guiElement);
+ void renderBox(int x, int y, int width, int height, byte color);
+ void renderBox(const GuiElement &guiElement);
+ void setColor63(byte value);
+ Common::Point getTextCursorPos();
+ void setTextCursorPos(int x, int y);
+ byte getTextCursorColor();
+ void setTextCursorColor(byte color);
+ void update();
+
+private:
+ void renderImageSection(const MSNImage *image, int section);
+
+private:
+ SupernovaEngine *_vm;
+ GameManager *_gm;
+ ResourceManager *_resMan;
+ const MSNImage *_currentImage;
+ ScreenBufferStack _screenBuffer;
+ int _screenWidth;
+ int _screenHeight;
+ int _textCursorX;
+ int _textCursorY;
+ int _textColor;
+ byte _viewportBrightness;
+ byte _guiBrightness;
+ bool _messageShown;
+};
+
+}
+
+#endif
diff --git a/engines/supernova/screenstatic.cpp b/engines/supernova/screenstatic.cpp
new file mode 100644
index 0000000000..db987bf2fb
--- /dev/null
+++ b/engines/supernova/screenstatic.cpp
@@ -0,0 +1,328 @@
+/* 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.
+*
+*/
+
+namespace Supernova {
+
+static const Screen::ImageInfo imageInfo[] = {
+ { 0, 0}, { 0, 1}, { 0, 2},
+ { 1, 0},
+ { 2, 0},
+ { 3, 0}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 3, 5},
+ { 3, 6}, { 3, 7}, { 3, 8}, { 3, 9}, { 3, 10}, { 3, 11},
+ { 4, 0}, { 4, 1}, { 4, 2}, { 4, 3},
+ { 5, 0}, { 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, { 5, 5},
+ { 5, 6}, { 5, 7}, { 5, 8}, { 5, 9},
+ { 6, 0}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 6, 5},
+ { 6, 6}, { 6, 7}, { 6, 8}, { 6, 9}, { 6, 10}, { 6, 11},
+ { 6, 12}, { 6, 13}, { 6, 14}, { 6, 15}, { 6, 16}, { 6, 17},
+ { 6, 18}, { 6, 19}, { 6, 20}, { 6, 21},
+ { 7, 0}, { 7, 1}, { 7, 2}, { 7, 3}, { 7, 4}, { 7, 5},
+ { 7, 6}, { 7, 7}, { 7, 8}, { 7, 9}, { 7, 10}, { 7, 11},
+ { 7, 12}, { 7, 13}, { 7, 14}, { 7, 15}, { 7, 16}, { 7, 17},
+ { 7, 18}, { 7, 19}, { 7, 20}, { 7, 21}, { 7, 22},
+ { 8, 0}, { 8, 1}, { 8, 2}, { 8, 3}, { 8, 4}, { 8, 5},
+ { 8, 6}, { 8, 7}, { 8, 8}, { 8, 9}, { 8, 10}, { 8, 11},
+ { 8, 12},
+ { 9, 0}, { 9, 1}, { 9, 2}, { 9, 3}, { 9, 4}, { 9, 5},
+ { 9, 6}, { 9, 7}, { 9, 8}, { 9, 9}, { 9, 10}, { 9, 11},
+ { 9, 12}, { 9, 13}, { 9, 14}, { 9, 15}, { 9, 16}, { 9, 17},
+ { 9, 18}, { 9, 19}, { 9, 20}, { 9, 21}, { 9, 22}, { 9, 23},
+ {10, 0}, {10, 1}, {10, 2}, {10, 3}, {10, 4}, {10, 5},
+ {10, 6}, {10, 7}, {10, 8}, {10, 9}, {10, 10}, {10, 11},
+ {10, 12}, {10, 13}, {10, 14}, {10, 15}, {10, 16},
+ {11, 0},
+ {12, 0}, {12, 1}, {12, 2}, {12, 3},
+ {13, 0}, {13, 1}, {13, 2}, {13, 3}, {13, 4}, {13, 5},
+ {13, 6}, {13, 7}, {13, 8}, {13, 9}, {13, 10}, {13, 11},
+ {13, 12}, {13, 13},
+ {14, 0}, {14, 1}, {14, 2}, {14, 3}, {14, 4}, {14, 5},
+ {14, 6}, {14, 7}, {14, 8}, {14, 9}, {14, 10}, {14, 11},
+ {14, 12}, {14, 13}, {14, 14}, {14, 15}, {14, 16}, {14, 17},
+ {14, 18}, {14, 19},
+ {15, 0}, {15, 1}, {15, 2}, {15, 3}, {15, 4}, {15, 5},
+ {16, 0}, {16, 1}, {16, 2}, {16, 3}, {16, 4}, {16, 5},
+ {16, 6}, {16, 7}, {16, 8}, {16, 9}, {16, 10}, {16, 11},
+ {16, 12}, {16, 13}, {16, 14}, {16, 15}, {16, 16}, {16, 17},
+ {16, 18}, {16, 19}, {16, 20}, {16, 21}, {16, 22}, {16, 23},
+ {16, 24}, {16, 25}, {16, 26}, {16, 27}, {16, 28}, {16, 29},
+ {16, 30}, {16, 31}, {16, 32}, {16, 33},
+ {17, 0}, {17, 1}, {17, 2}, {17, 3}, {17, 4}, {17, 5},
+ {17, 6}, {17, 7}, {17, 8}, {17, 9}, {17, 10}, {17, 11},
+ {17, 12}, {17, 13}, {17, 14}, {17, 15},
+ {18, 0}, {18, 1}, {18, 2}, {18, 3}, {18, 4}, {18, 5},
+ {18, 6}, {18, 7}, {18, 8}, {18, 9}, {18, 10}, {18, 11},
+ {18, 12}, {18, 13}, {18, 14}, {18, 15}, {18, 16}, {18, 17},
+ {18, 18}, {18, 19}, {18, 20}, {18, 21},
+ {19, 0}, {19, 1}, {19, 2}, {19, 3}, {19, 4}, {19, 5},
+ {19, 6}, {19, 7}, {19, 8}, {19, 9}, {19, 10}, {19, 11},
+ {19, 12}, {19, 13}, {19, 14}, {19, 15}, {19, 16}, {19, 17},
+ {19, 18}, {19, 19}, {19, 20}, {19, 21}, {19, 22}, {19, 23},
+ {19, 24}, {19, 25}, {19, 26}, {19, 27}, {19, 28}, {19, 29},
+ {19, 30}, {19, 31}, {19, 32}, {19, 33}, {19, 34}, {19, 35},
+ {19, 36}, {19, 37}, {19, 38}, {19, 39}, {19, 40},
+ {20, 0},
+ {21, 0}, {21, 1}, {21, 2}, {21, 3}, {21, 4}, {21, 5},
+ {21, 6}, {21, 7}, {21, 8}, {21, 9}, {21, 10}, {21, 11},
+ {21, 12}, {21, 13}, {21, 14}, {21, 15}, {21, 16}, {21, 17},
+ {21, 18}, {21, 19}, {21, 20}, {21, 21}, {21, 22}, {21, 23},
+ {21, 24}, {21, 25}, {21, 26}, {21, 27}, {21, 28}, {21, 29},
+ {21, 30}, {21, 31}, {21, 32}, {21, 33}, {21, 34}, {21, 35},
+ {21, 36}, {21, 37}, {21, 38},
+ {22, 0}, {22, 1}, {22, 2}, {22, 3}, {22, 4}, {22, 5},
+ {22, 6}, {22, 7}, {22, 8}, {22, 9}, {22, 10}, {22, 11},
+ {22, 12}, {22, 13}, {22, 14}, {22, 15}, {22, 16}, {22, 17},
+ {22, 18},
+ {23, 0},
+ {24, 0}, {24, 1}, {24, 2}, {24, 3}, {24, 4}, {24, 5},
+ {24, 6}, {24, 7}, {24, 8},
+ {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
+ {25, 6}, {25, 7}, {25, 8}, {25, 9}, {25, 10}, {25, 11},
+ {25, 12}, {25, 13}, {25, 14}, {25, 15}, {25, 16}, {25, 17},
+ {25, 18},
+ {26, 0},
+ {27, 0},
+ {28, 0}, {28, 1}, {28, 2}, {28, 3}, {28, 4}, {28, 5},
+ {28, 6}, {28, 7}, {28, 8}, {28, 9}, {28, 10}, {28, 11},
+ {28, 12}, {28, 13}, {28, 14}, {28, 15}, {28, 16}, {28, 17},
+ {28, 18}, {28, 19}, {28, 20}, {28, 21}, {28, 22},
+ {29, 0}, {29, 1}, {29, 2}, {29, 3}, {29, 4}, {29, 5},
+ {29, 6}, {29, 7}, {29, 8}, {29, 9}, {29, 10}, {29, 11},
+ {29, 12}, {29, 13},
+ {30, 0}, {30, 1},
+ {31, 0}, {31, 1}, {31, 2}, {31, 3}, {31, 4}, {31, 5},
+ {31, 6},
+ {32, 0}, {32, 1}, {32, 2}, {32, 3},
+ {33, 0}, {33, 1}, {33, 2}, {33, 3}, {33, 4}, {33, 5},
+ {34, 0}, {34, 1}, {34, 2}, {34, 3}, {34, 4}, {34, 5},
+ {34, 6}, {34, 7}, {34, 8}, {34, 9}, {34, 10}, {34, 11},
+ {34, 12}, {34, 13}, {34, 14}, {34, 15}, {34, 16}, {34, 17},
+ {35, 0}, {35, 1}, {35, 2}, {35, 3}, {35, 4}, {35, 5},
+ {35, 6}, {35, 7}, {35, 8}, {35, 9}, {35, 10}, {35, 11},
+ {35, 12}, {35, 13}, {35, 14}, {35, 15}, {35, 16}, {35, 17},
+ {35, 18}, {35, 19}, {35, 20}, {35, 21},
+ {36, 0}, {36, 1}, {36, 2}, {36, 3}, {36, 4}, {36, 5},
+ {37, 0}, {37, 1}, {37, 2}, {37, 3}, {37, 4}, {37, 5},
+ {37, 6}, {37, 7}, {37, 8}, {37, 9}, {37, 10}, {37, 11},
+ {37, 12}, {37, 13}, {37, 14}, {37, 15}, {37, 16}, {37, 17},
+ {37, 18}, {37, 19}, {37, 20}, {37, 21}, {37, 22}, {37, 23},
+ {37, 24}, {37, 25}, {37, 26},
+ {38, 0}, {38, 1}, {38, 2}, {38, 3}, {38, 4}, {38, 5},
+ {38, 6}, {38, 7}, {38, 8}, {38, 9}, {38, 10}, {38, 11},
+ {38, 12},
+ {39, 0},
+ {40, 0}, {40, 1}, {40, 2}, {40, 3}, {40, 4}, {40, 5},
+ {40, 6}, {40, 7},
+ {41, 0}, {41, 1}, {41, 2}, {41, 3},
+ {42, 0}, {42, 1}, {42, 2}, {42, 3}, {42, 4}, {42, 5},
+ {42, 6}, {42, 7}, {42, 8}, {42, 9}, {42, 10}, {42, 11},
+ {43, 0}, {43, 1}, {43, 2}, {43, 3}, {43, 4}, {43, 5},
+ {43, 6}, {43, 7}, {43, 8}, {43, 9}, {43, 10}, {43, 11},
+ {43, 12}, {43, 13}, {43, 14}, {43, 15}, {43, 16}, {43, 17},
+ {43, 18}, {43, 19}, {43, 20}, {43, 21}, {43, 22}, {43, 23},
+ {43, 24}, {43, 25}, {43, 26}, {43, 27}, {43, 28}, {43, 29},
+ {43, 30}, {43, 31}
+};
+
+// Default palette
+static const byte initVGAPalette[768] = {
+ 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x58, 0x58, 0x58, 0x70, 0x70, 0x70, 0xfc, 0xfc, 0xfc, 0x00, 0xd0, 0x00,
+ 0x00, 0xfc, 0x00, 0xd8, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0xb0, 0xa0, 0xa0, 0xa0,
+ 0x50, 0xc8, 0xfc, 0x28, 0xfc, 0x28, 0xf0, 0xf0, 0x00, 0xfc, 0x28, 0x28, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14,
+ 0x20, 0x20, 0x20, 0x2c, 0x2c, 0x2c, 0x38, 0x38, 0x38, 0x44, 0x44, 0x44, 0x50, 0x50, 0x50, 0x60, 0x60, 0x60,
+ 0x70, 0x70, 0x70, 0x80, 0x80, 0x80, 0x90, 0x90, 0x90, 0xa0, 0xa0, 0xa0, 0xb4, 0xb4, 0xb4, 0xc8, 0xc8, 0xc8,
+ 0xe0, 0xe0, 0xe0, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00, 0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc,
+ 0xfc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc, 0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00,
+ 0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc, 0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x00,
+ 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x00, 0xfc, 0x7c, 0x00, 0xfc, 0xbc, 0x00, 0xfc, 0xfc, 0x00, 0xbc, 0xfc,
+ 0x00, 0x7c, 0xfc, 0x00, 0x40, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c, 0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc,
+ 0xfc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc, 0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c,
+ 0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc, 0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0x7c,
+ 0x7c, 0xfc, 0x7c, 0x7c, 0xfc, 0x9c, 0x7c, 0xfc, 0xbc, 0x7c, 0xfc, 0xdc, 0x7c, 0xfc, 0xfc, 0x7c, 0xdc, 0xfc,
+ 0x7c, 0xbc, 0xfc, 0x7c, 0x9c, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4, 0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc,
+ 0xfc, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc, 0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4,
+ 0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc, 0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0xb4,
+ 0xb4, 0xfc, 0xb4, 0xb4, 0xfc, 0xc4, 0xb4, 0xfc, 0xd8, 0xb4, 0xfc, 0xe8, 0xb4, 0xfc, 0xfc, 0xb4, 0xe8, 0xfc,
+ 0xb4, 0xd8, 0xfc, 0xb4, 0xc4, 0xfc, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70,
+ 0x70, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70, 0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x00, 0x00, 0x70, 0x1c, 0x00,
+ 0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70, 0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x00,
+ 0x00, 0x70, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x70, 0x38, 0x00, 0x70, 0x54, 0x00, 0x70, 0x70, 0x00, 0x54, 0x70,
+ 0x00, 0x38, 0x70, 0x00, 0x1c, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38, 0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70,
+ 0x70, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70, 0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38,
+ 0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70, 0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x38,
+ 0x38, 0x70, 0x38, 0x38, 0x70, 0x44, 0x38, 0x70, 0x54, 0x38, 0x70, 0x60, 0x38, 0x70, 0x70, 0x38, 0x60, 0x70,
+ 0x38, 0x54, 0x70, 0x38, 0x44, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50, 0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70,
+ 0x70, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70, 0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50,
+ 0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70, 0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x50,
+ 0x50, 0x70, 0x50, 0x50, 0x70, 0x58, 0x50, 0x70, 0x60, 0x50, 0x70, 0x68, 0x50, 0x70, 0x70, 0x50, 0x68, 0x70,
+ 0x50, 0x60, 0x70, 0x50, 0x58, 0x70, 0x00, 0x00, 0x40, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40,
+ 0x40, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40, 0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x00, 0x00, 0x40, 0x10, 0x00,
+ 0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40, 0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x00,
+ 0x00, 0x40, 0x00, 0x00, 0x40, 0x10, 0x00, 0x40, 0x20, 0x00, 0x40, 0x30, 0x00, 0x40, 0x40, 0x00, 0x30, 0x40,
+ 0x00, 0x20, 0x40, 0x00, 0x10, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20, 0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40,
+ 0x40, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40, 0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20,
+ 0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40, 0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x20,
+ 0x20, 0x40, 0x20, 0x20, 0x40, 0x28, 0x20, 0x40, 0x30, 0x20, 0x40, 0x38, 0x20, 0x40, 0x40, 0x20, 0x38, 0x40,
+ 0x20, 0x30, 0x40, 0x20, 0x28, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c, 0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40,
+ 0x40, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40, 0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c,
+ 0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40, 0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x2c,
+ 0x2c, 0x40, 0x2c, 0x2c, 0x40, 0x30, 0x2c, 0x40, 0x34, 0x2c, 0x40, 0x3c, 0x2c, 0x40, 0x40, 0x2c, 0x3c, 0x40,
+ 0x2c, 0x34, 0x40, 0x2c, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const byte font[][5] = {
+ {0x00,0x00,0x00,0xff,0x00},
+ {0x5f,0xff,0x00,0x00,0x00},
+ {0x03,0x00,0x03,0xff,0x00},
+ {0x14,0x7f,0x14,0x7f,0x14},
+ {0x24,0x2a,0x7f,0x2a,0x12},
+ {0x61,0x10,0x08,0x04,0x43},
+ {0x38,0x4e,0x59,0x26,0x50},
+ {0x03,0xff,0x00,0x00,0x00},
+ {0x3e,0x41,0xff,0x00,0x00},
+ {0x41,0x3e,0xff,0x00,0x00},
+ {0x10,0x54,0x38,0x54,0x10},
+ {0x10,0x10,0x7c,0x10,0x10},
+ {0x80,0x40,0xff,0x00,0x00},
+ {0x10,0x10,0x10,0x10,0x10},
+ {0x40,0xff,0x00,0x00,0x00},
+ {0x60,0x10,0x08,0x04,0x03},
+
+ {0x3e,0x41,0x41,0x41,0x3e}, /* digits */
+ {0x04,0x02,0x7f,0xff,0x00},
+ {0x42,0x61,0x51,0x49,0x46},
+ {0x22,0x41,0x49,0x49,0x36},
+ {0x18,0x14,0x12,0x7f,0x10},
+ {0x27,0x45,0x45,0x45,0x39},
+ {0x3e,0x49,0x49,0x49,0x32},
+ {0x01,0x61,0x19,0x07,0x01},
+ {0x36,0x49,0x49,0x49,0x36},
+ {0x26,0x49,0x49,0x49,0x3e},
+
+ {0x44,0xff,0x00,0x00,0x00},
+ {0x80,0x44,0xff,0x00,0x00},
+ {0x10,0x28,0x44,0xff,0x00},
+ {0x28,0x28,0x28,0x28,0x28},
+ {0x44,0x28,0x10,0xff,0x00},
+ {0x02,0x01,0x51,0x09,0x06},
+ {0x3e,0x41,0x5d,0x5d,0x1e},
+
+ {0x7c,0x12,0x11,0x12,0x7c}, /* uppercase letters*/
+ {0x7f,0x49,0x49,0x49,0x36},
+ {0x3e,0x41,0x41,0x41,0x22},
+ {0x7f,0x41,0x41,0x22,0x1c},
+ {0x7f,0x49,0x49,0x49,0xff},
+ {0x7f,0x09,0x09,0x09,0xff},
+ {0x3e,0x41,0x41,0x49,0x3a},
+ {0x7f,0x08,0x08,0x08,0x7f},
+ {0x41,0x7f,0x41,0xff,0x00},
+ {0x20,0x40,0x40,0x3f,0xff},
+ {0x7f,0x08,0x14,0x22,0x41},
+ {0x7f,0x40,0x40,0x40,0xff},
+ {0x7f,0x02,0x04,0x02,0x7f},
+ {0x7f,0x02,0x0c,0x10,0x7f},
+ {0x3e,0x41,0x41,0x41,0x3e},
+ {0x7f,0x09,0x09,0x09,0x06},
+ {0x3e,0x41,0x51,0x21,0x5e},
+ {0x7f,0x09,0x19,0x29,0x46},
+ {0x26,0x49,0x49,0x49,0x32},
+ {0x01,0x01,0x7f,0x01,0x01},
+ {0x3f,0x40,0x40,0x40,0x3f},
+ {0x07,0x18,0x60,0x18,0x07},
+ {0x1f,0x60,0x18,0x60,0x1f},
+ {0x63,0x14,0x08,0x14,0x63},
+ {0x03,0x04,0x78,0x04,0x03},
+ {0x61,0x51,0x49,0x45,0x43},
+
+ {0x7f,0x41,0x41,0xff,0x00},
+ {0x03,0x04,0x08,0x10,0x60},
+ {0x41,0x41,0x7f,0xff,0x00},
+ {0x02,0x01,0x02,0xff,0x00},
+ {0x80,0x80,0x80,0x80,0x80},
+ {0x01,0x02,0xff,0x00,0x00},
+
+ {0x38,0x44,0x44,0x44,0x7c}, /* lowercase letters */
+ {0x7f,0x44,0x44,0x44,0x38},
+ {0x38,0x44,0x44,0x44,0x44},
+ {0x38,0x44,0x44,0x44,0x7f},
+ {0x38,0x54,0x54,0x54,0x58},
+ {0x04,0x7e,0x05,0x01,0xff},
+ {0x98,0xa4,0xa4,0xa4,0x7c},
+ {0x7f,0x04,0x04,0x04,0x78},
+ {0x7d,0xff,0x00,0x00,0x00},
+ {0x80,0x80,0x7d,0xff,0x00},
+ {0x7f,0x10,0x28,0x44,0xff},
+ {0x7f,0xff,0x00,0x00,0x00},
+ {0x7c,0x04,0x7c,0x04,0x78},
+ {0x7c,0x04,0x04,0x04,0x78},
+ {0x38,0x44,0x44,0x44,0x38},
+ {0xfc,0x24,0x24,0x24,0x18},
+ {0x18,0x24,0x24,0x24,0xfc},
+ {0x7c,0x08,0x04,0x04,0xff},
+ {0x48,0x54,0x54,0x54,0x24},
+ {0x04,0x3e,0x44,0x40,0xff},
+ {0x7c,0x40,0x40,0x40,0x3c},
+ {0x0c,0x30,0x40,0x30,0x0c},
+ {0x3c,0x40,0x3c,0x40,0x3c},
+ {0x44,0x28,0x10,0x28,0x44},
+ {0x9c,0xa0,0xa0,0xa0,0x7c},
+ {0x44,0x64,0x54,0x4c,0x44},
+
+ {0x08,0x36,0x41,0xff,0x00},
+ {0x77,0xff,0x00,0x00,0x00},
+ {0x41,0x36,0x08,0xff,0x00},
+ {0x02,0x01,0x02,0x01,0xff},
+ {0xff,0x00,0x00,0x00,0x00},
+
+ {0xfe,0x49,0x49,0x4e,0x30}, /* sharp S */
+
+ {0x7c,0x41,0x40,0x41,0x3c}, /* umlauts */
+
+ {0x04,0x06,0x7f,0x06,0x04}, /* arrows */
+ {0x20,0x60,0xfe,0x60,0x20},
+
+ {0x38,0x45,0x44,0x45,0x7c}, /* umlauts */
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0x79,0x14,0x12,0x14,0x79},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0x38,0x45,0x44,0x45,0x38},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0xff,0x00,0x00,0x00,0x00},
+ {0x3d,0x42,0x42,0x42,0x3d},
+ {0x3d,0x40,0x40,0x40,0x3d},
+};
+
+}
diff --git a/engines/supernova/sound.cpp b/engines/supernova/sound.cpp
new file mode 100644
index 0000000000..e7f3ce83bd
--- /dev/null
+++ b/engines/supernova/sound.cpp
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/raw.h"
+#include "audio/mods/protracker.h"
+#include "common/system.h"
+
+#include "supernova/resman.h"
+#include "supernova/sound.h"
+#include "supernova/supernova.h"
+
+namespace Supernova {
+
+Sound::Sound(Audio::Mixer *mixer, ResourceManager *resMan)
+ : _mixer(mixer)
+ , _resMan(resMan) {
+}
+
+void Sound::play(AudioId index) {
+ Audio::AudioStream *stream = _resMan->getSoundStream(index);
+
+ stop();
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, stream,
+ -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+}
+
+void Sound::play(MusicId index) {
+ Audio::AudioStream *stream = _resMan->getSoundStream(index);
+
+ stop();
+ _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, stream,
+ -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+}
+
+bool Sound::isPlaying() {
+ return _mixer->isSoundHandleActive(_soundHandle);
+}
+
+void Sound::stop() {
+ if (_mixer->isSoundHandleActive(_soundHandle))
+ _mixer->stopHandle(_soundHandle);
+}
+
+}
diff --git a/engines/supernova/sound.h b/engines/supernova/sound.h
new file mode 100644
index 0000000000..100c9a372b
--- /dev/null
+++ b/engines/supernova/sound.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SUPERNOVA_SOUND_H
+#define SUPERNOVA_SOUND_H
+
+#include "audio/mixer.h"
+
+namespace Supernova {
+
+class SupernovaEngine;
+class ResourceManager;
+
+enum AudioId {
+ kAudioFoundLocation, // 44|0
+ kAudioCrash, // 45|0
+ kAudioVoiceHalt, // 46|0
+ kAudioGunShot, // 46|2510
+ kAudioSmash, // 46|4020
+ kAudioVoiceSupernova, // 47|0
+ kAudioVoiceYeah, // 47|24010
+ kAudioRobotShock, // 48|0
+ kAudioRobotBreaks, // 48|2510
+ kAudioShock, // 48|10520
+ kAudioTurntable, // 48|13530
+ kAudioSiren, // 50|0
+ kAudioSnoring, // 50|12786
+ kAudioRocks, // 51|0
+ kAudioDeath, // 53|0
+ kAudioAlarm, // 54|0
+ kAudioSuccess, // 54|8010
+ kAudioSlideDoor, // 54|24020
+ kAudioDoorOpen, // 54|30030
+ kAudioDoorClose, // 54|31040
+ kAudioNumSamples
+};
+
+enum MusicId {
+ kMusicIntro = 49,
+ kMusicOutro = 52
+};
+
+class Sound {
+public:
+
+public:
+ Sound(Audio::Mixer *mixer, ResourceManager *resMan);
+
+ void play(AudioId index);
+ void play(MusicId index);
+ void stop();
+ bool isPlaying();
+private:
+ Audio::Mixer *_mixer;
+ ResourceManager *_resMan;
+ Audio::SoundHandle _soundHandle;
+};
+
+}
+
+#endif
diff --git a/engines/supernova/state.cpp b/engines/supernova/state.cpp
index e41edbf1d5..00a35055b7 100644
--- a/engines/supernova/state.cpp
+++ b/engines/supernova/state.cpp
@@ -21,11 +21,13 @@
*/
#include "common/system.h"
+#include "graphics/cursorman.h"
#include "graphics/palette.h"
#include "gui/message.h"
+
+#include "supernova/screen.h"
#include "supernova/supernova.h"
#include "supernova/state.h"
-#include "graphics/cursorman.h"
namespace Supernova {
@@ -136,13 +138,13 @@ bool GameManager::deserialize(Common::ReadStream *in, int version) {
_inventoryScroll = in->readSint32LE();
_inventory.clear();
for (int i = 0; i < inventorySize; ++i) {
- RoomID objectRoom = static_cast<RoomID>(in->readSint32LE());
+ RoomId objectRoom = static_cast<RoomId>(in->readSint32LE());
int objectIndex = in->readSint32LE();
_inventory.add(*_rooms[objectRoom]->getObject(objectIndex));
}
// Rooms
- RoomID curRoomId = static_cast<RoomID>(in->readByte());
+ RoomId curRoomId = static_cast<RoomId>(in->readByte());
for (int i = 0; i < NUMROOMS; ++i) {
_rooms[i]->deserialize(in, version);
}
@@ -194,16 +196,16 @@ Object *Inventory::get(int index) const {
if (index < _numObjects)
return _inventory[index];
- return const_cast<Object *>(&Object::nullObject);
+ return _nullObject;
}
-Object *Inventory::get(ObjectID id) const {
+Object *Inventory::get(ObjectId id) const {
for (int i = 0; i < _numObjects; ++i) {
if (_inventory[i]->_id == id)
return _inventory[i];
}
- return const_cast<Object *>(&Object::nullObject);
+ return _nullObject;
}
@@ -275,19 +277,20 @@ static Common::String timeToString(int msec) {
return Common::String(s);
}
-StringID GameManager::guiCommands[] = {
+StringId GameManager::guiCommands[] = {
kStringCommandGo, kStringCommandLook, kStringCommandTake, kStringCommandOpen, kStringCommandClose,
kStringCommandPress, kStringCommandPull, kStringCommandUse, kStringCommandTalk, kStringCommandGive
};
-StringID GameManager::guiStatusCommands[] = {
+StringId GameManager::guiStatusCommands[] = {
kStringStatusCommandGo, kStringStatusCommandLook, kStringStatusCommandTake, kStringStatusCommandOpen, kStringStatusCommandClose,
kStringStatusCommandPress, kStringStatusCommandPull, kStringStatusCommandUse, kStringStatusCommandTalk, kStringStatusCommandGive
};
-GameManager::GameManager(SupernovaEngine *vm)
- : _inventory(_inventoryScroll)
- , _vm(vm) {
+GameManager::GameManager(SupernovaEngine *vm, Sound *sound)
+ : _inventory(&_nullObject, _inventoryScroll)
+ , _vm(vm)
+ , _sound(sound) {
initRooms();
changeRoom(INTRO);
initState();
@@ -351,11 +354,10 @@ void GameManager::destroyRooms() {
delete _rooms[OUTRO];
}
-
void GameManager::initState() {
- Object::setObjectNull(_currentInputObject);
- Object::setObjectNull(_inputObject[0]);
- Object::setObjectNull(_inputObject[1]);
+ _currentInputObject = &_nullObject;
+ _inputObject[0] = &_nullObject;
+ _inputObject[1] = &_nullObject;
_inputVerb = ACTION_WALK;
_processInput = false;
_guiEnabled = true;
@@ -370,7 +372,7 @@ void GameManager::initState() {
_oldTime = g_system->getMillis();
_timerPaused = 0;
_timePaused = false;
- _timer1 = 0;
+ _messageDuration = 0;
_animationTimer = 0;
_currentSentence = -1;
@@ -466,7 +468,7 @@ void GameManager::initGui() {
int cmdAvailableSpace = 320 - (cmdCount - 1) * 2;
for (int i = 0; i < cmdCount; ++i) {
const Common::String &text = _vm->getGameString(guiCommands[i]);
- cmdAvailableSpace -= _vm->textWidth(text);
+ cmdAvailableSpace -= Screen::textWidth(text);
}
int commandButtonX = 0;
@@ -476,7 +478,7 @@ void GameManager::initGui() {
if (i < cmdCount - 1) {
int space = cmdAvailableSpace / (cmdCount - i);
cmdAvailableSpace -= space;
- width = _vm->textWidth(text) + space;
+ width = Screen::textWidth(text) + space;
} else
width = 320 - commandButtonX;
@@ -503,6 +505,75 @@ void GameManager::initGui() {
_guiInventoryArrow[1].setTextPosition(273, 186);
}
+void GameManager::updateEvents() {
+ handleTime();
+ if (_animationEnabled && !_vm->_screen->isMessageShown() && _animationTimer == 0)
+ _currentRoom->animation();
+
+ if (_state._eventCallback != kNoFn && _state._time >= _state._eventTime) {
+ _vm->_allowLoadGame = false;
+ _vm->_allowSaveGame = false;
+ _state._eventTime = kMaxTimerValue;
+ EventFunction fn = _state._eventCallback;
+ _state._eventCallback = kNoFn;
+ switch (fn) {
+ case kNoFn:
+ break;
+ case kSupernovaFn:
+ supernovaEvent();
+ break;
+ case kGuardReturnedFn:
+ guardReturnedEvent();
+ break;
+ case kGuardWalkFn:
+ guardWalkEvent();
+ break;
+ case kTaxiFn:
+ taxiEvent();
+ break;
+ case kSearchStartFn:
+ searchStartEvent();
+ break;
+ }
+ _vm->_allowLoadGame = true;
+ _vm->_allowSaveGame = true;
+ return;
+ }
+
+ if (_state._alarmOn && _state._timeAlarm <= _state._time) {
+ _state._alarmOn = false;
+ alarm();
+ return;
+ }
+
+ _mouseClicked = false;
+ _keyPressed = false;
+ Common::Event event;
+ while (g_system->getEventManager()->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ _keyPressed = true;
+ processInput(event.kbd);
+ break;
+ case Common::EVENT_LBUTTONUP:
+ // fallthrough
+ case Common::EVENT_RBUTTONUP:
+ if (_currentRoom->getId() != INTRO && _sound->isPlaying())
+ return;
+ _mouseClicked = true;
+ // fallthrough
+ case Common::EVENT_MOUSEMOVE:
+ _mouseClickType = event.type;
+ _mouseX = event.mouse.x;
+ _mouseY = event.mouse.y;
+ if (_guiEnabled)
+ processInput();
+ break;
+ default:
+ break;
+ }
+ }
+}
void GameManager::processInput(Common::KeyState &state) {
_key = state;
@@ -529,14 +600,18 @@ void GameManager::processInput(Common::KeyState &state) {
_vm->quitGame();
}
break;
+ case Common::KEYCODE_d:
+ if (state.flags & Common::KBD_CTRL)
+ _vm->_console->attach();
+ break;
default:
break;
}
}
void GameManager::resetInputState() {
- Object::setObjectNull(_inputObject[0]);
- Object::setObjectNull(_inputObject[1]);
+ setObjectNull(_inputObject[0]);
+ setObjectNull(_inputObject[1]);
_inputVerb = ACTION_WALK;
_processInput = false;
_mouseClicked = false;
@@ -571,7 +646,7 @@ void GameManager::processInput() {
mouseLocation = onNone;
if (_mouseClickType == Common::EVENT_LBUTTONUP) {
- if (_vm->_messageDisplayed) {
+ if (_vm->_screen->isMessageShown()) {
// Hide the message and consume the event
_vm->removeMessage();
if (mouseLocation != onCmdButton)
@@ -583,7 +658,7 @@ void GameManager::processInput() {
case onInventory:
// Fallthrough
if (_inputVerb == ACTION_GIVE || _inputVerb == ACTION_USE) {
- if (Object::isNullObject(_inputObject[0])) {
+ if (isNullObject(_inputObject[0])) {
_inputObject[0] = _currentInputObject;
if (!_inputObject[0]->hasProperty(COMBINABLE))
_processInput = true;
@@ -593,7 +668,7 @@ void GameManager::processInput() {
}
} else {
_inputObject[0] = _currentInputObject;
- if (!Object::isNullObject(_currentInputObject))
+ if (!isNullObject(_currentInputObject))
_processInput = true;
}
break;
@@ -614,13 +689,13 @@ void GameManager::processInput() {
}
} else if (_mouseClickType == Common::EVENT_RBUTTONUP) {
- if (_vm->_messageDisplayed) {
+ if (_vm->_screen->isMessageShown()) {
// Hide the message and consume the event
_vm->removeMessage();
return;
}
- if (Object::isNullObject(_currentInputObject))
+ if (isNullObject(_currentInputObject))
return;
if (mouseLocation == onObject || mouseLocation == onInventory) {
@@ -666,8 +741,9 @@ void GameManager::processInput() {
for (int i = 0; (_currentRoom->getObject(i)->_id != INVALIDOBJECT) &&
(field == -1) && i < kMaxObject; i++) {
click = _currentRoom->getObject(i)->_click;
- if (click != 255 && _vm->_currentImage) {
- MSNImageDecoder::ClickField *clickField = _vm->_currentImage->_clickField;
+ const MSNImage *image = _vm->_screen->getCurrentImage();
+ if (click != 255 && image) {
+ const MSNImage::ClickField *clickField = image->_clickField;
do {
if ((_mouseX >= clickField[click].x1) && (_mouseX <= clickField[click].x2) &&
(_mouseY >= clickField[click].y1) && (_mouseY <= clickField[click].y2))
@@ -698,7 +774,7 @@ void GameManager::processInput() {
break;
}
- Object::setObjectNull(_currentInputObject);
+ setObjectNull(_currentInputObject);
_mouseField = field;
if (_mouseField >= 0 && _mouseField < 256)
@@ -737,6 +813,14 @@ void GameManager::processInput() {
}
}
+void GameManager::setObjectNull(Object *&obj) {
+ obj = &_nullObject;
+}
+
+bool GameManager::isNullObject(Object *obj) {
+ return obj == &_nullObject;
+}
+
void GameManager::corridorOnEntrance() {
if (_state._corridorSearch)
busted(0);
@@ -761,7 +845,7 @@ void GameManager::telomat(int nr) {
"Alga Hurz Li"
};
- StringID dial1[4];
+ StringId dial1[4];
dial1[0] = kStringTelomat1;
dial1[1] = kNoString;
dial1[2] = kStringTelomat3;
@@ -769,7 +853,7 @@ void GameManager::telomat(int nr) {
static byte rows1[3] = {1, 2, 1};
- StringID dial2[4];
+ StringId dial2[4];
dial2[0] = kStringTelomat4;
dial2[1] = kStringTelomat5;
dial2[2] = kStringTelomat6;
@@ -813,7 +897,7 @@ void GameManager::telomat(int nr) {
i >>= 1;
if (i == 4) {
_vm->renderText(kStringTelomat14, 50, 120, kColorGreen);
- wait2(10);
+ wait(10);
_vm->renderBox(0, 0, 320, 200, kColorBlack);
_vm->renderRoom(*_currentRoom);
_vm->paletteBrightness();
@@ -824,7 +908,7 @@ void GameManager::telomat(int nr) {
if ((i == nr) || _rooms[BCORRIDOR]->getObject(4 + i)->hasProperty(CAUGHT)) {
_vm->renderText(kStringTelomat15, 50, 120, kColorGreen);
- wait2(10);
+ wait(10);
_vm->renderBox(0, 0, 320, 200, kColorBlack);
_vm->renderRoom(*_currentRoom);
_vm->paletteBrightness();
@@ -834,12 +918,12 @@ void GameManager::telomat(int nr) {
}
_vm->renderText(kStringTelomat16, 50, 120, kColorGreen);
- wait2(10);
+ wait(10);
_vm->renderBox(0, 0, 320, 200, kColorBlack);
_vm->renderRoom(*_currentRoom);
_vm->paletteBrightness();
_vm->renderMessage(kStringTelomat17, kMessageTop, name2[i]);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
if (_state._nameSeen[nr]) {
Common::String string = _vm->getGameString(kStringTelomat2);
@@ -851,7 +935,7 @@ void GameManager::telomat(int nr) {
switch (dialog(3, rows1, dial1, 1)) {
case 1: _vm->renderMessage(kStringTelomat18, kMessageTop);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
if ((_state._destination == 255) && !_rooms[BCORRIDOR]->isSectionVisible(7)) {
_state._eventTime = _state._time + ticksToMsec(150);
@@ -861,10 +945,10 @@ void GameManager::telomat(int nr) {
}
break;
case 0: _vm->renderMessage(kStringTelomat19, kMessageTop);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
if (dialog(4, rows2, dial2, 0) != 3) {
- wait2(10);
+ wait(10);
say(kStringTelomat20);
}
_rooms[BCORRIDOR]->setSectionVisible(7, true);
@@ -888,7 +972,7 @@ void GameManager::telomat(int nr) {
if (_key.keycode == Common::KEYCODE_RETURN) {
_vm->renderText(kStringShipSleepCabin9, 100, 120, kColorGreen);
- wait2(10);
+ wait(10);
}
// fallthrough
case Common::KEYCODE_ESCAPE:
@@ -926,7 +1010,7 @@ void GameManager::guardNoticed() {
_vm->paletteFadeIn();
_vm->renderImage(2);
reply(kStringGuardNoticed1, 2, 5);
- wait2(2);
+ wait(2);
reply(kStringGuardNoticed2, 2, 5);
_vm->paletteFadeOut();
_currentRoom->setSectionVisible(2, false);
@@ -947,19 +1031,19 @@ void GameManager::busted(int i) {
i = 5;
if (!_currentRoom->getObject(0)->hasProperty(OPENED)) {
_vm->renderImage(i - 1);
- _vm->playSound(kAudioDoorOpen);
- wait2(2);
+ _sound->play(kAudioDoorOpen);
+ wait(2);
}
_vm->renderImage(i);
- wait2(3);
+ wait(3);
_vm->renderImage(i + 3);
- _vm->playSound(kAudioVoiceHalt);
+ _sound->play(kAudioVoiceHalt);
_vm->renderImage(i);
- wait2(5);
+ wait(5);
if (_currentRoom->getId() == OFFICE_L2)
i = 13;
_vm->renderImage(i + 1);
- wait2(3);
+ wait(3);
_vm->renderImage(i + 2);
shot(0, 0);
} else if (_currentRoom->getId() == BCORRIDOR)
@@ -973,8 +1057,8 @@ void GameManager::busted(int i) {
else
_vm->renderImage(33); // above
}
- _vm->playSound(kAudioVoiceHalt);
- wait2(3);
+ _sound->play(kAudioVoiceHalt);
+ wait(3);
shot(0, 0);
}
@@ -1025,7 +1109,7 @@ void GameManager::supernovaEvent() {
CursorMan.showMouse(false);
if (_currentRoom->getId() <= CAVE) {
_vm->renderMessage(kStringSupernova1);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
_vm->paletteFadeOut();
changeRoom(MEETUP);
@@ -1038,7 +1122,7 @@ void GameManager::supernovaEvent() {
_vm->paletteFadeIn();
}
_vm->renderMessage(kStringSupernova2);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
_vm->setCurrentImage(26);
_vm->renderImage(0);
@@ -1046,28 +1130,28 @@ void GameManager::supernovaEvent() {
novaScroll();
_vm->paletteFadeOut();
_vm->renderBox(0, 0, 320, 200, kColorBlack);
- _vm->_menuBrightness = 255;
+ _vm->_screen->setGuiBrightness(255);
_vm->paletteBrightness();
if (_currentRoom->getId() == GLIDER) {
_vm->renderMessage(kStringSupernova3);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
- _vm->_menuBrightness = 0;
+ _vm->_screen->setGuiBrightness(0);
_vm->paletteBrightness();
_vm->renderRoom(*_currentRoom);
_vm->paletteFadeIn();
_vm->renderMessage(kStringSupernova4, kMessageTop);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
_vm->renderMessage(kStringSupernova5, kMessageTop);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
_vm->renderMessage(kStringSupernova6, kMessageTop);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
_vm->renderMessage(kStringSupernova7, kMessageTop);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
changeRoom(MEETUP2);
_rooms[MEETUP2]->setSectionVisible(1, true);
@@ -1077,9 +1161,9 @@ void GameManager::supernovaEvent() {
_inventory.remove(*(_rooms[ROGER]->getObject(8)));
} else {
_vm->renderMessage(kStringSupernova8);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
- _vm->_menuBrightness = 0;
+ _vm->_screen->setGuiBrightness(0);
_vm->paletteBrightness();
changeRoom(MEETUP2);
if (_rooms[ROGER]->getObject(3)->hasProperty(CARRIED) && !_rooms[GLIDER]->isSectionVisible(5)) {
@@ -1121,7 +1205,7 @@ void GameManager::walk(int imgId) {
_vm->renderImage(_prevImgId + 128);
_vm->renderImage(imgId);
_prevImgId = imgId;
- wait2(3);
+ wait(3);
}
void GameManager::guardWalkEvent() {
@@ -1130,14 +1214,14 @@ void GameManager::guardWalkEvent() {
_rooms[BCORRIDOR]->getObject(_state._origin + 4)->hasProperty(OPENED));
_rooms[BCORRIDOR]->getObject(_state._origin + 4)->disableProperty(OCCUPIED);
if (_currentRoom == _rooms[BCORRIDOR]) {
- if (_vm->_messageDisplayed)
+ if (_vm->_screen->isMessageShown())
_vm->removeMessage();
if (!behind) {
_vm->renderImage(_state._origin + 1);
_prevImgId = _state._origin + 1;
- _vm->playSound(kAudioDoorOpen);
- wait2(3);
+ _sound->play(kAudioDoorOpen);
+ wait(3);
}
int imgId;
@@ -1158,13 +1242,13 @@ void GameManager::guardWalkEvent() {
}
_vm->renderImage(imgId);
if (!behind) {
- wait2(3);
+ wait(3);
_vm->renderImage(_prevImgId + 128);
- _vm->playSound(kAudioDoorClose);
+ _sound->play(kAudioDoorClose);
}
_prevImgId = imgId;
- wait2(3);
+ wait(3);
switch (_state._origin) {
case 0:
walk(12);
@@ -1221,12 +1305,12 @@ void GameManager::guardWalkEvent() {
if (behind) {
_vm->renderImage(_state._destination + 1);
- _vm->playSound(kAudioDoorOpen);
- wait2(3);
+ _sound->play(kAudioDoorOpen);
+ wait(3);
_vm->renderImage(_prevImgId + 128);
- wait2(3);
+ wait(3);
_vm->renderImage(_state._destination + 1 + 128);
- _vm->playSound(kAudioDoorClose);
+ _sound->play(kAudioDoorClose);
_rooms[BCORRIDOR]->getObject(_state._destination + 4)->setProperty(OCCUPIED);
_state._destination = 255;
} else if (_rooms[BCORRIDOR]->isSectionVisible(_state._destination + 1)) {
@@ -1236,7 +1320,7 @@ void GameManager::guardWalkEvent() {
_state._eventTime = _state._time + ticksToMsec(60);
_state._eventCallback = kGuardWalkFn;
} else {
- wait2(18);
+ wait(18);
SWAP(_state._origin, _state._destination);
_state._eventCallback = kGuardWalkFn;
}
@@ -1266,7 +1350,7 @@ void GameManager::taxiEvent() {
_vm->renderImage(1);
_vm->renderImage(2);
- _vm->playSound(kAudioRocks);
+ _sound->play(kAudioRocks);
screenShake();
_vm->renderImage(9);
_currentRoom->getObject(1)->setProperty(OPENED);
@@ -1274,7 +1358,7 @@ void GameManager::taxiEvent() {
_currentRoom->setSectionVisible(2, false);
_vm->renderImage(3);
for (int i = 4; i <= 8; i++) {
- wait2(2);
+ wait(2);
_vm->renderImage(invertSection(i - 1));
_vm->renderImage(i);
}
@@ -1292,7 +1376,7 @@ void GameManager::great(uint number) {
if (number && (_state._greatFlag & (1 << number)))
return;
- _vm->playSound(kAudioSuccess);
+ _sound->play(kAudioSuccess);
_state._greatFlag |= 1 << number;
}
@@ -1321,7 +1405,7 @@ void GameManager::sentence(int number, bool brightness) {
}
}
-void GameManager::say(StringID textId) {
+void GameManager::say(StringId textId) {
Common::String str = _vm->getGameString(textId);
if (!str.empty())
say(str.c_str());
@@ -1351,7 +1435,7 @@ void GameManager::say(const char *text) {
_vm->renderBox(0, 138, 320, 62, kColorBlack);
}
-void GameManager::reply(StringID textId, int aus1, int aus2) {
+void GameManager::reply(StringId textId, int aus1, int aus2) {
Common::String str = _vm->getGameString(textId);
if (!str.empty())
reply(str.c_str(), aus1, aus2);
@@ -1375,7 +1459,7 @@ void GameManager::reply(const char *text, int aus1, int aus2) {
_vm->removeMessage();
}
-int GameManager::dialog(int num, byte rowLength[6], StringID text[6], int number) {
+int GameManager::dialog(int num, byte rowLength[6], StringId text[6], int number) {
_vm->_allowLoadGame = false;
_guiEnabled = false;
@@ -1407,7 +1491,12 @@ int GameManager::dialog(int num, byte rowLength[6], StringID text[6], int number
_currentSentence = -1;
do {
- mouseInput3();
+ do {
+ updateEvents();
+ mousePosDialog(_mouseX, _mouseY);
+ g_system->updateScreen();
+ g_system->delayMillis(_vm->_delay);
+ } while (!_mouseClicked && !_vm->shouldQuit());
} while (_currentSentence == -1 && !_vm->shouldQuit());
_vm->renderBox(0, 138, 320, 62, kColorBlack);
@@ -1443,7 +1532,7 @@ void GameManager::turnOn() {
return;
_state._powerOff = false;
- _vm->_brightness = 255;
+ _vm->_screen->setViewportBrightness(255);
_rooms[SLEEP]->setSectionVisible(1, false);
_rooms[SLEEP]->setSectionVisible(2, false);
_rooms[COCKPIT]->setSectionVisible(22, false);
@@ -1462,7 +1551,7 @@ void GameManager::takeObject(Object &obj) {
void GameManager::drawCommandBox() {
for (int i = 0; i < ARRAYSIZE(_guiCommandButton); ++i) {
_vm->renderBox(_guiCommandButton[i]);
- int space = (_guiCommandButton[i].width() - _vm->textWidth(_guiCommandButton[i].getText())) / 2;
+ int space = (_guiCommandButton[i].width() - Screen::textWidth(_guiCommandButton[i].getText())) / 2;
_vm->renderText(_guiCommandButton[i].getText(),
_guiCommandButton[i].getTextPos().x + space,
_guiCommandButton[i].getTextPos().y,
@@ -1491,7 +1580,7 @@ void GameManager::drawInventory() {
uint16 GameManager::getKeyInput(bool blockForPrintChar) {
while (!_vm->shouldQuit()) {
- _vm->updateEvents();
+ updateEvents();
if (_keyPressed) {
if (blockForPrintChar) {
if (Common::isPrint(_key.keycode) ||
@@ -1521,7 +1610,7 @@ uint16 GameManager::getKeyInput(bool blockForPrintChar) {
Common::EventType GameManager::getMouseInput() {
while (!_vm->shouldQuit()) {
- _vm->updateEvents();
+ updateEvents();
if (_mouseClicked)
return _mouseClickType;
g_system->updateScreen();
@@ -1532,7 +1621,7 @@ Common::EventType GameManager::getMouseInput() {
void GameManager::getInput() {
while (!_vm->shouldQuit()) {
- _vm->updateEvents();
+ updateEvents();
if (_mouseClicked || _keyPressed)
break;
g_system->updateScreen();
@@ -1540,15 +1629,6 @@ void GameManager::getInput() {
}
}
-void GameManager::mouseInput3() {
- do {
- _vm->updateEvents();
- mousePosDialog(_mouseX, _mouseY);
- g_system->updateScreen();
- g_system->delayMillis(_vm->_delay);
- } while (!_mouseClicked && !_vm->shouldQuit());
-}
-
void GameManager::roomBrightness() {
_roomBrightness = 255;
if ((_currentRoom->getId() != OUTSIDE) && (_currentRoom->getId() < ROCKS) && _state._powerOff)
@@ -1558,22 +1638,22 @@ void GameManager::roomBrightness() {
else if ((_currentRoom->getId() == GUARD3) && _state._powerOff)
_roomBrightness = 0;
- if (_vm->_brightness != 0)
- _vm->_brightness = _roomBrightness;
+ if (_vm->_screen->getViewportBrightness() != 0)
+ _vm->_screen->setViewportBrightness(_roomBrightness);
_vm->paletteBrightness();
}
-void GameManager::changeRoom(RoomID id) {
+void GameManager::changeRoom(RoomId id) {
_currentRoom = _rooms[id];
_newRoom = true;
}
-void GameManager::wait2(int ticks) {
+void GameManager::wait(int ticks) {
int32 end = _state._time + ticksToMsec(ticks);
do {
g_system->delayMillis(_vm->_delay);
- _vm->updateEvents();
+ updateEvents();
g_system->updateScreen();
} while (_state._time < end && !_vm->shouldQuit());
}
@@ -1582,7 +1662,7 @@ void GameManager::waitOnInput(int ticks) {
int32 end = _state._time + ticksToMsec(ticks);
do {
g_system->delayMillis(_vm->_delay);
- _vm->updateEvents();
+ updateEvents();
g_system->updateScreen();
} while (_state._time < end && !_vm->shouldQuit() && !_keyPressed && !_mouseClicked);
}
@@ -1592,7 +1672,7 @@ bool GameManager::waitOnInput(int ticks, Common::KeyCode &keycode) {
int32 end = _state._time + ticksToMsec(ticks);
do {
g_system->delayMillis(_vm->_delay);
- _vm->updateEvents();
+ updateEvents();
g_system->updateScreen();
if (_keyPressed) {
keycode = _key.keycode;
@@ -1652,14 +1732,14 @@ void GameManager::saveTime() {
void GameManager::screenShake() {
for (int i = 0; i < 12; ++i) {
_vm->_system->setShakePos(8);
- wait2(1);
+ wait(1);
_vm->_system->setShakePos(0);
- wait2(1);
+ wait(1);
}
}
void GameManager::shock() {
- _vm->playSound(kAudioShock);
+ _sound->play(kAudioShock);
dead(kStringShock);
}
@@ -1704,24 +1784,24 @@ void GameManager::edit(Common::String &input, int x, int y, uint length) {
kScreenWidth - x : (length + 1) * (kFontWidth + 2);
while (isEditing) {
- _vm->_textCursorX = x;
- _vm->_textCursorY = y;
- _vm->_textColor = kColorWhite99;
+ _vm->_screen->setTextCursorPos(x, y);
+ _vm->_screen->setTextCursorColor(kColorWhite99);
_vm->renderBox(x, y - 1, overdrawWidth, 9, kColorDarkBlue);
for (uint i = 0; i < input.size(); ++i) {
// Draw char highlight depending on cursor position
if (i == cursorIndex) {
- _vm->renderBox(_vm->_textCursorX, y - 1, _vm->textWidth(input[i]), 9, kColorWhite99);
- _vm->_textColor = kColorDarkBlue;
+ _vm->renderBox(_vm->_screen->getTextCursorPos().x, y - 1,
+ Screen::textWidth(input[i]), 9, kColorWhite99);
+ _vm->_screen->setTextCursorColor(kColorDarkBlue);
_vm->renderText(input[i]);
- _vm->_textColor = kColorWhite99;
+ _vm->_screen->setTextCursorColor(kColorWhite99);
} else
_vm->renderText(input[i]);
}
if (cursorIndex == input.size()) {
- _vm->renderBox(_vm->_textCursorX + 1, y - 1, 6, 9, kColorDarkBlue);
- _vm->renderBox(_vm->_textCursorX , y - 1, 1, 9, kColorWhite99);
+ _vm->renderBox(_vm->_screen->getTextCursorPos().x + 1, y - 1, 6, 9, kColorDarkBlue);
+ _vm->renderBox(_vm->_screen->getTextCursorPos().x, y - 1, 1, 9, kColorWhite99);
}
getKeyInput(true);
@@ -1767,15 +1847,15 @@ void GameManager::edit(Common::String &input, int x, int y, uint length) {
void GameManager::shot(int a, int b) {
if (a)
_vm->renderImage(a);
- _vm->playSound(kAudioGunShot);
- wait2(2);
+ _sound->play(kAudioGunShot);
+ wait(2);
if (b)
_vm->renderImage(b);
- wait2(2);
+ wait(2);
if (a)
_vm->renderImage(a);
- _vm->playSound(kAudioGunShot);
- wait2(2);
+ _sound->play(kAudioGunShot);
+ wait(2);
if (b)
_vm->renderImage(b);
@@ -1801,7 +1881,7 @@ void GameManager::drawStatus() {
_vm->renderBox(0, 140, 320, 9, kColorWhite25);
_vm->renderText(_vm->getGameString(guiStatusCommands[index]), 1, 141, kColorDarkGreen);
- if (Object::isNullObject(_inputObject[0]))
+ if (isNullObject(_inputObject[0]))
_vm->renderText(_currentInputObject->_name);
else {
_vm->renderText(_inputObject[0]->_name);
@@ -1832,19 +1912,18 @@ void GameManager::closeLocker(const Room *room, Object *obj, Object *lock, int s
}
}
-void GameManager::dead(StringID messageId) {
+void GameManager::dead(StringId messageId) {
_vm->paletteFadeOut();
_guiEnabled = false;
_vm->setCurrentImage(11);
_vm->renderImage(0);
_vm->renderMessage(messageId);
- _vm->playSound(kAudioDeath);
+ _sound->play(kAudioDeath);
_vm->paletteFadeIn();
getInput();
_vm->paletteFadeOut();
_vm->removeMessage();
- // TODO: Load screen
destroyRooms();
initRooms();
initState();
@@ -1926,10 +2005,10 @@ bool GameManager::genericInteract(Action verb, Object &obj1, Object &obj2) {
}
} else if ((verb == ACTION_LOOK) && (obj1._id == NEWSPAPER)) {
_vm->renderMessage(kStringGenericInteract_10);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
_vm->renderMessage(kStringGenericInteract_11);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
_vm->setCurrentImage(2);
_vm->renderImage(0);
@@ -2127,7 +2206,7 @@ bool GameManager::genericInteract(Action verb, Object &obj1, Object &obj2) {
_vm->renderMessage(kStringGenericInteract_30);
else if ((verb == ACTION_LOOK) && (obj1._id == BOOK2)) {
_vm->renderMessage(kStringGenericInteract_31);
- waitOnInput(_timer1);
+ waitOnInput(_messageDuration);
_vm->removeMessage();
_vm->renderMessage(kStringGenericInteract_32);
} else
@@ -2192,7 +2271,7 @@ void GameManager::handleInput() {
byte i = _inputObject[0]->_click;
_inputObject[0]->_click = _inputObject[0]->_click2;
_inputObject[0]->_click2 = i;
- _vm->playSound(kAudioDoorOpen);
+ _sound->play(kAudioDoorOpen);
}
break;
@@ -2211,7 +2290,7 @@ void GameManager::handleInput() {
byte i = _inputObject[0]->_click;
_inputObject[0]->_click = _inputObject[0]->_click2;
_inputObject[0]->_click2 = i;
- _vm->playSound(kAudioDoorClose);
+ _sound->play(kAudioDoorClose);
}
break;
@@ -2230,7 +2309,7 @@ void GameManager::handleInput() {
}
void GameManager::executeRoom() {
- if (_processInput && !_vm->_messageDisplayed && _guiEnabled) {
+ if (_processInput && !_vm->_screen->isMessageShown() && _guiEnabled) {
handleInput();
if (_mouseClicked) {
Common::Event event;
@@ -2246,7 +2325,7 @@ void GameManager::executeRoom() {
}
if (_guiEnabled) {
- if (!_vm->_messageDisplayed) {
+ if (!_vm->_screen->isMessageShown()) {
g_system->fillScreen(kColorBlack);
_vm->renderRoom(*_currentRoom);
}
@@ -2257,7 +2336,7 @@ void GameManager::executeRoom() {
}
roomBrightness();
- if (_vm->_brightness == 0)
+ if (_vm->_screen->getViewportBrightness() == 0)
_vm->paletteFadeIn();
if (!_currentRoom->hasSeen() && _newRoom) {
@@ -2269,31 +2348,31 @@ void GameManager::executeRoom() {
void GameManager::guardShot() {
_vm->renderImage(2);
_vm->renderImage(5);
- wait2(3);
+ wait(3);
_vm->renderImage(2);
- _vm->playSound(kAudioVoiceHalt);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- wait2(1);
+ _sound->play(kAudioVoiceHalt);
+ while (_sound->isPlaying())
+ wait(1);
_vm->renderImage(5);
- wait2(5);
+ wait(5);
_vm->renderImage(3);
- wait2(3);
+ wait(3);
shot(4, 3);
}
void GameManager::guard3Shot() {
_vm->renderImage(1);
- wait2(3);
- _vm->playSound(kAudioVoiceHalt); // 46/0
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle))
- wait2(1);
+ wait(3);
+ _sound->play(kAudioVoiceHalt); // 46/0
+ while (_sound->isPlaying())
+ wait(1);
- wait2(5);
+ wait(5);
_vm->renderImage(2);
- wait2(3);
+ wait(3);
shot(3,2);
}
@@ -2337,12 +2416,12 @@ void GameManager::alarmSound() {
_vm->removeMessage();
_vm->renderMessage(kStringAlarm);
- int32 end = _state._time + ticksToMsec(_timer1);
+ int32 end = _state._time + ticksToMsec(_messageDuration);
do {
- _vm->playSound(kAudioAlarm);
- while (_vm->_mixer->isSoundHandleActive(_vm->_soundHandle)) {
+ _sound->play(kAudioAlarm);
+ while (_sound->isPlaying()) {
g_system->delayMillis(_vm->_delay);
- _vm->updateEvents();
+ updateEvents();
g_system->updateScreen();
}
} while (_state._time < end && !_vm->shouldQuit());
diff --git a/engines/supernova/state.h b/engines/supernova/state.h
index ab21842296..7d7b2284ad 100644
--- a/engines/supernova/state.h
+++ b/engines/supernova/state.h
@@ -23,9 +23,11 @@
#ifndef SUPERNOVA_STATE_H
#define SUPERNOVA_STATE_H
+#include "common/events.h"
#include "common/rect.h"
#include "common/keyboard.h"
#include "supernova/rooms.h"
+#include "supernova/sound.h"
namespace Supernova {
@@ -63,8 +65,9 @@ struct GameState {
class Inventory {
public:
- Inventory(int &inventoryScroll)
+ Inventory(Object *nullObject, int &inventoryScroll)
: _numObjects(0)
+ , _nullObject(nullObject)
, _inventoryScroll(inventoryScroll)
{}
@@ -72,11 +75,12 @@ public:
void remove(Object &obj);
void clear();
Object *get(int index) const;
- Object *get(ObjectID id) const;
+ Object *get(ObjectId id) const;
int getSize() const { return _numObjects; }
private:
Object *_inventory[kMaxCarry];
+ Object *_nullObject;
int &_inventoryScroll;
int _numObjects;
};
@@ -121,18 +125,20 @@ private:
class GameManager {
public:
- GameManager(SupernovaEngine *vm);
+ GameManager(SupernovaEngine *vm, Sound *sound);
~GameManager();
+ void updateEvents();
void processInput(Common::KeyState &state);
void processInput();
void executeRoom();
bool serialize(Common::WriteStream *out);
bool deserialize(Common::ReadStream *in, int version);
- static StringID guiCommands[];
- static StringID guiStatusCommands[];
+ static StringId guiCommands[];
+ static StringId guiStatusCommands[];
SupernovaEngine *_vm;
+ Sound *_sound;
Common::KeyState _key;
Common::EventType _mouseClickType;
bool _mouseClicked;
@@ -150,13 +156,13 @@ public:
bool _animationEnabled;
byte _roomBrightness;
Action _inputVerb;
+ Object _nullObject;
Object *_currentInputObject;
Object *_inputObject[2];
- bool _waitEvent;
int32 _oldTime;
uint _timePaused;
bool _timerPaused;
- int32 _timer1;
+ int32 _messageDuration;
int32 _animationTimer;
int _inventoryScroll;
int _exitList[25];
@@ -166,11 +172,13 @@ public:
// Dialog
int _currentSentence;
int _sentenceNumber[6];
- StringID _texts[6];
+ StringId _texts[6];
byte _rows[6];
byte _rowsStart[6];
void takeObject(Object &obj);
+ void setObjectNull(Object *&obj);
+ bool isNullObject(Object *obj);
void initState();
void initRooms();
@@ -184,8 +192,7 @@ public:
Common::EventType getMouseInput();
uint16 getKeyInput(bool blockForPrintChar = false);
void getInput();
- void mouseInput3();
- void wait2(int ticks);
+ void wait(int ticks);
void waitOnInput(int ticks);
bool waitOnInput(int ticks, Common::KeyCode &keycode);
void turnOff();
@@ -203,7 +210,7 @@ public:
void drawStatus();
void drawCommandBox();
void drawInventory();
- void changeRoom(RoomID id);
+ void changeRoom(RoomId id);
void resetInputState();
void handleInput();
void handleTime();
@@ -211,12 +218,12 @@ public:
void loadTime();
void saveTime();
void setAnimationTimer(int ticks);
- void dead(StringID messageId);
- int dialog(int num, byte rowLength[6], StringID text[6], int number);
+ void dead(StringId messageId);
+ int dialog(int num, byte rowLength[6], StringId text[6], int number);
void sentence(int number, bool brightness);
- void say(StringID textId);
+ void say(StringId textId);
void say(const char *text);
- void reply(StringID textId, int aus1, int aus2);
+ void reply(StringId textId, int aus1, int aus2);
void reply(const char *text, int aus1, int aus2);
void mousePosDialog(int x, int y);
void shot(int a, int b);
diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp
index 50731ae52f..c47e476de7 100644
--- a/engines/supernova/supernova.cpp
+++ b/engines/supernova/supernova.cpp
@@ -20,7 +20,6 @@
*
*/
-#include "audio/mods/protracker.h"
#include "common/config-manager.h"
#include "common/debug.h"
#include "common/debug-channels.h"
@@ -42,36 +41,14 @@
#include "graphics/thumbnail.h"
#include "gui/saveload.h"
+#include "supernova/resman.h"
+#include "supernova/screen.h"
+#include "supernova/sound.h"
#include "supernova/supernova.h"
#include "supernova/state.h"
namespace Supernova {
-const AudioInfo audioInfo[kAudioNumSamples] = {
- {44, 0, -1},
- {45, 0, -1},
- {46, 0, 2510},
- {46, 2510, 4020},
- {46, 4020, -1},
- {47, 0, 24010},
- {47, 24010, -1},
- {48, 0, 2510},
- {48, 2510, 10520},
- {48, 10520, 13530},
- {48, 13530, -1},
- {50, 0, 12786},
- {50, 12786, -1},
- {51, 0, -1},
- {53, 0, -1},
- {54, 0, 8010},
- {54, 8010, 24020},
- {54, 24020, 30030},
- {54, 30030, 31040},
- {54, 31040, -1}
-};
-
-const Object Object::nullObject;
-
ObjectType operator|(ObjectType a, ObjectType b) {
return static_cast<ObjectType>(+a | +b);
}
@@ -98,74 +75,37 @@ ObjectType &operator^=(ObjectType &a, ObjectType b) {
SupernovaEngine::SupernovaEngine(OSystem *syst)
: Engine(syst)
- , _console(NULL)
- , _gm(NULL)
- , _currentImage(NULL)
- , _soundMusicIntro(NULL)
- , _soundMusicOutro(NULL)
- , _rnd("supernova")
- , _brightness(255)
- , _menuBrightness(255)
+ , _console(nullptr)
+ , _gm(nullptr)
+ , _sound(nullptr)
+ , _resMan(nullptr)
+ , _screen(nullptr)
, _delay(33)
, _textSpeed(kTextSpeed[2])
- , _screenWidth(320)
- , _screenHeight(200)
- , _messageDisplayed(false)
, _allowLoadGame(true)
- , _allowSaveGame(true)
-{
-// const Common::FSNode gameDataDir(ConfMan.get("path"));
-// SearchMan.addSubDirectoryMatching(gameDataDir, "sound");
-
+ , _allowSaveGame(true) {
if (ConfMan.hasKey("textspeed"))
_textSpeed = ConfMan.getInt("textspeed");
- // setup engine specific debug channels
DebugMan.addDebugChannel(kDebugGeneral, "general", "Supernova general debug channel");
}
SupernovaEngine::~SupernovaEngine() {
DebugMan.clearAllDebugChannels();
- delete _currentImage;
delete _console;
delete _gm;
- delete _soundMusicIntro;
- delete _soundMusicOutro;
+ delete _sound;
+ delete _resMan;
+ delete _screen;
}
Common::Error SupernovaEngine::run() {
- Graphics::ModeList modes;
- modes.push_back(Graphics::Mode(320, 200));
- modes.push_back(Graphics::Mode(640, 480));
- initGraphicsModes(modes);
- initGraphics(_screenWidth, _screenHeight);
-
- Common::Error status = loadGameStrings();
- if (status.getCode() != Common::kNoError)
- return status;
-
- _gm = new GameManager(this);
- _console = new Console(this, _gm);
-
- initData();
- initPalette();
-
- CursorMan.replaceCursor(_mouseNormal, 16, 16, 0, 0, kColorCursorTransparent);
- CursorMan.replaceCursorPalette(initVGAPalette, 0, 16);
- CursorMan.showMouse(true);
-
- setTotalPlayTime(0);
-
- int saveSlot = ConfMan.getInt("save_slot");
- if (saveSlot >= 0) {
- if (loadGameState(saveSlot).getCode() != Common::kNoError)
- error("Failed to load save game from slot %i", saveSlot);
- }
+ init();
while (!shouldQuit()) {
uint32 start = _system->getMillis();
- updateEvents();
+ _gm->updateEvents();
_gm->executeRoom();
_console->onFrame();
_system->updateScreen();
@@ -174,89 +114,34 @@ Common::Error SupernovaEngine::run() {
_system->delayMillis(end);
}
- stopSound();
+ _mixer->stopAll();
return Common::kNoError;
}
-void SupernovaEngine::updateEvents() {
- _gm->handleTime();
- if (_gm->_animationEnabled && !_messageDisplayed && _gm->_animationTimer == 0)
- _gm->_currentRoom->animation();
-
- if (_gm->_state._eventCallback != kNoFn && _gm->_state._time >= _gm->_state._eventTime) {
- _allowLoadGame = false;
- _allowSaveGame = false;
- _gm->_state._eventTime = kMaxTimerValue;
- EventFunction fn = _gm->_state._eventCallback;
- _gm->_state._eventCallback = kNoFn;
- switch (fn) {
- case kNoFn:
- break;
- case kSupernovaFn:
- _gm->supernovaEvent();
- break;
- case kGuardReturnedFn:
- _gm->guardReturnedEvent();
- break;
- case kGuardWalkFn:
- _gm->guardWalkEvent();
- break;
- case kTaxiFn:
- _gm->taxiEvent();
- break;
- case kSearchStartFn:
- _gm->searchStartEvent();
- break;
- }
- _allowLoadGame = true;
- _allowSaveGame = true;
- return;
- }
-
- if (_gm->_state._alarmOn && _gm->_state._timeAlarm <= _gm->_state._time) {
- _gm->_state._alarmOn = false;
- _gm->alarm();
- return;
- }
+void SupernovaEngine::init() {
+ Graphics::ModeList modes;
+ modes.push_back(Graphics::Mode(320, 200));
+ modes.push_back(Graphics::Mode(640, 480));
+ initGraphicsModes(modes);
+ initGraphics(320, 200);
- _gm->_mouseClicked = false;
- _gm->_keyPressed = false;
- Common::Event event;
- while (g_system->getEventManager()->pollEvent(event)) {
- switch (event.type) {
- case Common::EVENT_KEYDOWN:
- _gm->_keyPressed = true;
- if (event.kbd.keycode == Common::KEYCODE_d &&
- (event.kbd.flags & Common::KBD_CTRL)) {
- _console->attach();
- }
- if (event.kbd.keycode == Common::KEYCODE_x &&
- (event.kbd.flags & Common::KBD_CTRL)) {
- // TODO: Draw exit box
- }
+ Common::Error status = loadGameStrings();
+ if (status.getCode() != Common::kNoError)
+ error("Failed reading game strings");
- _gm->processInput(event.kbd);
- break;
+ _resMan = new ResourceManager();
+ _sound = new Sound(_mixer, _resMan);
+ _gm = new GameManager(this, _sound);
+ _screen = new Screen(this, _gm, _resMan);
+ _console = new Console(this, _gm);
- case Common::EVENT_LBUTTONUP:
- // fallthrough
- case Common::EVENT_RBUTTONUP:
- if (_gm->_currentRoom->getId() != INTRO && _mixer->isSoundHandleActive(_soundHandle))
- return;
- _gm->_mouseClicked = true;
- // fallthrough
- case Common::EVENT_MOUSEMOVE:
- _gm->_mouseClickType = event.type;
- _gm->_mouseX = event.mouse.x;
- _gm->_mouseY = event.mouse.y;
- if (_gm->_guiEnabled)
- _gm->processInput();
- break;
+ setTotalPlayTime(0);
- default:
- break;
- }
+ int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0) {
+ if (loadGameState(saveSlot).getCode() != Common::kNoError)
+ error("Failed to load save game from slot %i", saveSlot);
}
}
@@ -337,440 +222,133 @@ Common::Error SupernovaEngine::loadGameStrings() {
return Common::kReadingFailed;
}
-void SupernovaEngine::initData() {
- // Sound
- // Note:
- // - samples start with a header of 6 bytes: 01 SS SS 00 AD 00
- // where SS SS (LE uint16) is the size of the sound sample + 2
- // - samples end with a footer of 4 bytes: 00 00
- // Skip those in the buffer
- Common::File file;
-
- for (int i = 0; i < kAudioNumSamples; ++i) {
- if (!file.open(Common::String::format("msn_data.%03d", audioInfo[i]._filenumber))) {
- error("File %s could not be read!", file.getName());
- }
-
- if (audioInfo[i]._offsetEnd == -1) {
- file.seek(0, SEEK_END);
- _soundSamples[i]._length = file.pos() - audioInfo[i]._offsetStart - 10;
- } else {
- _soundSamples[i]._length = audioInfo[i]._offsetEnd - audioInfo[i]._offsetStart - 10;
- }
- _soundSamples[i]._buffer = new byte[_soundSamples[i]._length];
- file.seek(audioInfo[i]._offsetStart + 6);
- file.read(_soundSamples[i]._buffer, _soundSamples[i]._length);
- file.close();
- }
-
- _soundMusicIntro = convertToMod("msn_data.049");
- _soundMusicOutro = convertToMod("msn_data.052");
-
- // Cursor
- const uint16 *bufferNormal = reinterpret_cast<const uint16 *>(mouseNormal);
- const uint16 *bufferWait = reinterpret_cast<const uint16 *>(mouseWait);
- for (uint i = 0; i < sizeof(mouseNormal) / 4; ++i) {
- for (uint bit = 0; bit < 16; ++bit) {
- uint mask = 0x8000 >> bit;
- uint bitIndex = i * 16 + bit;
-
- _mouseNormal[bitIndex] = (READ_LE_UINT16(bufferNormal + i) & mask) ? kColorCursorTransparent : kColorBlack;
- if (READ_LE_UINT16(bufferNormal + i + 16) & mask)
- _mouseNormal[bitIndex] = kColorLightRed;
- _mouseWait[bitIndex] = (READ_LE_UINT16(bufferWait + i) & mask) ? kColorCursorTransparent : kColorBlack;
- if (READ_LE_UINT16(bufferWait + i + 16) & mask)
- _mouseWait[bitIndex] = kColorLightRed;
- }
- }
+const Common::String &SupernovaEngine::getGameString(int idx) const {
+ if (idx < 0 || idx >= (int)_gameStrings.size())
+ return _nullString;
+ return _gameStrings[idx];
}
-void SupernovaEngine::initPalette() {
- _system->getPaletteManager()->setPalette(initVGAPalette, 0, 256);
-}
-
-void SupernovaEngine::playSound(AudioIndex sample) {
- if (sample > kAudioNumSamples - 1)
+void SupernovaEngine::setGameString(int idx, const Common::String &string) {
+ if (idx < 0)
return;
-
- Audio::SeekableAudioStream *audioStream = Audio::makeRawStream(
- _soundSamples[sample]._buffer, _soundSamples[sample]._length,
- 11931, Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN, DisposeAfterUse::NO);
- stopSound();
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, audioStream);
-}
-
-void SupernovaEngine::stopSound() {
- if (_mixer->isSoundHandleActive(_soundHandle))
- _mixer->stopHandle(_soundHandle);
+ while ((int)_gameStrings.size() <= idx)
+ _gameStrings.push_back(Common::String());
+ _gameStrings[idx] = string;
}
-void SupernovaEngine::playSoundMod(int filenumber)
-{
- Audio::AudioStream *audioStream;
- if (filenumber == 49)
- audioStream = Audio::makeProtrackerStream(_soundMusicIntro);
- else if (filenumber == 52)
- audioStream = Audio::makeProtrackerStream(_soundMusicOutro);
- else
- return;
-
- stopSound();
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, audioStream,
- -1, Audio::Mixer::kMaxChannelVolume, 0);
+void SupernovaEngine::playSound(AudioId sample) {
+ _sound->play(sample);
}
-void SupernovaEngine::renderImageSection(int section) {
- // Note: inverting means we are removing the section. So we should get the rect for that
- // section but draw the background (section 0) instead.
- bool invert = false;
- if (section > 128) {
- section -= 128;
- invert = true;
- }
- if (!_currentImage || section > _currentImage->_numSections - 1)
- return;
-
- Common::Rect sectionRect(_currentImage->_section[section].x1,
- _currentImage->_section[section].y1,
- _currentImage->_section[section].x2 + 1,
- _currentImage->_section[section].y2 + 1) ;
- if (_currentImage->_filenumber == 1 || _currentImage->_filenumber == 2) {
- sectionRect.setWidth(640);
- sectionRect.setHeight(480);
- if (_screenWidth != 640) {
- _screenWidth = 640;
- _screenHeight = 480;
- initGraphics(_screenWidth, _screenHeight);
- }
- } else {
- if (_screenWidth != 320) {
- _screenWidth = 320;
- _screenHeight = 200;
- initGraphics(_screenWidth, _screenHeight);
- }
- }
-
- uint offset = 0;
- int pitch = sectionRect.width();
- if (invert) {
- pitch = _currentImage->_pitch;
- offset = _currentImage->_section[section].y1 * pitch + _currentImage->_section[section].x1;
- section = 0;
- }
-
- _system->copyRectToScreen(static_cast<const byte *>(_currentImage->_sectionSurfaces[section]->getPixels()) + offset,
- pitch,
- sectionRect.left, sectionRect.top,
- sectionRect.width(), sectionRect.height());
+void SupernovaEngine::playSound(MusicId index) {
+ _sound->play(index);
}
void SupernovaEngine::renderImage(int section) {
- if (!_currentImage)
- return;
-
- bool sectionVisible = true;
-
- if (section > 128) {
- sectionVisible = false;
- section -= 128;
- }
-
- _gm->_currentRoom->setSectionVisible(section, sectionVisible);
-
- do {
- if (sectionVisible)
- renderImageSection(section);
- else
- renderImageSection(section + 128);
- section = _currentImage->_section[section].next;
- } while (section != 0);
+ _screen->renderImage(section);
}
bool SupernovaEngine::setCurrentImage(int filenumber) {
- if (_currentImage && _currentImage->_filenumber == filenumber)
- return true;
-
- delete _currentImage;
- _currentImage = new MSNImageDecoder();
- if (!_currentImage->init(filenumber)) {
- delete _currentImage;
- _currentImage = NULL;
- return false;
- }
-
- _system->getPaletteManager()->setPalette(_currentImage->getPalette(), 16, 239);
- paletteBrightness();
- return true;
+ return _screen->setCurrentImage(filenumber);
}
void SupernovaEngine::saveScreen(int x, int y, int width, int height) {
- _screenBuffer.push(x, y, width, height);
+ _screen->saveScreen(x, y, width, height);
}
void SupernovaEngine::saveScreen(const GuiElement &guiElement) {
- saveScreen(guiElement.left, guiElement.top, guiElement.width(), guiElement.height());
+ _screen->saveScreen(guiElement);
}
void SupernovaEngine::restoreScreen() {
- _screenBuffer.restore();
+ _screen->restoreScreen();
}
void SupernovaEngine::renderRoom(Room &room) {
- if (room.getId() == INTRO)
- return;
-
- if (setCurrentImage(room.getFileNumber())) {
- for (int i = 0; i < _currentImage->_numSections; ++i) {
- int section = i;
- if (room.isSectionVisible(section)) {
- do {
- renderImageSection(section);
- section = _currentImage->_section[section].next;
- } while (section != 0);
- }
- }
- }
+ _screen->renderRoom(room);
}
-int SupernovaEngine::textWidth(const uint16 key) {
- char text[2];
- text[0] = key & 0xFF;
- text[1] = 0;
- return textWidth(text);
+void SupernovaEngine::renderMessage(const char *text, MessagePosition position) {
+ _screen->renderMessage(text, position);
}
-int SupernovaEngine::textWidth(const char *text) {
- int charWidth = 0;
- while (*text != '\0') {
- byte c = *text++;
- if (c < 32) {
- continue;
- } else if (c == 225) {
- c = 35;
- }
-
- for (uint i = 0; i < 5; ++i) {
- if (font[c - 32][i] == 0xff) {
- break;
- }
- ++charWidth;
- }
- ++charWidth;
- }
-
- return charWidth;
+void SupernovaEngine::renderMessage(const Common::String &text, MessagePosition position) {
+ _screen->renderMessage(text, position);
}
-void SupernovaEngine::renderMessage(const char *text, MessagePosition position) {
- Common::String t(text);
- char *row[20];
- Common::String::iterator p = t.begin();
- uint numRows = 0;
- int rowWidthMax = 0;
- int x = 0;
- int y = 0;
- byte textColor = 0;
-
- while (*p != '\0') {
- row[numRows] = p;
- ++numRows;
- while ((*p != '\0') && (*p != '|')) {
- ++p;
- }
- if (*p == '|') {
- *p = '\0';
- ++p;
- }
- }
- for (uint i = 0; i < numRows; ++i) {
- int rowWidth = textWidth(row[i]);
- if (rowWidth > rowWidthMax)
- rowWidthMax = rowWidth;
- }
-
- switch (position) {
- case kMessageNormal:
- x = 160 - rowWidthMax / 2;
- textColor = kColorWhite99;
- break;
- case kMessageTop:
- x = 160 - rowWidthMax / 2;
- textColor = kColorLightYellow;
- break;
- case kMessageCenter:
- x = 160 - rowWidthMax / 2;
- textColor = kColorLightRed;
- break;
- case kMessageLeft:
- x = 3;
- textColor = kColorLightYellow;
- break;
- case kMessageRight:
- x = 317 - rowWidthMax;
- textColor = kColorLightGreen;
- break;
- }
-
- if (position == kMessageNormal) {
- y = 70 - ((numRows * 9) / 2);
- } else if (position == kMessageTop) {
- y = 5;
- } else {
- y = 142;
- }
-
- int message_columns = x - 3;
- int message_rows = y - 3;
- int message_width = rowWidthMax + 6;
- int message_height = numRows * 9 + 5;
- saveScreen(message_columns, message_rows, message_width, message_height);
- renderBox(message_columns, message_rows, message_width, message_height, kColorWhite35);
- for (uint i = 0; i < numRows; ++i) {
- renderText(row[i], x, y, textColor);
- y += 9;
- }
-
- _messageDisplayed = true;
- _gm->_timer1 = (Common::strnlen(text, 512) + 20) * _textSpeed / 10;
+void SupernovaEngine::renderMessage(StringId stringId, MessagePosition position, Common::String var1, Common::String var2) {
+ _screen->renderMessage(stringId, position, var1, var2);
}
void SupernovaEngine::removeMessage() {
- if (_messageDisplayed) {
- restoreScreen();
- _messageDisplayed = false;
- }
+ _screen->removeMessage();
}
-void SupernovaEngine::renderText(const char *text, int x, int y, byte color) {
- Graphics::Surface *screen = _system->lockScreen();
- byte *cursor = static_cast<byte *>(screen->getBasePtr(x, y));
- const byte *basePtr = cursor;
-
- byte c;
- while ((c = *text++) != '\0') {
- if (c < 32) {
- continue;
- } else if (c == 225) {
- c = 128;
- }
+void SupernovaEngine::renderText(const uint16 character) {
+ _screen->renderText(character);
+}
- for (uint i = 0; i < 5; ++i) {
- if (font[c - 32][i] == 0xff) {
- break;
- }
+void SupernovaEngine::renderText(const char *text) {
+ _screen->renderText(text);
+}
- byte *ascentLine = cursor;
- for (byte j = font[c - 32][i]; j != 0; j >>= 1) {
- if (j & 1) {
- *cursor = color;
- }
- cursor += kScreenWidth;
- }
- cursor = ++ascentLine;
- }
- ++cursor;
- }
- _system->unlockScreen();
+void SupernovaEngine::renderText(const Common::String &text) {
+ _screen->renderText(text);
+}
- uint numChars = cursor - basePtr;
- uint absPosition = y * kScreenWidth + x + numChars;
- _textCursorX = absPosition % kScreenWidth;
- _textCursorY = absPosition / kScreenWidth;
- _textColor = color;
+void SupernovaEngine::renderText(StringId stringId) {
+ _screen->renderText(stringId);
+}
+
+void SupernovaEngine::renderText(const GuiElement &guiElement) {
+ _screen->renderText(guiElement);
}
void SupernovaEngine::renderText(const uint16 character, int x, int y, byte color) {
- char text[2];
- text[0] = character & 0xFF;
- text[1] = 0;
- renderText(text, x, y, color);
+ _screen->renderText(character, x, y, color);
}
-void SupernovaEngine::renderText(const char *text) {
- renderText(text, _textCursorX, _textCursorY, _textColor);
+void SupernovaEngine::renderText(const char *text, int x, int y, byte color) {
+ _screen->renderText(text, x, y, color);
}
-void SupernovaEngine::renderText(const uint16 character) {
- char text[2];
- text[0] = character & 0xFF;
- text[1] = 0;
- renderText(text, _textCursorX, _textCursorY, _textColor);
+void SupernovaEngine::renderText(const Common::String &text, int x, int y, byte color) {
+ _screen->renderText(text, x, y, color);
}
-void SupernovaEngine::renderText(const GuiElement &guiElement) {
- renderText(guiElement.getText(), guiElement.getTextPos().x,
- guiElement.getTextPos().y, guiElement.getTextColor());
+
+void SupernovaEngine::renderText(StringId stringId, int x, int y, byte color) {
+ _screen->renderText(stringId, x, y, color);
}
void SupernovaEngine::renderBox(int x, int y, int width, int height, byte color) {
- Graphics::Surface *screen = _system->lockScreen();
- screen->fillRect(Common::Rect(x, y, x + width, y + height), color);
- _system->unlockScreen();
+ _screen->renderBox(x, y, width, height, color);
}
void SupernovaEngine::renderBox(const GuiElement &guiElement) {
- renderBox(guiElement.left, guiElement.top, guiElement.width(),
- guiElement.height(), guiElement.getBackgroundColor());
+ _screen->renderBox(guiElement);
}
void SupernovaEngine::paletteBrightness() {
- byte palette[768];
-
- _system->getPaletteManager()->grabPalette(palette, 0, 255);
- for (uint i = 0; i < 48; ++i) {
- palette[i] = (initVGAPalette[i] * _menuBrightness) >> 8;
- }
- for (uint i = 0; i < 717; ++i) {
- const byte *imagePalette;
- if (_currentImage && _currentImage->getPalette()) {
- imagePalette = _currentImage->getPalette();
- } else {
- imagePalette = palette + 48;
- }
- palette[i + 48] = (imagePalette[i] * _brightness) >> 8;
- }
- _system->getPaletteManager()->setPalette(palette, 0, 255);
+ _screen->paletteBrightness();
}
void SupernovaEngine::paletteFadeOut() {
- while (_menuBrightness > 10) {
- _menuBrightness -= 10;
- if (_brightness > _menuBrightness)
- _brightness = _menuBrightness;
- paletteBrightness();
- _system->updateScreen();
- _system->delayMillis(_delay);
- }
- _menuBrightness = 0;
- _brightness = 0;
- paletteBrightness();
- _system->updateScreen();
+ _screen->paletteFadeOut();
}
void SupernovaEngine::paletteFadeIn() {
- while (_menuBrightness < 245) {
- if (_brightness < _gm->_roomBrightness)
- _brightness += 10;
- _menuBrightness += 10;
- paletteBrightness();
- _system->updateScreen();
- _system->delayMillis(_delay);
- }
- _menuBrightness = 255;
- _brightness = _gm->_roomBrightness;
- paletteBrightness();
- _system->updateScreen();
+ _screen->paletteFadeIn();
}
void SupernovaEngine::setColor63(byte value) {
- byte color[3] = {value, value, value};
- _system->getPaletteManager()->setPalette(color, 63, 1);
+ _screen->setColor63(value);
}
void SupernovaEngine::setTextSpeed() {
- const Common::String& textSpeedString = getGameString(kStringTextSpeed);
- int stringWidth = textWidth(textSpeedString);
- int textX = (320 - stringWidth) / 2;
+ const Common::String &textSpeedString = getGameString(kStringTextSpeed);
+ int stringWidth = Screen::textWidth(textSpeedString);
+ int textX = (kScreenWidth - stringWidth) / 2;
int textY = 100;
stringWidth += 4;
- int boxX = stringWidth > 110 ? (320 - stringWidth) / 2 : 105;
+ int boxX = stringWidth > 110 ? (kScreenWidth - stringWidth) / 2 : 105;
int boxY = 97;
int boxWidth = stringWidth > 110 ? stringWidth : 110;
int boxHeight = 27;
@@ -878,191 +456,6 @@ bool SupernovaEngine::quitGameDialog() {
return quit;
}
-Common::MemoryReadStream *SupernovaEngine::convertToMod(const char *filename, int version) {
- // MSN format
- struct {
- uint16 seg;
- uint16 start;
- uint16 end;
- uint16 loopStart;
- uint16 loopEnd;
- char volume;
- char dummy[5];
- } instr2[22];
- int nbInstr2; // 22 for version1, 15 for version 2
- int16 songLength;
- char arrangement[128];
- int16 patternNumber;
- int32 note2[28][64][4];
-
- nbInstr2 = ((version == 1) ? 22 : 15);
-
- Common::File msnFile;
- msnFile.open(filename);
- if (!msnFile.isOpen()) {
- warning("Data file '%s' not found", msnFile.getName());
- return NULL;
- }
-
- for (int i = 0 ; i < nbInstr2 ; ++i) {
- instr2[i].seg = msnFile.readUint16LE();
- instr2[i].start = msnFile.readUint16LE();
- instr2[i].end = msnFile.readUint16LE();
- instr2[i].loopStart = msnFile.readUint16LE();
- instr2[i].loopEnd = msnFile.readUint16LE();
- instr2[i].volume = msnFile.readByte();
- msnFile.read(instr2[i].dummy, 5);
- }
- songLength = msnFile.readSint16LE();
- msnFile.read(arrangement, 128);
- patternNumber = msnFile.readSint16LE();
- for (int p = 0 ; p < patternNumber ; ++p) {
- for (int n = 0 ; n < 64 ; ++n) {
- for (int k = 0 ; k < 4 ; ++k) {
- note2[p][n][k] = msnFile.readSint32LE();
- }
- }
- }
-
- /* MOD format */
- struct {
- char iname[22];
- uint16 length;
- char finetune;
- char volume;
- uint16 loopStart;
- uint16 loopLength;
- } instr[31];
- int32 note[28][64][4];
-
- // We can't recover some MOD effects since several of them are mapped to 0.
- // Assume the MSN effect of value 0 is Arpeggio (MOD effect of value 0).
- const char invConvEff[8] = {0, 1, 2, 3, 10, 12, 13 ,15};
-
- // Reminder from convertToMsn
- // 31 30 29 28 27 26 25 24 - 23 22 21 20 19 18 17 16 - 15 14 13 12 11 10 09 08 - 07 06 05 04 03 02 01 00
- // h h h h g g g g f f f f e e e e d d d d c c c c b b b b a a a a
- //
- // MSN:
- // hhhh (4 bits) Cleared to 0
- // dddd c (5 bits) Sample index | after mapping through convInstr
- // ccc (3 bits) Effect type | after mapping through convEff
- // bbbb aaaa (8 bits) Effect value | unmodified
- // gggg ffff eeee (12 bits) Sample period | unmodified
- //
- // MS2:
- // hhhh (4 bits) Cleared to 0
- // dddd (4 bits) Sample index | after mapping through convInstr
- // cccc (4 bits) Effect type | unmodified
- // bbbb aaaa (8 bits) Effect value | unmodified
- // gggg ffff eeee (12 bits) Sample period | transformed (0xE000 / p) - 256
- //
- // MOD:
- // hhhh dddd (8 bits) Sample index
- // cccc (4 bits) Effect type for this channel/division
- // bbbb aaaa (8 bits) Effect value
- // gggg ffff eeee (12 bits) Sample period
-
- // Can we recover the instruments mapping? I don't think so as part of the original instrument index is cleared.
- // And it doesn't really matter as long as we are consistent.
- // However we need to make sure 31 (or 15 in MS2) is mapped to 0 in MOD.
- // We just add 1 to all other values, and this means a 1 <-> 1 mapping for the instruments
- for (int p = 0; p < patternNumber; ++p) {
- for (int n = 0; n < 64; ++n) {
- for (int k = 0; k < 4; ++k) {
- int32* l = &(note[p][n][k]);
- *l = note2[p][n][k];
- int32 i = 0;
- if (nbInstr2 == 22) { // version 1
- i = ((*l & 0xF800) >> 11);
- int32 e = ((*l & 0x0700) >> 8);
- int32 e1 = invConvEff[e];
- *l &= 0x0FFF00FF;
- *l |= (e1 << 8);
- } else { // version 2
- int32 h = (*l >> 16);
- i = ((*l & 0xF000) >> 12);
- *l &= 0x00000FFF;
- if (h)
- h = 0xE000 / (h + 256);
- *l |= (h << 16);
- if (i == 15)
- i = 31;
- }
-
- // Add back index in note
- if (i != 31) {
- ++i;
- *l |= ((i & 0x0F) << 12);
- *l |= ((i & 0xF0) << 24);
- }
- }
- }
- }
-
- for (int i = 0; i < 31; ++i) {
- // iname is not stored in the mod file. Just set it to 'instrument#'
- // finetune is not stored either. Assume 0.
- memset(instr[i].iname, 0, 22);
- sprintf(instr[i].iname, "instrument%d", i+1);
- instr[i].length = 0;
- instr[i].finetune = 0;
- instr[i].volume = 0;
- instr[i].loopStart = 0;
- instr[i].loopLength = 0;
-
- if (i < nbInstr2) {
- instr[i].length = ((instr2[i].end - instr2[i].start) >> 1);
- instr[i].loopStart = ((instr2[i].loopStart - instr2[i].start) >> 1);
- instr[i].loopLength = (( instr2[i].loopEnd - instr2[i].loopStart) >> 1);
- instr[i].volume = instr2[i].volume;
- }
- }
-
- // The ciaaSpeed is kind of useless and not present in the MSN file.
- // Traditionally 0x78 in SoundTracker. Was used in NoiseTracker as a restart point.
- // ProTracker uses 0x7F. FastTracker uses it as a restart point, whereas ScreamTracker 3 uses 0x7F like ProTracker.
- // You can use this to roughly detect which tracker made a MOD, and detection gets more accurate for more obscure MOD types.
- char ciaaSpeed = 0x7F;
-
- // The mark cannot be recovered either. Since we have 4 channels and 31 instrument it can be either ID='M.K.' or ID='4CHN'.
- // Assume 'M.K.'
- const char mark[4] = { 'M', '.', 'K', '.' };
-
- Common::MemoryWriteStreamDynamic buffer(DisposeAfterUse::NO);
-
- buffer.write(msnFile.getName(), 19);
- buffer.writeByte(0);
-
- for (int i = 0 ; i < 31 ; ++i) {
- buffer.write(instr[i].iname, 22);
- buffer.writeUint16BE(instr[i].length);
- buffer.writeByte(instr[i].finetune);
- buffer.writeByte(instr[i].volume);
- buffer.writeUint16BE(instr[i].loopStart);
- buffer.writeUint16BE(instr[i].loopLength);
- }
- buffer.writeByte((char)songLength);
- buffer.writeByte(ciaaSpeed);
- buffer.write(arrangement, 128);
- buffer.write(mark, 4);
-
- for (int p = 0 ; p < patternNumber ; ++p) {
- for (int n = 0 ; n < 64 ; ++n) {
- for (int k = 0 ; k < 4 ; ++k) {
-// buffer.writeUint32BE(*((uint32*)(note[p][n]+k)));
- buffer.writeSint32BE(note[p][n][k]);
- }
- }
- }
-
- uint nb;
- char buf[4096];
- while ((nb = msnFile.read(buf, 4096)) > 0)
- buffer.write(buf, nb);
-
- return new Common::MemoryReadStream(buffer.getData(), buffer.size(), DisposeAfterUse::YES);
-}
bool SupernovaEngine::canLoadGameStateCurrently() {
return _allowLoadGame;
@@ -1117,10 +510,11 @@ bool SupernovaEngine::loadGame(int slot) {
_gm->deserialize(savefile, saveVersion);
if (saveVersion >= 5) {
- _menuBrightness = savefile->readByte();
- _brightness = savefile->readByte();
+ _screen->setGuiBrightness(savefile->readByte());
+ _screen->setViewportBrightness(savefile->readByte());
} else {
- _menuBrightness = _brightness = 255;
+ _screen->setGuiBrightness(255);
+ _screen->setViewportBrightness(255);
}
delete savefile;
@@ -1153,8 +547,8 @@ bool SupernovaEngine::saveGame(int slot, const Common::String &description) {
Graphics::saveThumbnail(*savefile);
_gm->serialize(savefile);
- savefile->writeByte(_menuBrightness);
- savefile->writeByte(_brightness);
+ savefile->writeByte(_screen->getGuiBrightness());
+ savefile->writeByte(_screen->getViewportBrightness());
savefile->finalize();
delete savefile;
@@ -1169,59 +563,5 @@ void SupernovaEngine::errorTempSave(bool saving) {
error("Unrecoverable error");
}
-ScreenBufferStack::ScreenBufferStack()
- : _last(_buffer) {
-}
-
-void ScreenBufferStack::push(int x, int y, int width, int height) {
- if (_last == ARRAYEND(_buffer))
- return;
-
- Graphics::Surface* screenSurface = g_system->lockScreen();
-
- if (x < 0) {
- width += x;
- x = 0;
- }
- if (x + width > screenSurface->w)
- width = screenSurface->w - x;
-
- if (y < 0) {
- height += y;
- y = 0;
- }
- if (y + height > screenSurface->h)
- height = screenSurface->h - y;
-
- _last->_pixels = new byte[width * height];
- byte *pixels = _last->_pixels;
- const byte *screen = static_cast<const byte *>(screenSurface->getBasePtr(x, y));
- for (int i = 0; i < height; ++i) {
- Common::copy(screen, screen + width, pixels);
- screen += screenSurface->pitch;
- pixels += width;
- }
- g_system->unlockScreen();
-
- _last->_x = x;
- _last->_y = y;
- _last->_width = width;
- _last->_height = height;
-
- ++_last;
-}
-
-void ScreenBufferStack::restore() {
- if (_last == _buffer)
- return;
-
- --_last;
- g_system->lockScreen()->copyRectToSurface(
- _last->_pixels, _last->_width, _last->_x, _last->_y,
- _last->_width, _last->_height);
- g_system->unlockScreen();
-
- delete[] _last->_pixels;
-}
}
diff --git a/engines/supernova/supernova.h b/engines/supernova/supernova.h
index e01fb778a5..132e25deeb 100644
--- a/engines/supernova/supernova.h
+++ b/engines/supernova/supernova.h
@@ -23,9 +23,6 @@
#ifndef SUPERNOVA_SUPERNOVA_H
#define SUPERNOVA_SUPERNOVA_H
-#include "audio/audiostream.h"
-#include "audio/mixer.h"
-#include "audio/decoders/raw.h"
#include "common/array.h"
#include "common/events.h"
#include "common/random.h"
@@ -38,6 +35,7 @@
#include "supernova/graphics.h"
#include "supernova/msn_def.h"
#include "supernova/rooms.h"
+#include "supernova/sound.h"
namespace Supernova {
@@ -48,96 +46,55 @@ namespace Supernova {
#define SUPERNOVA_DAT "supernova.dat"
#define SUPERNOVA_DAT_VERSION 1
-
-struct ScreenBuffer {
- ScreenBuffer()
- : _x(0)
- , _y(0)
- , _width(0)
- , _height(0)
- , _pixels(NULL)
- {}
-
- byte *_pixels;
- int _x;
- int _y;
- int _width;
- int _height;
-};
-class ScreenBufferStack {
-public:
- ScreenBufferStack();
-
- void push(int x, int y, int width, int height);
- void restore();
-
-private:
- ScreenBuffer _buffer[8];
- ScreenBuffer *_last;
-};
-
-struct SoundSample {
- SoundSample()
- : _buffer(NULL)
- , _length(0)
- {}
-
- ~SoundSample() {
- delete[] _buffer;
- }
-
- byte *_buffer;
- int _length;
-};
-
class GuiElement;
+class ResourceManager;
+class Sound;
+class console;
+class GameManager;
+class Screen;
+
class SupernovaEngine : public Engine {
public:
explicit SupernovaEngine(OSystem *syst);
~SupernovaEngine();
virtual Common::Error run();
+ virtual Common::Error loadGameState(int slot);
+ virtual bool canLoadGameStateCurrently();
+ virtual Common::Error saveGameState(int slot, const Common::String &desc);
+ virtual bool canSaveGameStateCurrently();
+ virtual bool hasFeature(EngineFeature f) const;
+ virtual void pauseEngineIntern(bool pause);
- Common::RandomSource _rnd;
GameManager *_gm;
Console *_console;
- Audio::SoundHandle _soundHandle;
- ScreenBufferStack _screenBuffer;
- byte _mouseNormal[256];
- byte _mouseWait[256];
- MSNImageDecoder *_currentImage;
- SoundSample _soundSamples[kAudioNumSamples];
- Common::MemoryReadStream *_soundMusicIntro;
- Common::MemoryReadStream *_soundMusicOutro;
- int _screenWidth;
- int _screenHeight;
+ Sound *_sound;
+ ResourceManager *_resMan;
+ Screen *_screen;
bool _allowLoadGame;
bool _allowSaveGame;
Common::StringArray _gameStrings;
Common::String _nullString;
- byte _menuBrightness;
- byte _brightness;
uint _delay;
- bool _messageDisplayed;
int _textSpeed;
- int _textCursorX;
- int _textCursorY;
- int _textColor;
- int textWidth(const char *text);
- int textWidth(const uint16 key);
Common::Error loadGameStrings();
- void initData();
- void initPalette();
+ void init();
+ bool loadGame(int slot);
+ bool saveGame(int slot, const Common::String &description);
+ bool quitGameDialog();
+ void errorTempSave(bool saving);
+ void setTextSpeed();
+ const Common::String &getGameString(int idx) const;
+ void setGameString(int idx, const Common::String &string);
+
+ // forwarding calls
+ void playSound(AudioId sample);
+ void playSound(MusicId index);
void paletteFadeIn();
void paletteFadeOut();
void paletteBrightness();
- void updateEvents();
- void playSound(AudioIndex sample);
- void playSoundMod(int filenumber);
- void stopSound();
- void renderImageSection(int section);
void renderImage(int section);
bool setCurrentImage(int filenumber);
void saveScreen(int x, int y, int width, int height);
@@ -145,77 +102,22 @@ public:
void restoreScreen();
void renderRoom(Room &room);
void renderMessage(const char *text, MessagePosition position = kMessageNormal);
+ void renderMessage(const Common::String &text, MessagePosition position = kMessageNormal);
+ void renderMessage(StringId stringId, MessagePosition position = kMessageNormal,
+ Common::String var1 = "", Common::String var2 = "");
void removeMessage();
- void renderText(const char *text, int x, int y, byte color);
- void renderText(const uint16 character, int x, int y, byte color);
- void renderText(const char *text);
void renderText(const uint16 character);
+ void renderText(const char *text);
+ void renderText(const Common::String &text);
+ void renderText(StringId stringId);
+ void renderText(const uint16 character, int x, int y, byte color);
+ void renderText(const char *text, int x, int y, byte color);
+ void renderText(const Common::String &text, int x, int y, byte color);
+ void renderText(StringId stringId, int x, int y, byte color);
void renderText(const GuiElement &guiElement);
void renderBox(int x, int y, int width, int height, byte color);
void renderBox(const GuiElement &guiElement);
void setColor63(byte value);
- bool loadGame(int slot);
- bool saveGame(int slot, const Common::String &description);
- bool quitGameDialog();
- void errorTempSave(bool saving);
- void setTextSpeed();
-
- const Common::String &getGameString(int idx) const {
- if (idx < 0 || idx >= (int)_gameStrings.size())
- return _nullString;
- return _gameStrings[idx];
- }
-
- void setGameString(int idx, const Common::String &string) {
- if (idx < 0)
- return;
- while ((int)_gameStrings.size() <= idx)
- _gameStrings.push_back(Common::String());
- _gameStrings[idx] = string;
- }
-
- int textWidth(const Common::String &text) {
- if (text.empty())
- return 0;
- return textWidth(text.c_str());
- }
- void renderMessage(StringID stringId, MessagePosition position = kMessageNormal, Common::String var1 = "", Common::String var2 = "") {
- Common::String text = getGameString(stringId);
- if (!var1.empty()) {
- if (!var2.empty())
- text = Common::String::format(text.c_str(), var1.c_str(), var2.c_str());
- else
- text = Common::String::format(text.c_str(), var1.c_str());
- }
- renderMessage(text, position);
- }
- void renderMessage(const Common::String &text, MessagePosition position = kMessageNormal) {
- if (!text.empty())
- renderMessage(text.c_str(), position);
- }
- void renderText(StringID stringId, int x, int y, byte color) {
- renderText(getGameString(stringId), x, y, color);
- }
- void renderText(const Common::String &text, int x, int y, byte color) {
- if (!text.empty())
- renderText(text.c_str(), x, y, color);
- }
- void renderText(StringID stringId) {
- renderText(getGameString(stringId));
- }
- void renderText(const Common::String &text) {
- if (!text.empty())
- renderText(text.c_str());
- }
-
- Common::MemoryReadStream *convertToMod(const char *filename, int version = 1);
-
- virtual Common::Error loadGameState(int slot);
- virtual bool canLoadGameStateCurrently();
- virtual Common::Error saveGameState(int slot, const Common::String &desc);
- virtual bool canSaveGameStateCurrently();
- virtual bool hasFeature(EngineFeature f) const;
- virtual void pauseEngineIntern(bool pause);
};
}
diff --git a/engines/sword1/detection.cpp b/engines/sword1/detection.cpp
index d4343c8a9f..0b81690bc5 100644
--- a/engines/sword1/detection.cpp
+++ b/engines/sword1/detection.cpp
@@ -300,7 +300,11 @@ SaveStateDescriptor SwordMetaEngine::querySaveMetaInfos(const char *target, int
in->skip(1);
if (Graphics::checkThumbnailHeader(*in)) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ delete in;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
}
diff --git a/engines/sword25/gfx/graphicengine.cpp b/engines/sword25/gfx/graphicengine.cpp
index fd3b63aeee..ca1f37c9d3 100644
--- a/engines/sword25/gfx/graphicengine.cpp
+++ b/engines/sword25/gfx/graphicengine.cpp
@@ -362,7 +362,7 @@ void GraphicEngine::updateLastFrameDuration() {
}
bool GraphicEngine::saveThumbnailScreenshot(const Common::String &filename) {
- // Note: In ScumMVM, rather than saivng the thumbnail to a file, we store it in memory
+ // Note: In ScummVM, rather than saving the thumbnail to a file, we store it in memory
// until needed when creating savegame files
delete _thumbnail;
@@ -373,10 +373,10 @@ bool GraphicEngine::saveThumbnailScreenshot(const Common::String &filename) {
void GraphicEngine::ARGBColorToLuaColor(lua_State *L, uint color) {
lua_Number components[4] = {
- (lua_Number)((color >> 16) & 0xff), // Red
- (lua_Number)((color >> 8) & 0xff), // Green
- (lua_Number)(color & 0xff), // Blue
- (lua_Number)(color >> 24), // Alpha
+ (lua_Number)((color >> 16) & 0xff), // Red
+ (lua_Number)((color >> 8) & 0xff), // Green
+ (lua_Number)( color & 0xff), // Blue
+ (lua_Number)( color >> 24), // Alpha
};
lua_newtable(L);
diff --git a/engines/teenagent/detection.cpp b/engines/teenagent/detection.cpp
index caa7bdbec9..e35e7033d5 100644
--- a/engines/teenagent/detection.cpp
+++ b/engines/teenagent/detection.cpp
@@ -178,8 +178,11 @@ public:
SaveStateDescriptor ssd(slot, desc);
//checking for the thumbnail
- if (Graphics::Surface *const thumb = Graphics::loadThumbnail(*in))
- ssd.setThumbnail(thumb);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ return SaveStateDescriptor();
+ }
+ ssd.setThumbnail(thumbnail);
return ssd;
}
diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp
index 1b5af76ee7..589c95de3b 100644
--- a/engines/testbed/graphics.cpp
+++ b/engines/testbed/graphics.cpp
@@ -464,7 +464,7 @@ TestExitStatus GFXtests::fullScreenMode() {
}
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !isFeatureEnabled);
+ g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !isFeatureEnabled);
g_system->endGFXTransaction();
// Current state should be now !isFeatureEnabled
@@ -482,7 +482,7 @@ TestExitStatus GFXtests::fullScreenMode() {
}
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !isFeatureEnabled);
+ g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !isFeatureEnabled);
g_system->endGFXTransaction();
g_system->delayMillis(1000);
@@ -536,7 +536,7 @@ TestExitStatus GFXtests::filteringMode() {
if (g_system->hasFeature(OSystem::kFeatureFullscreenMode) && !g_system->getFeatureState(OSystem::kFeatureFullscreenMode)) {
fullScreenToggled = true;
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureFullscreenMode, true);
+ g_system->setFeatureState(OSystem::kFeatureFullscreenMode, true);
g_system->endGFXTransaction();
}
@@ -557,7 +557,7 @@ TestExitStatus GFXtests::filteringMode() {
}
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureFilteringMode, !isFeatureEnabled);
+ g_system->setFeatureState(OSystem::kFeatureFilteringMode, !isFeatureEnabled);
g_system->endGFXTransaction();
// Current state should be now !isFeatureEnabled
@@ -575,7 +575,7 @@ TestExitStatus GFXtests::filteringMode() {
}
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureFilteringMode, !isFeatureEnabled);
+ g_system->setFeatureState(OSystem::kFeatureFilteringMode, !isFeatureEnabled);
g_system->endGFXTransaction();
g_system->delayMillis(1000);
@@ -591,7 +591,7 @@ TestExitStatus GFXtests::filteringMode() {
// Restore fullscreen state
if (fullScreenToggled) {
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureFullscreenMode, false);
+ g_system->setFeatureState(OSystem::kFeatureFullscreenMode, false);
g_system->endGFXTransaction();
}
@@ -639,7 +639,7 @@ TestExitStatus GFXtests::aspectRatio() {
}
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, !isFeatureEnabled);
+ g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, !isFeatureEnabled);
g_system->endGFXTransaction();
g_system->delayMillis(1000);
@@ -653,7 +653,7 @@ TestExitStatus GFXtests::aspectRatio() {
}
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, isFeatureEnabled);
+ g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, isFeatureEnabled);
g_system->endGFXTransaction();
} else {
Testsuite::displayMessage("feature not supported");
@@ -835,13 +835,13 @@ TestExitStatus GFXtests::iconifyWindow() {
// Toggle
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureIconifyWindow, !isFeatureEnabled);
+ g_system->setFeatureState(OSystem::kFeatureIconifyWindow, !isFeatureEnabled);
g_system->endGFXTransaction();
g_system->delayMillis(1000);
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureIconifyWindow, isFeatureEnabled);
+ g_system->setFeatureState(OSystem::kFeatureIconifyWindow, isFeatureEnabled);
g_system->endGFXTransaction();
} else {
Testsuite::displayMessage("feature not supported");
@@ -884,7 +884,7 @@ TestExitStatus GFXtests::scaledCursors() {
if (isAspectRatioCorrected) {
g_system->beginGFXTransaction();
- g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, false);
+ g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, false);
g_system->endGFXTransaction();
}
@@ -911,8 +911,8 @@ TestExitStatus GFXtests::scaledCursors() {
g_system->beginGFXTransaction();
- bool isGFXModeSet = g_system->setGraphicsMode(gfxMode->id);
- g_system->initSize(320, 200);
+ bool isGFXModeSet = g_system->setGraphicsMode(gfxMode->id);
+ g_system->initSize(320, 200);
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
@@ -947,12 +947,13 @@ TestExitStatus GFXtests::scaledCursors() {
// Restore Original State
g_system->beginGFXTransaction();
- bool isGFXModeSet = g_system->setGraphicsMode(currGFXMode);
- g_system->initSize(320, 200);
- if (isAspectRatioCorrected) {
- g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, true);
- }
+ bool isGFXModeSet = g_system->setGraphicsMode(currGFXMode);
+ g_system->initSize(320, 200);
+
+ if (isAspectRatioCorrected) {
+ g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, true);
+ }
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
@@ -1226,7 +1227,7 @@ TestExitStatus GFXtests::pixelFormats() {
// Switch to that pixel Format
g_system->beginGFXTransaction();
- g_system->initSize(320, 200, &(*iter));
+ g_system->initSize(320, 200, &(*iter));
g_system->endGFXTransaction();
Testsuite::clearScreen(true);
@@ -1272,7 +1273,7 @@ TestExitStatus GFXtests::pixelFormats() {
// Revert back to 8bpp
g_system->beginGFXTransaction();
- g_system->initSize(320, 200);
+ g_system->initSize(320, 200);
g_system->endGFXTransaction();
GFXTestSuite::setCustomColor(255, 0, 0);
initMousePalette();
diff --git a/engines/tinsel/cursor.cpp b/engines/tinsel/cursor.cpp
index e69031d572..c23e4f2845 100644
--- a/engines/tinsel/cursor.cpp
+++ b/engines/tinsel/cursor.cpp
@@ -375,6 +375,10 @@ void SetAuxCursor(SCNHANDLE hFilm) {
DelAuxCursor(); // Get rid of previous
+ // WORKAROUND: There's no palette when loading a DW1 savegame with a held item, so exit if so
+ if (!BgPal())
+ return;
+
GetCursorXY(&x, &y, false); // Note: also waits for cursor to appear
pim = GetImageFromFilm(hFilm, 0, &pfr, &pmi, &pfilm);// Get pointer to image
diff --git a/engines/tinsel/pcode.cpp b/engines/tinsel/pcode.cpp
index dc19f39405..8899eea65b 100644
--- a/engines/tinsel/pcode.cpp
+++ b/engines/tinsel/pcode.cpp
@@ -156,6 +156,7 @@ static const byte fragment14[] = {OP_LIBCALL | OPSIZE8, 58,
OP_IMM, FRAGMENT_DWORD((42 << 23)), OP_ONE, OP_ZERO, OP_LIBCALL | OPSIZE8, 44,
OP_LIBCALL | OPSIZE8, 97, OP_JUMP | OPSIZE16, FRAGMENT_WORD(2220)
};
+static const byte fragment15[] = { OP_JMPFALSE | OPSIZE16, FRAGMENT_WORD(154) };
#undef FRAGMENT_WORD
@@ -226,6 +227,9 @@ const WorkaroundEntry workaroundList[] = {
// quitting the game when no user input happens for a while
{TINSEL_V1, true, true, Common::kPlatformPSX, 0, 2186, sizeof(fragment14), fragment14},
+ // DW1-GRA: Fixes hang in Temple, when trying to use items on the big hammer
+ {TINSEL_V1, false, false, Common::kPlatformUnknown, 276915849, 0x98, sizeof(fragment15), fragment15},
+
{TINSEL_V0, false, false, Common::kPlatformUnknown, 0, 0, 0, NULL}
};
diff --git a/engines/titanic/core/project_item.cpp b/engines/titanic/core/project_item.cpp
index b2bd5cd92b..6da891c417 100644
--- a/engines/titanic/core/project_item.cpp
+++ b/engines/titanic/core/project_item.cpp
@@ -190,10 +190,6 @@ void CProjectItem::loadGame(int slotId) {
// Load the savegame header in
TitanicSavegameHeader header;
readSavegameHeader(&file, header);
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
g_vm->_events->setTotalPlayTicks(header._totalFrames);
@@ -488,13 +484,9 @@ SaveStateList CProjectItem::getSavegameList(const Common::String &target) {
if (in) {
SimpleFile f;
f.open(in);
- if (!readSavegameHeader(&f, header))
- continue;
-
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+ if (readSavegameHeader(&f, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- header._thumbnail->free();
- delete header._thumbnail;
delete in;
}
}
@@ -503,7 +495,7 @@ SaveStateList CProjectItem::getSavegameList(const Common::String &target) {
return saveList;
}
-bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) {
+bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
header._thumbnail = nullptr;
header._totalFrames = 0;
@@ -526,8 +518,7 @@ bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &h
while ((ch = (char)file->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*file);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*file, header._thumbnail, skipThumbnail))
return false;
// Read in save date/time
diff --git a/engines/titanic/core/project_item.h b/engines/titanic/core/project_item.h
index c9fd6f97cb..ef557f7f9d 100644
--- a/engines/titanic/core/project_item.h
+++ b/engines/titanic/core/project_item.h
@@ -155,7 +155,7 @@ public:
/**
* Read in the header information for a savegame
*/
- static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header);
+ static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header, bool loadThumbnail = false);
public:
CLASSDEF;
CProjectItem();
diff --git a/engines/titanic/detection.cpp b/engines/titanic/detection.cpp
index b33ac51bed..c98fbbdade 100644
--- a/engines/titanic/detection.cpp
+++ b/engines/titanic/detection.cpp
@@ -128,11 +128,6 @@ SaveStateList TitanicMetaEngine::listSaves(const char *target) const {
if (Titanic::CProjectItem::readSavegameHeader(&cf, header))
saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
cf.close();
}
}
@@ -161,7 +156,10 @@ SaveStateDescriptor TitanicMetaEngine::querySaveMetaInfos(const char *target, in
file.open(f);
Titanic::TitanicSavegameHeader header;
- Titanic::CProjectItem::readSavegameHeader(&file, header);
+ if (!Titanic::CProjectItem::readSavegameHeader(&file, header, false)) {
+ file.close();
+ return SaveStateDescriptor();
+ }
file.close();
diff --git a/engines/titanic/pet_control/pet_load_save.cpp b/engines/titanic/pet_control/pet_load_save.cpp
index d918478fb1..72770b9eb2 100644
--- a/engines/titanic/pet_control/pet_load_save.cpp
+++ b/engines/titanic/pet_control/pet_load_save.cpp
@@ -135,11 +135,6 @@ void CPetLoadSave::resetSlots() {
_slotNames[idx].setText(header._saveName);
}
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
file.close();
}
}
diff --git a/engines/titanic/titanic.cpp b/engines/titanic/titanic.cpp
index e0e4a07ce6..5daf399b04 100644
--- a/engines/titanic/titanic.cpp
+++ b/engines/titanic/titanic.cpp
@@ -49,7 +49,6 @@
#include "common/translation.h"
#include "engines/util.h"
#include "graphics/scaler.h"
-#include "graphics/thumbnail.h"
#include "graphics/screen.h"
#include "gui/saveload.h"
@@ -256,11 +255,6 @@ CString TitanicEngine::getSavegameName(int slot) {
TitanicSavegameHeader header;
bool isValid = CProjectItem::readSavegameHeader(&file, header);
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
file.close();
if (isValid)
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 9303760057..0cd9596c8c 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -276,7 +276,7 @@ SaveStateList ToltecsMetaEngine::listSaves(const char *target) const {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ if (Toltecs::ToltecsEngine::readSaveHeader(in, header) == Toltecs::ToltecsEngine::kRSHENoError) {
saveList.push_back(SaveStateDescriptor(slotNum, header.description));
}
delete in;
@@ -325,7 +325,7 @@ SaveStateDescriptor ToltecsMetaEngine::querySaveMetaInfos(const char *target, in
Toltecs::ToltecsEngine::SaveHeader header;
Toltecs::ToltecsEngine::kReadSaveHeaderError error;
- error = Toltecs::ToltecsEngine::readSaveHeader(in, true, header);
+ error = Toltecs::ToltecsEngine::readSaveHeader(in, header, false);
delete in;
if (error == Toltecs::ToltecsEngine::kRSHENoError) {
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 5fc0599c2a..c4373265e6 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -525,7 +525,7 @@ int MenuSystem::loadSavegamesList() {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ if (Toltecs::ToltecsEngine::readSaveHeader(in, header) == Toltecs::ToltecsEngine::kRSHENoError) {
_savegames.push_back(SavegameItem(slotNum, header.description));
//debug("%s -> %s", file->c_str(), header.description.c_str());
}
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 409fc97076..1f2198fc35 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -41,7 +41,7 @@ namespace Toltecs {
#define TOLTECS_SAVEGAME_VERSION 4
-ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+WARN_UNUSED_RESULT ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) {
header.version = in->readUint32LE();
if (header.version > TOLTECS_SAVEGAME_VERSION)
@@ -52,10 +52,8 @@ ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::Seekab
while (descriptionLen--)
header.description += (char)in->readByte();
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*in);
- } else {
- Graphics::skipThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ return kRSHEIoError;
}
// Not used yet, reserved for future usage
@@ -147,7 +145,7 @@ void ToltecsEngine::loadgame(const char *filename) {
SaveHeader header;
- kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
+ kReadSaveHeaderError errorCode = readSaveHeader(in, header);
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index ece82f4a1a..1c9e9366c7 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -225,7 +225,7 @@ public:
const char *getSavegameFilename(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
- static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
+ WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true);
};
diff --git a/engines/tony/loc.cpp b/engines/tony/loc.cpp
index be2b20294f..fe553b5fab 100644
--- a/engines/tony/loc.cpp
+++ b/engines/tony/loc.cpp
@@ -1005,7 +1005,7 @@ void RMCharacter::goTo(CORO_PARAM, RMPoint destcoord, bool bReversed) {
_walkCount = 0;
if (bReversed) {
- while (0) ;
+ while (0);
}
int nPatt = getCurPattern();
diff --git a/engines/toon/detection.cpp b/engines/toon/detection.cpp
index e93d676d87..6eb38c4883 100644
--- a/engines/toon/detection.cpp
+++ b/engines/toon/detection.cpp
@@ -232,7 +232,11 @@ SaveStateDescriptor ToonMetaEngine::querySaveMetaInfos(const char *target, int s
SaveStateDescriptor desc(slot, saveName);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*file, thumbnail)) {
+ delete file;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
uint32 saveDate = file->readUint32BE();
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index e476391f71..5d31cca75e 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -131,9 +131,6 @@ public:
if (in) {
if (TsAGE::Saver::readSavegameHeader(in, header)) {
saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- header._thumbnail->free();
- delete header._thumbnail;
}
delete in;
@@ -161,7 +158,11 @@ public:
if (f) {
TsAGE::tSageSavegameHeader header;
- TsAGE::Saver::readSavegameHeader(f, header);
+ if (!TsAGE::Saver::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index 03f615db21..81bb973d02 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -189,10 +189,10 @@ Common::Error Saver::restore(int slot) {
// Read in the savegame header
tSageSavegameHeader header;
- readSavegameHeader(saveFile, header);
- if (header._thumbnail)
- header._thumbnail->free();
- delete header._thumbnail;
+ if (!readSavegameHeader(saveFile, header)) {
+ delete saveFile;
+ return Common::kReadingFailed;
+ }
serializer.setSaveVersion(header._version);
@@ -247,9 +247,8 @@ Common::Error Saver::restore(int slot) {
const char *SAVEGAME_STR = "SCUMMVM_TSAGE";
#define SAVEGAME_STR_SIZE 13
-bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header) {
+WARN_UNUSED_RESULT bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = NULL;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -266,9 +265,9 @@ bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &head
while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._saveYear = in->readSint16LE();
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index 04a1e02b28..3de34489fd 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -221,7 +221,7 @@ public:
Common::Error save(int slot, const Common::String &saveName);
Common::Error restore(int slot);
- static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header, bool skipThumbnail = true);
static void writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &header);
void addListener(SaveListener *obj);
diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp
index 7d07edabd3..119d60f23a 100644
--- a/engines/tucker/detection.cpp
+++ b/engines/tucker/detection.cpp
@@ -175,7 +175,7 @@ public:
if (ext && (slot = atoi(ext + 1)) >= 0 && slot <= Tucker::kLastSaveSlot) {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- if (Tucker::TuckerEngine::readSavegameHeader(in, header, false) == Tucker::TuckerEngine::kSavegameNoError) {
+ if (Tucker::TuckerEngine::readSavegameHeader(in, header) == Tucker::TuckerEngine::kSavegameNoError) {
saveList.push_back(SaveStateDescriptor(slot, header.description));
}
@@ -207,7 +207,7 @@ public:
}
Tucker::TuckerEngine::SavegameHeader header;
- Tucker::TuckerEngine::SavegameError savegameError = Tucker::TuckerEngine::readSavegameHeader(file, header, true);
+ Tucker::TuckerEngine::SavegameError savegameError = Tucker::TuckerEngine::readSavegameHeader(file, header, false);
if (savegameError) {
delete file;
return SaveStateDescriptor();
diff --git a/engines/tucker/saveload.cpp b/engines/tucker/saveload.cpp
index a56ced915e..af836593c3 100644
--- a/engines/tucker/saveload.cpp
+++ b/engines/tucker/saveload.cpp
@@ -141,7 +141,7 @@ Common::Error TuckerEngine::loadGameState(int slot) {
}
-TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target, int slot, SavegameHeader &header) {
+WARN_UNUSED_RESULT TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target, int slot, SavegameHeader &header) {
Common::String fileName = generateGameStateFileName(target, slot);
Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);
@@ -155,8 +155,8 @@ TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target,
return savegameError;
}
-TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool loadThumbnail) {
- header.version = -1;
+WARN_UNUSED_RESULT TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool skipThumbnail) {
+ header.version = 0;
header.flags = 0;
header.description.clear();
header.saveDate = 0;
@@ -196,10 +196,8 @@ TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile
header.saveTime = file->readUint32LE();
header.playTime = file->readUint32LE();
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*file);
- } else {
- Graphics::skipThumbnail(*file);
+ if (!Graphics::loadThumbnail(*file, header.thumbnail, skipThumbnail)) {
+ return kSavegameIoError;
}
}
diff --git a/engines/tucker/tucker.h b/engines/tucker/tucker.h
index 4cb427fe35..e3748680fe 100644
--- a/engines/tucker/tucker.h
+++ b/engines/tucker/tucker.h
@@ -452,8 +452,8 @@ public:
virtual bool hasFeature(EngineFeature f) const;
GUI::Debugger *getDebugger() { return _console; }
- static SavegameError readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool loadThumbnail = false);
- static SavegameError readSavegameHeader(const char *target, int slot, SavegameHeader &header);
+ WARN_UNUSED_RESULT static SavegameError readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool skipThumbnail = true);
+ WARN_UNUSED_RESULT static SavegameError readSavegameHeader(const char *target, int slot, SavegameHeader &header);
bool isAutosaveAllowed();
static bool isAutosaveAllowed(const char *target);
protected:
diff --git a/engines/voyeur/detection.cpp b/engines/voyeur/detection.cpp
index eefe174e94..6452e5741f 100644
--- a/engines/voyeur/detection.cpp
+++ b/engines/voyeur/detection.cpp
@@ -132,7 +132,6 @@ SaveStateList VoyeurMetaEngine::listSaves(const char *target) const {
if (in) {
if (header.read(in)) {
saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- header._thumbnail->free();
}
delete in;
}
@@ -159,7 +158,7 @@ SaveStateDescriptor VoyeurMetaEngine::querySaveMetaInfos(const char *target, int
if (f) {
Voyeur::VoyeurSavegameHeader header;
- header.read(f);
+ header.read(f, false);
delete f;
// Create the return descriptor
diff --git a/engines/voyeur/files_threads.cpp b/engines/voyeur/files_threads.cpp
index 1b4e30665c..9e55b99ca1 100644
--- a/engines/voyeur/files_threads.cpp
+++ b/engines/voyeur/files_threads.cpp
@@ -864,7 +864,7 @@ const byte *ThreadResource::cardPerform(const byte *card) {
if (cardPerform2(card, id)) {
card += subId;
card = cardPerform(card);
- while (*card++ != 61) ;
+ while (*card++ != 61);
} else {
card += subId;
while (*card != 61 && *card != 29)
diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp
index 7f2f0e312e..b7769c1fd4 100644
--- a/engines/voyeur/voyeur.cpp
+++ b/engines/voyeur/voyeur.cpp
@@ -789,9 +789,6 @@ void VoyeurEngine::loadGame(int slot) {
VoyeurSavegameHeader header;
if (!header.read(saveFile))
return;
- if (header._thumbnail)
- header._thumbnail->free();
- delete header._thumbnail;
serializer.setVersion(header._version);
synchronize(serializer);
@@ -856,9 +853,7 @@ void VoyeurEngine::synchronize(Common::Serializer &s) {
/*------------------------------------------------------------------------*/
-bool VoyeurSavegameHeader::read(Common::InSaveFile *f) {
- _thumbnail = NULL;
-
+bool VoyeurSavegameHeader::read(Common::InSaveFile *f, bool skipThumbnail) {
uint32 signature = f->readUint32BE();
if (signature != MKTAG('V', 'O', 'Y', 'R')) {
warning("Invalid savegame");
@@ -875,9 +870,9 @@ bool VoyeurSavegameHeader::read(Common::InSaveFile *f) {
_saveName += c;
// Get the thumbnail
- _thumbnail = Graphics::loadThumbnail(*f);
- if (!_thumbnail)
+ if (!Graphics::loadThumbnail(*f, _thumbnail, skipThumbnail)) {
return false;
+ }
// Read in the save datet/ime
_saveYear = f->readSint16LE();
diff --git a/engines/voyeur/voyeur.h b/engines/voyeur/voyeur.h
index dcd82b24a9..a098ba9e62 100644
--- a/engines/voyeur/voyeur.h
+++ b/engines/voyeur/voyeur.h
@@ -312,7 +312,7 @@ struct VoyeurSavegameHeader {
/**
* Read in the header from the specified file
*/
- bool read(Common::InSaveFile *f);
+ bool read(Common::InSaveFile *f, bool skipThumbnail = true);
/**
* Write out header information to the specified file
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index 0f6a184cb3..15cd33d28c 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -125,7 +125,7 @@ bool BaseRenderOSystem::initRenderer(int width, int height, bool windowed) {
Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
g_system->beginGFXTransaction();
- g_system->initSize(_width, _height, &format);
+ g_system->initSize(_width, _height, &format);
OSystem::TransactionError gfxError = g_system->endGFXTransaction();
if (gfxError != OSystem::kTransactionSuccess) {
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.h b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
index bc267fd656..47099046e9 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -96,7 +96,7 @@ public:
bool setViewport(Rect32 *rect) override { return BaseRenderer::setViewport(rect); }
Rect32 getViewPort() override;
void modTargetRect(Common::Rect *rect);
- void pointFromScreen(Point32 *point) ;
+ void pointFromScreen(Point32 *point);
void pointToScreen(Point32 *point);
void dumpData(const char *filename) override;
diff --git a/engines/xeen/character.cpp b/engines/xeen/character.cpp
index 1f53b2bbfe..6f78e6e626 100644
--- a/engines/xeen/character.cpp
+++ b/engines/xeen/character.cpp
@@ -955,6 +955,7 @@ int Character::getNumAwards() const {
ItemCategory Character::makeItem(int p1, int itemIndex, int p3) {
XeenEngine *vm = Party::_vm;
Scripts &scripts = *vm->_scripts;
+ int itemOffset = vm->getGameID() == GType_Swords ? 6 : 0;
if (!p1)
return CATEGORY_WEAPON;
@@ -967,18 +968,18 @@ ItemCategory Character::makeItem(int p1, int itemIndex, int p3) {
// Randomly pick a category and item Id
if (p3 == 12) {
- if (scripts._itemType < 35) {
+ if (scripts._itemType < (35 + itemOffset)) {
category = CATEGORY_WEAPON;
itemId = scripts._itemType;
- } else if (scripts._itemType < 49) {
+ } else if (scripts._itemType < (49 + itemOffset)) {
category = CATEGORY_ARMOR;
- itemId = scripts._itemType - 35;
- } else if (scripts._itemType < 60) {
+ itemId = scripts._itemType - (35 + itemOffset);
+ } else if (scripts._itemType < (60 + itemOffset)) {
category = CATEGORY_ACCESSORY;
- itemId = scripts._itemType - 49;
+ itemId = scripts._itemType - (49 + itemOffset);
} else {
category = CATEGORY_MISC;
- itemId = scripts._itemType - 60;
+ itemId = scripts._itemType - (60 + itemOffset);
}
} else {
switch (p3) {
@@ -1222,7 +1223,7 @@ void Character::subtractHitPoints(int amount) {
// Subtract the given HP amount
_currentHp -= amount;
- bool breakFlag = _currentHp <= -10;
+ bool breakFlag = _currentHp <= (g_vm->_extOptions._durableArmor ? -80 : -10);
assert(_currentHp < 65000);
if (_currentHp < 1) {
diff --git a/engines/xeen/character.h b/engines/xeen/character.h
index 77e3360748..47312efe66 100644
--- a/engines/xeen/character.h
+++ b/engines/xeen/character.h
@@ -51,7 +51,11 @@ enum Race { HUMAN = 0, ELF = 1, DWARF = 2, GNOME = 3, HALF_ORC = 4 };
enum CharacterClass {
CLASS_KNIGHT = 0, CLASS_PALADIN = 1, CLASS_ARCHER = 2, CLASS_CLERIC = 3,
CLASS_SORCERER = 4, CLASS_ROBBER = 5, CLASS_NINJA = 6, CLASS_BARBARIAN = 7,
- CLASS_DRUID = 8, CLASS_RANGER = 9, TOTAL_CLASSES = 10, CLASS_12 = 12, CLASS_15 = 15, CLASS_16 = 16
+ CLASS_DRUID = 8, CLASS_RANGER = 9, TOTAL_CLASSES = 10
+};
+
+enum HatesClass {
+ HATES_DWARF = 12, HATES_PARTY = 15, HATES_NOBODY = 16
};
enum Attribute {
diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp
index baff2f1f34..f3baca77a4 100644
--- a/engines/xeen/combat.cpp
+++ b/engines/xeen/combat.cpp
@@ -491,12 +491,12 @@ void Combat::moveMonsters() {
switch (party._mazeDirection) {
case DIR_NORTH:
case DIR_SOUTH:
- if (monsterCanMove(pt, Res.MONSTER_GRID_BITMASK[MONSTER_GRID_BITINDEX1[arrIndex]],
+ if (canMonsterMove(pt, Res.MONSTER_GRID_BITMASK[MONSTER_GRID_BITINDEX1[arrIndex]],
MONSTER_GRID_X[arrIndex], MONSTER_GRID_Y[arrIndex], idx)) {
// Move the monster
moveMonster(idx, Common::Point(MONSTER_GRID_X[arrIndex], MONSTER_GRID_Y[arrIndex]));
} else {
- if (monsterCanMove(pt, Res.MONSTER_GRID_BITMASK[MONSTER_GRID_BITINDEX2[arrIndex]],
+ if (canMonsterMove(pt, Res.MONSTER_GRID_BITMASK[MONSTER_GRID_BITINDEX2[arrIndex]],
arrIndex >= 21 && arrIndex <= 27 ? MONSTER_GRID3[arrIndex] : 0,
arrIndex >= 21 && arrIndex <= 27 ? 0 : MONSTER_GRID3[arrIndex],
idx)) {
@@ -511,7 +511,7 @@ void Combat::moveMonsters() {
case DIR_EAST:
case DIR_WEST:
- if (monsterCanMove(pt, Res.MONSTER_GRID_BITMASK[MONSTER_GRID_BITINDEX2[arrIndex]],
+ if (canMonsterMove(pt, Res.MONSTER_GRID_BITMASK[MONSTER_GRID_BITINDEX2[arrIndex]],
arrIndex >= 21 && arrIndex <= 27 ? MONSTER_GRID3[arrIndex] : 0,
arrIndex >= 21 && arrIndex <= 27 ? 0 : MONSTER_GRID3[arrIndex],
idx)) {
@@ -520,7 +520,7 @@ void Combat::moveMonsters() {
} else {
moveMonster(idx, Common::Point(0, MONSTER_GRID3[arrIndex]));
}
- } else if (monsterCanMove(pt, Res.MONSTER_GRID_BITMASK[MONSTER_GRID_BITINDEX1[arrIndex]],
+ } else if (canMonsterMove(pt, Res.MONSTER_GRID_BITMASK[MONSTER_GRID_BITINDEX1[arrIndex]],
MONSTER_GRID_X[arrIndex], MONSTER_GRID_Y[arrIndex], idx)) {
moveMonster(idx, Common::Point(MONSTER_GRID_X[arrIndex], MONSTER_GRID_Y[arrIndex]));
}
@@ -633,12 +633,12 @@ void Combat::monstersAttack() {
_monstersAttacking = false;
- if (_vm->_mode != MODE_SLEEPING) {
+ if (_vm->_mode == MODE_SLEEPING) {
for (uint charNum = 0; charNum < party._activeParty.size(); ++charNum) {
Condition condition = party._activeParty[charNum].worstCondition();
- if (condition != ASLEEP && (condition < PARALYZED || condition == NO_CONDITION)) {
- _vm->_mode = MODE_1;
+ if (condition == DEPRESSED || condition == CONFUSED || condition == NO_CONDITION) {
+ _vm->_mode = MODE_INTERACTIVE;
break;
}
}
@@ -670,8 +670,7 @@ void Combat::setupMonsterAttack(int monsterDataIndex, const Common::Point &pt) {
}
}
-bool Combat::monsterCanMove(const Common::Point &pt, int wallShift,
- int xDiff, int yDiff, int monsterId) {
+bool Combat::canMonsterMove(const Common::Point &pt, int wallShift, int xDiff, int yDiff, int monsterId) {
Map &map = *_vm->_map;
MazeMonster &monster = map._mobData._monsters[monsterId];
MonsterStruct &monsterData = *monster._monsterData;
@@ -815,15 +814,20 @@ void Combat::doMonsterTurn(int monsterId) {
}
MonsterStruct &monsterData = map._monsterData[monsterId];
- bool flag = false;
for (int attackNum = 0; attackNum < monsterData._numberOfAttacks; ++attackNum) {
int charNum = -1;
bool isHated = false;
- if (monsterData._hatesClass != -1) {
- if (monsterData._hatesClass == 15)
- // Monster hates all classes
- goto loop;
+ if (monsterData._hatesClass != CLASS_PALADIN) {
+ if (monsterData._hatesClass == HATES_PARTY) {
+ // Monster hates entire party, even the disabled/dead
+ for (uint idx = 0; idx < _combatParty.size(); ++idx) {
+ doMonsterTurn(monsterId, idx);
+ }
+
+ // Move onto monster's next attack (if any)
+ continue;
+ }
for (uint charIndex = 0; charIndex < _combatParty.size(); ++charIndex) {
Character &c = *_combatParty[charIndex];
@@ -831,10 +835,8 @@ void Combat::doMonsterTurn(int monsterId) {
if (cond >= PARALYZED && cond <= ERADICATED)
continue;
- isHated = false;
switch (monsterData._hatesClass) {
case CLASS_KNIGHT:
- case CLASS_PALADIN:
case CLASS_ARCHER:
case CLASS_CLERIC:
case CLASS_SORCERER:
@@ -845,7 +847,7 @@ void Combat::doMonsterTurn(int monsterId) {
case CLASS_RANGER:
isHated = c._class == monsterData._hatesClass;
break;
- case 12:
+ case HATES_DWARF:
isHated = c._race == DWARF;
break;
default:
@@ -860,102 +862,78 @@ void Combat::doMonsterTurn(int monsterId) {
}
if (!isHated) {
- // No particularly hated foe, so decide which character to start with
- switch (_combatParty.size()) {
- case 1:
- charNum = 0;
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- charNum = _vm->getRandomNumber(0, _combatParty.size() - 1);
- break;
- case 6:
- if (_vm->getRandomNumber(1, 6) == 6)
- charNum = 5;
- else
- charNum = _vm->getRandomNumber(0, 4);
- break;
- }
+ // No particularly hated foe, so pick a random character to start with
+ // Note: Original had a whole switch statement depending on party size, that boiled down to
+ // picking a random character in all cases anyway
+ charNum = _vm->getRandomNumber(0, _combatParty.size() - 1);
}
- // Attacking loop
- do {
- if (!flag) {
- Condition cond = _combatParty[charNum]->worstCondition();
-
- if (cond >= PARALYZED && cond <= ERADICATED) {
- Common::Array<int> ableChars;
- bool skip = false;
-
- for (uint idx = 0; idx < _combatParty.size() && !skip; ++idx) {
- switch (_combatParty[idx]->worstCondition()) {
- case PARALYZED:
- case UNCONSCIOUS:
- //if (flag)
- // skip = true;
- break;
- case DEAD:
- case STONED:
- case ERADICATED:
- break;
- default:
- ableChars.push_back(idx);
- break;
- }
- }
-
- if (!skip) {
- if (ableChars.size() == 0) {
- party._dead = true;
- _vm->_mode = MODE_1;
- return;
- }
-
- charNum = ableChars[_vm->getRandomNumber(0, ableChars.size() - 1)];
- }
+ // If the chosen character is already disabled, we need to pick a still able body character
+ // from the remainder of the combat party
+ Condition cond = _combatParty[charNum]->worstCondition();
+ if (cond >= PARALYZED && cond <= ERADICATED) {
+ Common::Array<int> ableChars;
+
+ for (uint idx = 0; idx < _combatParty.size(); ++idx) {
+ switch (_combatParty[idx]->worstCondition()) {
+ case PARALYZED:
+ case UNCONSCIOUS:
+ case DEAD:
+ case STONED:
+ case ERADICATED:
+ break;
+ default:
+ ableChars.push_back(idx);
+ break;
}
}
- // Unconditional if to get around goto initialization errors
- if (true) {
- Character &c = *_combatParty[charNum];
- if (monsterData._attackType != DT_PHYSICAL || c._conditions[ASLEEP]) {
- doCharDamage(c, charNum, monsterId);
- } else {
- int v = _vm->getRandomNumber(1, 20);
- if (v == 1) {
- // Critical Save
- sound.playFX(6);
- } else {
- if (v == 20)
- // Critical failure
- doCharDamage(c, charNum, monsterId);
- v += monsterData._hitChance / 4 + _vm->getRandomNumber(1,
- monsterData._hitChance);
-
- int ac = c.getArmorClass() + (!_charsBlocked[charNum] ? 10 :
- c.getCurrentLevel() / 2 + 15);
- if (ac > v) {
- sound.playFX(6);
- } else {
- doCharDamage(c, charNum, monsterId);
- }
- }
- }
-
- if (flag)
- break;
+ if (ableChars.size() == 0) {
+ party._dead = true;
+ _vm->_mode = MODE_INTERACTIVE;
+ return;
}
-loop:
- flag = true;
- } while (++charNum < (int)_combatParty.size());
+
+ charNum = ableChars[_vm->getRandomNumber(0, ableChars.size() - 1)];
+ }
+
+ doMonsterTurn(monsterId, charNum);
}
intf.drawParty(true);
}
+void Combat::doMonsterTurn(int monsterId, int charNum) {
+ Map &map = *_vm->_map;
+ Sound &sound = *_vm->_sound;
+ MonsterStruct &monsterData = map._monsterData[monsterId];
+ Character &c = *_combatParty[charNum];
+
+ if (monsterData._attackType != DT_PHYSICAL || c._conditions[ASLEEP]) {
+ doCharDamage(c, charNum, monsterId);
+ } else {
+ int v = _vm->getRandomNumber(1, 20);
+ if (v == 1) {
+ // Critical Save
+ sound.playFX(6);
+ } else {
+ if (v == 20)
+ // Critical failure
+ doCharDamage(c, charNum, monsterId);
+ v += monsterData._hitChance / 4 + _vm->getRandomNumber(1,
+ monsterData._hitChance);
+
+ int ac = c.getArmorClass() + (!_charsBlocked[charNum] ? 10 :
+ c.getCurrentLevel() / 2 + 15);
+ if (ac > v) {
+ sound.playFX(6);
+ } else {
+ doCharDamage(c, charNum, monsterId);
+ }
+ }
+ }
+}
+
int Combat::stopAttack(const Common::Point &diffPt) {
Map &map = *_vm->_map;
Party &party = *_vm->_party;
@@ -1115,7 +1093,7 @@ void Combat::setSpeedTable() {
if (_speedTable.empty()) {
_whosSpeed = 0;
} else if (_whosSpeed >= (int)_speedTable.size() || _speedTable[_whosSpeed] != oldSpeed) {
- for (_whosSpeed = 0; _whosSpeed < (int)charSpeeds.size(); ++_whosSpeed) {
+ for (_whosSpeed = 0; _whosSpeed < (int)_speedTable.size(); ++_whosSpeed) {
if (oldSpeed == _speedTable[_whosSpeed])
break;
}
@@ -1387,6 +1365,7 @@ void Combat::attack(Character &c, RangeType rangeType) {
}
void Combat::attack2(int damage, RangeType rangeType) {
+ Debugger &debugger = *_vm->_debugger;
Interface &intf = *_vm->_interface;
Map &map = *_vm->_map;
Party &party = *_vm->_party;
@@ -1398,6 +1377,8 @@ void Combat::attack2(int damage, RangeType rangeType) {
if (!ccNum && damage && rangeType != RT_SINGLE && monster._spriteId == 89)
damage = 0;
+ if (debugger._superStrength)
+ damage = 10000;
if (!damage) {
sound.playSound(_missVoc, 1);
@@ -2101,4 +2082,21 @@ void Combat::shootRangedWeapon() {
rangedAttack(POW_ARROW);
}
+bool Combat::areMonstersPresent() const {
+ for (int idx = 0; idx < 26; ++idx) {
+ if (_attackMonsters[idx] != -1)
+ return true;
+ }
+
+ return false;
+}
+
+void Combat::reset() {
+ clearShooting();
+ setupCombatParty();
+
+ _combatMode = COMBATMODE_INTERACTIVE;
+ _monster2Attack = -1;
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/combat.h b/engines/xeen/combat.h
index 5d27dc5c4e..e1a02c0759 100644
--- a/engines/xeen/combat.h
+++ b/engines/xeen/combat.h
@@ -58,7 +58,7 @@ enum ShootType {
};
enum CombatMode {
- COMBATMODE_STARTUP = 0, COMBATMODE_1 = 1, COMBATMODE_2 = 2
+ COMBATMODE_STARTUP = 0, COMBATMODE_INTERACTIVE = 1, COMBATMODE_2 = 2
};
enum PowType {
@@ -77,6 +77,7 @@ enum RangeType {
class XeenEngine;
class Character;
class XeenItem;
+class MonsterStruct;
struct PowSlot {
bool _active;
@@ -205,6 +206,11 @@ public:
void clearShooting();
/**
+ * Resets all combat related data
+ */
+ void reset();
+
+ /**
* Gives damage to character or characters in the party
*/
void giveCharDamage(int damage, DamageType attackType, int charIndex);
@@ -273,18 +279,30 @@ public:
/**
* Determines whether a given monster can move
+ * @param pt Monster position
+ * @param wallShift Shift mask for determining direction being moved
+ * @param xDiff X Delta for move
+ * @param yDiff Y Delta for move
+ * @param monsterId Monster number being tested
*/
- bool monsterCanMove(const Common::Point &pt, int wallShift,
- int v1, int v2, int monsterId);
+ bool canMonsterMove(const Common::Point &pt, int wallShift, int xDiff, int yDiff, int monsterId);
/**
* Moves a monster by a given delta amount if it's a valid move
*/
void moveMonster(int monsterId, const Common::Point &moveDelta);
+ /**
+ * Handle a monster's turn at attacking combat party members
+ */
void doMonsterTurn(int monsterId);
/**
+ * Handles a monster's turn at attacking a specific member of the combat party
+ */
+ void doMonsterTurn(int monsterId, int charNum);
+
+ /**
* Called when combat has ended
*/
void endAttack();
@@ -305,6 +323,11 @@ public:
* Fires off a ranged attack at all oncoming monsters
*/
void shootRangedWeapon();
+
+ /**
+ * Returns true if there are any monsters in the vacinity
+ */
+ bool areMonstersPresent() const;
};
} // End of namespace Xeen
diff --git a/engines/xeen/debugger.cpp b/engines/xeen/debugger.cpp
index 978baf1715..322833eed6 100644
--- a/engines/xeen/debugger.cpp
+++ b/engines/xeen/debugger.cpp
@@ -45,7 +45,7 @@ static int strToInt(const char *s) {
/*------------------------------------------------------------------------*/
Debugger::Debugger(XeenEngine *vm) : GUI::Debugger(), _vm(vm),
- _spellId(-1), _invincible(false), _intangible(false) {
+ _spellId(-1), _invincible(false), _intangible(false), _superStrength(false) {
registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
registerCmd("spell", WRAP_METHOD(Debugger, cmdSpell));
registerCmd("spells", WRAP_METHOD(Debugger, cmdSpells));
@@ -55,6 +55,7 @@ Debugger::Debugger(XeenEngine *vm) : GUI::Debugger(), _vm(vm),
registerCmd("map", WRAP_METHOD(Debugger, cmdMap));
registerCmd("pos", WRAP_METHOD(Debugger, cmdPos));
registerCmd("invincible", WRAP_METHOD(Debugger, cmdInvincible));
+ registerCmd("strength", WRAP_METHOD(Debugger, cmdSuperStrength));
registerCmd("intangible", WRAP_METHOD(Debugger, cmdIntangible));
}
@@ -200,6 +201,12 @@ bool Debugger::cmdInvincible(int argc, const char **argv) {
return true;
}
+bool Debugger::cmdSuperStrength(int argc, const char **argv) {
+ _superStrength = (argc < 2) || strcmp(argv[1], "off");
+ debugPrintf("Super-powered attacks are %s\n", _superStrength ? "on" : "off");
+ return true;
+}
+
bool Debugger::cmdIntangible(int argc, const char **argv) {
_intangible = (argc < 2) || strcmp(argv[1], "off");
debugPrintf("Intangibility is %s\n", _intangible ? "on" : "off");
diff --git a/engines/xeen/debugger.h b/engines/xeen/debugger.h
index c459dc1bfa..48eb8f35f6 100644
--- a/engines/xeen/debugger.h
+++ b/engines/xeen/debugger.h
@@ -76,12 +76,18 @@ private:
bool cmdInvincible(int argc, const char **argv);
/**
+ * Flags whether to make the party super-strength attacks
+ */
+ bool cmdSuperStrength(int argc, const char **argv);
+
+ /**
* Flags whether to make the party invincible
*/
bool cmdIntangible(int argc, const char **argv);
public:
bool _invincible;
bool _intangible;
+ bool _superStrength;
public:
Debugger(XeenEngine *vm);
diff --git a/engines/xeen/detection.cpp b/engines/xeen/detection.cpp
index 49b74b24a2..91eab285b3 100644
--- a/engines/xeen/detection.cpp
+++ b/engines/xeen/detection.cpp
@@ -73,6 +73,7 @@ static const PlainGameDescriptor XeenGames[] = {
};
#define GAMEOPTION_SHOW_ITEM_COSTS GUIO_GAMEOPTIONS1
+#define GAMEOPTION_DURABLE_ARMOR GUIO_GAMEOPTIONS2
#include "xeen/detection_tables.h"
@@ -88,6 +89,16 @@ static const ADExtraGuiOptionsMap optionsList[] = {
}
},
+ {
+ GAMEOPTION_DURABLE_ARMOR,
+ {
+ _s("More durable armor"),
+ _s("Armor won't break until character is at -80HP, rather than merely -10HP"),
+ "DurableArmor",
+ false
+ }
+ },
+
AD_EXTRA_GUI_OPTIONS_TERMINATOR
};
@@ -170,12 +181,9 @@ SaveStateList XeenMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- Xeen::SavesManager::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+ if (Xeen::SavesManager::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- if (header._thumbnail)
- header._thumbnail->free();
- delete header._thumbnail;
delete in;
}
}
@@ -200,7 +208,11 @@ SaveStateDescriptor XeenMetaEngine::querySaveMetaInfos(const char *target, int s
if (f) {
Xeen::XeenSavegameHeader header;
- Xeen::SavesManager::readSavegameHeader(f, header);
+ if (!Xeen::SavesManager::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/xeen/detection_tables.h b/engines/xeen/detection_tables.h
index 282fc62cc7..36c116fc2c 100644
--- a/engines/xeen/detection_tables.h
+++ b/engines/xeen/detection_tables.h
@@ -36,7 +36,7 @@ static const XeenGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GAMEOPTION_SHOW_ITEM_COSTS)
+ GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
},
GType_WorldOfXeen,
0
@@ -55,7 +55,7 @@ static const XeenGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GAMEOPTION_SHOW_ITEM_COSTS)
+ GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
},
GType_WorldOfXeen,
0
@@ -74,7 +74,7 @@ static const XeenGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GAMEOPTION_SHOW_ITEM_COSTS)
+ GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
},
GType_WorldOfXeen,
0
@@ -92,7 +92,7 @@ static const XeenGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GAMEOPTION_SHOW_ITEM_COSTS)
+ GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
},
GType_Clouds,
0
@@ -110,7 +110,7 @@ static const XeenGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GAMEOPTION_SHOW_ITEM_COSTS)
+ GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
},
GType_DarkSide,
0
@@ -128,7 +128,7 @@ static const XeenGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO1(GAMEOPTION_SHOW_ITEM_COSTS)
+ GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
},
GType_Swords,
0
diff --git a/engines/xeen/dialogs/dialogs.cpp b/engines/xeen/dialogs/dialogs.cpp
index 3e777ba232..1b99ec6978 100644
--- a/engines/xeen/dialogs/dialogs.cpp
+++ b/engines/xeen/dialogs/dialogs.cpp
@@ -66,48 +66,55 @@ bool ButtonContainer::checkEvents(XeenEngine *vm) {
EventsManager &events = *vm->_events;
Party &party = *vm->_party;
Windows &windows = *_vm->_windows;
+ PendingEvent event;
+ const Common::Rect WAIT_BOUNDS(8, 8, 224, 140);
_buttonValue = 0;
- if (events._leftButton) {
- Common::Point pt = events._mousePos;
-
- // Check for party member glyphs being clicked
- Common::Rect r(0, 0, 32, 32);
- for (uint idx = 0; idx < party._activeParty.size(); ++idx) {
- r.moveTo(Res.CHAR_FACES_X[idx], 150);
- if (r.contains(pt)) {
- _buttonValue = Common::KEYCODE_F1 + idx;
- break;
+ if (events.getEvent(event)) {
+ if (event._leftButton) {
+ Common::Point pt = events._mousePos;
+
+ // Check for party member glyphs being clicked
+ Common::Rect r(0, 0, 32, 32);
+ for (uint idx = 0; idx < party._activeParty.size(); ++idx) {
+ r.moveTo(Res.CHAR_FACES_X[idx], 150);
+ if (r.contains(pt)) {
+ _buttonValue = Common::KEYCODE_F1 + idx;
+ break;
+ }
}
- }
- // Check whether any button is selected
- for (uint i = 0; i < _buttons.size(); ++i) {
- if (_buttons[i]._bounds.contains(pt)) {
- events.debounceMouse();
+ // Check whether any button is selected
+ for (uint i = 0; i < _buttons.size(); ++i) {
+ if (_buttons[i]._bounds.contains(pt)) {
+ events.debounceMouse();
- _buttonValue = _buttons[i]._value;
- break;
+ _buttonValue = _buttons[i]._value;
+ break;
+ }
+ }
+
+ if (!_buttonValue && WAIT_BOUNDS.contains(pt)) {
+ _buttonValue = Common::KEYCODE_SPACE;
+ return true;
}
- }
- if (!_buttonValue && Common::Rect(8, 8, 224, 135).contains(pt)) {
- _buttonValue = 1;
- return true;
+ } else if (event.isKeyboard()) {
+ const Common::KeyCode &keycode = event._keyState.keycode;
+
+ if (keycode == Common::KEYCODE_KP8)
+ _buttonValue = Common::KEYCODE_UP;
+ else if (keycode == Common::KEYCODE_KP2)
+ _buttonValue = Common::KEYCODE_DOWN;
+ else if (keycode == Common::KEYCODE_KP_ENTER)
+ _buttonValue = Common::KEYCODE_RETURN;
+ else if (keycode != Common::KEYCODE_LCTRL && keycode != Common::KEYCODE_RCTRL
+ && keycode != Common::KEYCODE_LALT && keycode != Common::KEYCODE_RALT)
+ _buttonValue = keycode;
+
+ if (_buttonValue)
+ _buttonValue |= (event._keyState.flags & ~Common::KBD_STICKY) << 16;
}
- } else if (events.isKeyPending()) {
- Common::KeyState keyState;
- events.getKey(keyState);
-
- _buttonValue = keyState.keycode;
- if (_buttonValue == Common::KEYCODE_KP8)
- _buttonValue = Common::KEYCODE_UP;
- else if (_buttonValue == Common::KEYCODE_KP2)
- _buttonValue = Common::KEYCODE_DOWN;
- else if (_buttonValue == Common::KEYCODE_KP_ENTER)
- _buttonValue = Common::KEYCODE_RETURN;
-
- _buttonValue |= (keyState.flags & ~Common::KBD_STICKY) << 16;
}
if (_buttonValue) {
diff --git a/engines/xeen/dialogs/dialogs_char_info.cpp b/engines/xeen/dialogs/dialogs_char_info.cpp
index 08b9aed8b1..aec8be5ee4 100644
--- a/engines/xeen/dialogs/dialogs_char_info.cpp
+++ b/engines/xeen/dialogs/dialogs_char_info.cpp
@@ -396,14 +396,18 @@ bool CharacterInfo::expandStat(int attrib, const Character &c) {
bounds.setHeight(42);
break;
- case 10:
+ case 10: {
// Hit Points
- stat1 = c._currentHp;
- stat2 = c.getMaxHP();
- msg = Common::String::format(Res.CURRENT_MAXIMUM_TEXT, Res.STAT_NAMES[attrib],
- stat1, stat2);
+ Common::String fmt(Res.CURRENT_MAXIMUM_TEXT);
+ const char *p;
+ while ((p = strstr(fmt.c_str(), "%u")) != nullptr)
+ fmt.setChar('d', p - fmt.c_str() + 1);
+
+ msg = Common::String::format(fmt.c_str(), Res.STAT_NAMES[attrib],
+ c._currentHp, c.getMaxHP());
bounds.setHeight(42);
break;
+ }
case 11:
// Spell Points
diff --git a/engines/xeen/dialogs/dialogs_control_panel.cpp b/engines/xeen/dialogs/dialogs_control_panel.cpp
index 5c4ed16712..f589c8b0c3 100644
--- a/engines/xeen/dialogs/dialogs_control_panel.cpp
+++ b/engines/xeen/dialogs/dialogs_control_panel.cpp
@@ -172,8 +172,7 @@ int ControlPanel::execute() {
if (g_vm->canLoadGameStateCurrently())
saves.loadGame();
} else if (result == 4) {
- if (g_vm->canSaveGameStateCurrently())
- saves.saveGame();
+ saves.saveGame();
}
return result;
diff --git a/engines/xeen/dialogs/dialogs_input.cpp b/engines/xeen/dialogs/dialogs_input.cpp
index 0ac8f3612b..d273e57b10 100644
--- a/engines/xeen/dialogs/dialogs_input.cpp
+++ b/engines/xeen/dialogs/dialogs_input.cpp
@@ -84,9 +84,9 @@ Common::KeyState Input::waitForKey(const Common::String &msg) {
intf._tillMove = 0;
bool flag = !_vm->_startupWindowActive && !windows[25]._enabled
- && _vm->_mode != MODE_FF && _vm->_mode != MODE_17;
+ && _vm->_mode != MODE_FF && _vm->_mode != MODE_INTERACTIVE7;
- Common::KeyState ks;
+ PendingEvent pe;
while (!_vm->shouldExit()) {
events.updateGameCounter();
@@ -100,11 +100,8 @@ Common::KeyState Input::waitForKey(const Common::String &msg) {
windows[3].update();
events.wait(1);
-
- if (events.isKeyPending()) {
- events.getKey(ks);
+ if (events.getEvent(pe) && pe.isKeyboard())
break;
- }
}
_window->writeString("");
@@ -113,7 +110,7 @@ Common::KeyState Input::waitForKey(const Common::String &msg) {
intf._tillMove = oldTillMove;
intf._upDoorText = oldUpDoorText;
- return ks;
+ return pe._keyState;
}
void Input::animateCursor() {
@@ -144,7 +141,6 @@ int StringInput::show(XeenEngine *vm, bool type, const Common::String &msg1,
int StringInput::execute(bool type, const Common::String &expected,
const Common::String &title, int opcode) {
FileManager &files = *_vm->_files;
- Interface &intf = *_vm->_interface;
Scripts &scripts = *_vm->_scripts;
Windows &windows = *_vm->_windows;
Window &w = windows[6];
@@ -158,9 +154,9 @@ int StringInput::execute(bool type, const Common::String &expected,
Common::String line;
if (getString(line, 30, 200, false)) {
if (type) {
- if (line == intf._interfaceText) {
+ if (!line.compareToIgnoreCase(scripts._message)) {
result = true;
- } else if (line == expected) {
+ } else if (!line.compareToIgnoreCase(expected)) {
result = (opcode == 55) ? -1 : 1;
}
} else {
@@ -219,7 +215,7 @@ int NumericInput::execute(int maxLength, int maxWidth) {
/*------------------------------------------------------------------------*/
-int Choose123::show(XeenEngine *vm, int numOptions) {
+int Choose123::show(XeenEngine *vm, uint numOptions) {
assert(numOptions <= 3);
Choose123 *dlg = new Choose123(vm);
int result = dlg->execute(numOptions);
@@ -228,7 +224,7 @@ int Choose123::show(XeenEngine *vm, int numOptions) {
return result;
}
-int Choose123::execute(int numOptions) {
+int Choose123::execute(uint numOptions) {
EventsManager &events = *_vm->_events;
Interface &intf = *_vm->_interface;
LocationManager &loc = *_vm->_locations;
@@ -256,24 +252,17 @@ int Choose123::execute(int numOptions) {
}
events.wait(delay);
+ checkEvents(_vm);
+
if (_vm->shouldExit())
return 0;
} while (!_buttonValue);
- switch (_buttonValue) {
- case Common::KEYCODE_ESCAPE:
+ if (_buttonValue == Common::KEYCODE_ESCAPE) {
result = 0;
- break;
- case Common::KEYCODE_1:
- case Common::KEYCODE_2:
- case Common::KEYCODE_3: {
- int v = _buttonValue - Common::KEYCODE_1 + 1;
- if (v <= numOptions)
- result = v;
- break;
- }
- default:
- break;
+ } else if (_buttonValue >= Common::KEYCODE_1 && _buttonValue < (Common::KEYCODE_1 + (int)numOptions)) {
+ _buttonValue -= Common::KEYCODE_0;
+ result = (_buttonValue == (int)numOptions) ? 0 : _buttonValue;
}
}
@@ -283,15 +272,17 @@ int Choose123::execute(int numOptions) {
return result;
}
-void Choose123::loadButtons(int numOptions) {
+void Choose123::loadButtons(uint numOptions) {
+ assert(numOptions > 0 && numOptions <= 9);
_iconSprites.load("choose.icn");
+ const int XPOS[3] = { 235, 260, 286 };
+ const int YPOS[3] = { 75, 96, 117 };
- if (numOptions >= 1)
- addButton(Common::Rect(235, 75, 259, 95), Common::KEYCODE_1, &_iconSprites);
- if (numOptions >= 2)
- addButton(Common::Rect(260, 75, 284, 95), Common::KEYCODE_2, &_iconSprites);
- if (numOptions >= 3)
- addButton(Common::Rect(286, 75, 311, 95), Common::KEYCODE_3, &_iconSprites);
+ for (uint idx = 0; idx < numOptions; ++idx) {
+ Common::Rect r(24, 20);
+ r.moveTo(XPOS[idx % 3], YPOS[idx / 3]);
+ addButton(r, Common::KEYCODE_1 + idx, &_iconSprites);
+ }
}
/*------------------------------------------------------------------------*/
diff --git a/engines/xeen/dialogs/dialogs_input.h b/engines/xeen/dialogs/dialogs_input.h
index 270495ffd5..8cb41f3d36 100644
--- a/engines/xeen/dialogs/dialogs_input.h
+++ b/engines/xeen/dialogs/dialogs_input.h
@@ -82,11 +82,11 @@ private:
Choose123(XeenEngine *vm) : ButtonContainer(vm) {}
- int execute(int numOptions);
+ int execute(uint numOptions);
- void loadButtons(int numOptions);
+ void loadButtons(uint numOptions);
public:
- static int show(XeenEngine *vm, int numOptions);
+ static int show(XeenEngine *vm, uint numOptions);
};
class HowMuch : public ButtonContainer {
diff --git a/engines/xeen/dialogs/dialogs_items.cpp b/engines/xeen/dialogs/dialogs_items.cpp
index 0ea835e121..cdb38e37b4 100644
--- a/engines/xeen/dialogs/dialogs_items.cpp
+++ b/engines/xeen/dialogs/dialogs_items.cpp
@@ -375,9 +375,12 @@ Character *ItemsDialog::execute(Character *c, ItemsMode mode) {
Common::fill(&arr[0], &arr[40], 0);
arr[itemIndex] = 15;
}
-
- redrawFlag = REDRAW_TEXT;
+ } else {
+ Common::fill(&arr[0], &arr[40], 0);
+ itemIndex = -1;
}
+
+ redrawFlag = REDRAW_TEXT;
break;
case Common::KEYCODE_a:
diff --git a/engines/xeen/dialogs/dialogs_message.cpp b/engines/xeen/dialogs/dialogs_message.cpp
index df8afea34c..f571e6e811 100644
--- a/engines/xeen/dialogs/dialogs_message.cpp
+++ b/engines/xeen/dialogs/dialogs_message.cpp
@@ -51,7 +51,7 @@ void MessageDialog::execute(const Common::String &msg, MessageWaitType waitType)
break;
case WT_ANIMATED_WAIT:
- if (windows[11]._enabled || _vm->_mode == MODE_17) {
+ if (windows[11]._enabled || _vm->_mode == MODE_INTERACTIVE7) {
g_vm->_locations->wait();
break;
}
diff --git a/engines/xeen/dialogs/dialogs_party.cpp b/engines/xeen/dialogs/dialogs_party.cpp
index 306d1f9c2b..6bd54db712 100644
--- a/engines/xeen/dialogs/dialogs_party.cpp
+++ b/engines/xeen/dialogs/dialogs_party.cpp
@@ -58,7 +58,7 @@ void PartyDialog::execute() {
setupBackground();
while (!_vm->shouldExit()) {
- _vm->_mode = MODE_1;
+ _vm->_mode = MODE_INTERACTIVE;
// Build up a list of available characters in the Roster that are on the
// same side of Xeen as the player is currently on
diff --git a/engines/xeen/dialogs/dialogs_quests.cpp b/engines/xeen/dialogs/dialogs_quests.cpp
index 239793ee8c..1c91af2eba 100644
--- a/engines/xeen/dialogs/dialogs_quests.cpp
+++ b/engines/xeen/dialogs/dialogs_quests.cpp
@@ -44,8 +44,9 @@ void Quests::execute() {
int count = 0;
bool headerShown = false;
int topRow = 0;
- const char **questItems = (g_vm->getGameID() == GType_Swords) ? Res.QUEST_ITEM_NAMES_SWORDS : Res.QUEST_ITEM_NAMES;
+ const char **questItemNames = (g_vm->getGameID() == GType_Swords) ? Res.QUEST_ITEM_NAMES_SWORDS : Res.QUEST_ITEM_NAMES;
int itemsCount = (g_vm->getGameID() == GType_Swords) ? TOTAL_QUEST_ITEMS_SWORDS : TOTAL_QUEST_ITEMS;
+ const char *title1 = (g_vm->getGameID() == GType_Swords) ? Res.SWORDS_OF_XEEN_LINE : Res.CLOUDS_OF_XEEN_LINE;
addButtons();
loadQuestNotes();
@@ -75,30 +76,43 @@ void Quests::execute() {
headerShown = false;
for (int idx = 0; idx < itemsCount; ++idx) {
if (party._questItems[idx]) {
- if (!count && !headerShown && idx < 35) {
- lines[count++] = Res.CLOUDS_OF_XEEN_LINE;
+ if (!count && !headerShown) {
+ if (_vm->getGameID() == GType_Swords)
+ lines[count++] = Res.SWORDS_OF_XEEN_LINE;
+ else if (idx < 35)
+ lines[count++] = title1;
}
if (idx >= 35 && !headerShown) {
lines[count++] = Res.DARKSIDE_OF_XEEN_LINE;
headerShown = true;
}
- switch (idx) {
- case 17:
- case 26:
- case 79:
- case 80:
- case 81:
- case 82:
- case 83:
- case 84:
+ bool multiFlag = false;
+ if (_vm->getGameID() == GType_Swords) {
+ multiFlag = (idx == 20) || (idx == 27) || (idx == 41);
+ } else {
+ switch (idx) {
+ case 17:
+ case 26:
+ case 79:
+ case 80:
+ case 81:
+ case 82:
+ case 83:
+ case 84:
+ multiFlag = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (multiFlag) {
lines[count++] = Common::String::format("%d %s%c",
- party._questItems[idx], questItems[idx],
+ party._questItems[idx], questItemNames[idx],
party._questItems[idx] == 1 ? ' ' : 's');
- break;
- default:
- lines[count++] = questItems[idx];
- break;
+ } else {
+ lines[count++] = questItemNames[idx];
}
}
}
@@ -125,7 +139,7 @@ void Quests::execute() {
for (int idx = 0; idx < TOTAL_QUEST_FLAGS; ++idx) {
if (party._questFlags[(idx + 1) / 30][(idx + 1) % 30]) {
if (!count && !headerShown && idx < 29) {
- lines[count++] = Res.CLOUDS_OF_XEEN_LINE;
+ lines[count++] = title1;
}
if (idx > 28 && !headerShown) {
lines[count++] = Res.DARKSIDE_OF_XEEN_LINE;
@@ -152,7 +166,7 @@ void Quests::execute() {
for (int idx = 0; idx < MAX_DIALOG_LINES; ++idx) {
if (party._worldFlags[idx]) {
if (!count && !headerShown && idx < 72) {
- lines[count++] = Res.CLOUDS_OF_XEEN_LINE;
+ lines[count++] = title1;
}
if (idx >= 72 && !headerShown) {
lines[count++] = Res.DARKSIDE_OF_XEEN_LINE;
diff --git a/engines/xeen/dialogs/dialogs_spells.cpp b/engines/xeen/dialogs/dialogs_spells.cpp
index e1a0c22e3e..99ef0155c8 100644
--- a/engines/xeen/dialogs/dialogs_spells.cpp
+++ b/engines/xeen/dialogs/dialogs_spells.cpp
@@ -137,7 +137,7 @@ Character *SpellsDialog::execute(ButtonContainer *priorDialog, Character *c, int
spells._lastCaster = _buttonValue;
intf.highlightChar(_buttonValue);
- if (_vm->_mode == MODE_17) {
+ if (_vm->_mode == MODE_INTERACTIVE7) {
windows[10].writeString(Common::String::format(Res.GUILD_OPTIONS,
XeenEngine::printMil(party._gold).c_str(), Res.GUILD_TEXT, c->_name.c_str()));
} else {
@@ -305,9 +305,10 @@ const char *SpellsDialog::setSpellText(Character *c, int mode) {
spellId < Res.DARK_SPELL_RANGES[groupIndex][1]; ++spellId) {
int idx = 0;
while (idx <= SPELLS_PER_CLASS && Res.SPELLS_ALLOWED[category][idx] ==
- Res.DARK_SPELL_OFFSETS[category][spellId]);
+ Res.DARK_SPELL_OFFSETS[category][spellId])
+ ++idx;
- if (idx <= SPELLS_PER_CLASS) {
+ if (idx < SPELLS_PER_CLASS) {
if (!c->_spells[idx] || (mode & 0x80)) {
int cost = spells.calcSpellCost(Res.SPELLS_ALLOWED[category][idx], expenseFactor);
_spells.push_back(SpellEntry(Common::String::format("\x3l%s\x3r\x9""000%u",
@@ -319,11 +320,11 @@ const char *SpellsDialog::setSpellText(Character *c, int mode) {
} else {
for (int spellId = 0; spellId < 20; ++spellId) {
int idx = 0;
- while (Res.CLOUDS_GUILD_SPELLS[party._mazeId - 28][spellId] !=
- (int)Res.SPELLS_ALLOWED[category][idx] && idx <= SPELLS_PER_CLASS)
+ while (idx < SPELLS_PER_CLASS && Res.CLOUDS_GUILD_SPELLS[party._mazeId - 28][spellId] !=
+ (int)Res.SPELLS_ALLOWED[category][idx])
++idx;
- if (idx <= SPELLS_PER_CLASS) {
+ if (idx < SPELLS_PER_CLASS) {
if (!c->_spells[idx] || (mode & 0x80)) {
int cost = spells.calcSpellCost(Res.SPELLS_ALLOWED[category][idx], expenseFactor);
_spells.push_back(SpellEntry(Common::String::format("\x3l%s\x3r\x9""000%u",
@@ -621,7 +622,7 @@ int SelectElement::execute(int spellId) {
while (result == 999) {
do {
events.updateGameCounter();
- intf.draw3d(true);
+ intf.draw3d(true, false);
w.frame();
w.writeString(Res.WHICH_ELEMENT2);
drawButtons(&windows[0]);
@@ -765,12 +766,13 @@ bool LloydsBeacon::execute() {
switch (_buttonValue) {
case Common::KEYCODE_r:
- if (!ccNum && c._lloydMap >= 75 && c._lloydMap <= 78 && !party._cloudsEnd) {
+ if (!ccNum && c._lloydMap >= XEEN_CASTLE1 && c._lloydMap <= XEEN_CASTLE4 && party._cloudsCompleted) {
+ // Xeen's Castle has already been destroyed
result = false;
} else {
sound.playFX(51);
- map._loadCcNum = ccNum;
if (c._lloydMap != party._mazeId || c._lloydSide != ccNum) {
+ map._loadCcNum = c._lloydSide;
map.load(c._lloydMap);
}
@@ -850,10 +852,9 @@ int Teleport::execute() {
break;
}
- v = map.mazeLookup(pt, map._isOutdoors ? 0xF : 0xFFFF, 0);
+ v = map.mazeLookup(pt, 0, map._isOutdoors ? 0xF : 0xFFFF);
- if ((v != (map._isOutdoors ? 0 : INVALID_CELL)) &&
- (!map._isOutdoors || v == SURFTYPE_DWATER)) {
+ if ((v != (map._isOutdoors ? 0 : INVALID_CELL)) && (!map._isOutdoors || v != SURFTYPE_DWATER)) {
party._mazePosition = pt;
return 1;
} else {
@@ -879,20 +880,35 @@ int TownPortal::execute() {
Mode oldMode = _vm->_mode;
_vm->_mode = MODE_FF;
- // Build up a lsit of the names of the towns on the current side of Xeen
- for (int idx = 0; idx < 5; ++idx) {
- Common::String txtName = Common::String::format("%s%04d.txt", map._sideTownPortal ? "dark" : "xeen",
- Res.TOWN_MAP_NUMBERS[map._sideTownPortal][idx]);
- File f(txtName, 1);
- townNames[idx] = f.readString();
- f.close();
+ w.open();
+
+ if (_vm->getGameID() == GType_Swords) {
+ // Build up a lsit of the names of the towns on the current side of Xeen
+ for (int idx = 0; idx < 3; ++idx) {
+ Common::String txtName = Common::String::format("%s%04d.txt", "dark", Res.TOWN_MAP_NUMBERS[2][idx]);
+ File f(txtName, 1);
+ townNames[idx] = f.readString();
+ f.close();
+ }
+
+ w.writeString(Common::String::format(Res.TOWN_PORTAL_SWORDS, townNames[0].c_str(), townNames[1].c_str(),
+ townNames[2].c_str()));
+ } else {
+ // Build up a lsit of the names of the towns on the current side of Xeen
+ for (int idx = 0; idx < 5; ++idx) {
+ Common::String txtName = Common::String::format("%s%04d.txt", map._sideTownPortal ? "dark" : "xeen",
+ Res.TOWN_MAP_NUMBERS[map._sideTownPortal][idx]);
+ File f(txtName, 1);
+ townNames[idx] = f.readString();
+ f.close();
+ }
+
+ w.writeString(Common::String::format(Res.TOWN_PORTAL,
+ townNames[0].c_str(), townNames[1].c_str(), townNames[2].c_str(),
+ townNames[3].c_str(), townNames[4].c_str()
+ ));
}
- w.open();
- w.writeString(Common::String::format(Res.TOWN_PORTAL,
- townNames[0].c_str(), townNames[1].c_str(), townNames[2].c_str(),
- townNames[3].c_str(), townNames[4].c_str()
- ));
w.update();
// Get the town number
@@ -901,7 +917,7 @@ int TownPortal::execute() {
do {
int result = Input::show(_vm, &w, num, 1, 160, true);
townNumber = !result ? 0 : atoi(num.c_str());
- } while (townNumber > 5);
+ } while (townNumber > (_vm->getGameID() == GType_Swords ? 3 : 5));
w.close();
_vm->_mode = oldMode;
diff --git a/engines/xeen/events.cpp b/engines/xeen/events.cpp
index 6ceef4406b..414ba6a26e 100644
--- a/engines/xeen/events.cpp
+++ b/engines/xeen/events.cpp
@@ -33,7 +33,7 @@ namespace Xeen {
EventsManager::EventsManager(XeenEngine *vm) : _vm(vm), _playTime(0),
_frameCounter(0), _priorFrameCounterTime(0), _gameCounter(0),
- _leftButton(false), _rightButton(false), _sprites("mouse.icn") {
+ _mousePressed(false), _sprites("mouse.icn") {
Common::fill(&_gameCounters[0], &_gameCounters[6], 0);
}
@@ -80,24 +80,24 @@ void EventsManager::pollEvents() {
_vm->_debugger->attach();
_vm->_debugger->onFrame();
} else {
- _keys.push(event.kbd);
+ addEvent(event.kbd);
}
break;
case Common::EVENT_MOUSEMOVE:
_mousePos = event.mouse;
break;
case Common::EVENT_LBUTTONDOWN:
- _leftButton = true;
- return;
- case Common::EVENT_LBUTTONUP:
- _leftButton = false;
+ _mousePressed = true;
+ addEvent(true, false);
return;
case Common::EVENT_RBUTTONDOWN:
- _rightButton = true;
+ _mousePressed = true;
+ addEvent(false, true);
return;
+ case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONUP:
- _rightButton = false;
- break;
+ _mousePressed = false;
+ return;
default:
break;
}
@@ -110,31 +110,38 @@ void EventsManager::pollEventsAndWait() {
}
void EventsManager::clearEvents() {
- _keys.clear();
- _leftButton = _rightButton = false;
-
+ _pendingEvents.clear();
+ _mousePressed = false;
}
void EventsManager::debounceMouse() {
- while (_leftButton && !_vm->shouldExit()) {
+ while (_mousePressed && !_vm->shouldExit()) {
pollEventsAndWait();
}
}
-bool EventsManager::getKey(Common::KeyState &key) {
- if (_keys.empty()) {
+
+void EventsManager::addEvent(const Common::KeyState &keyState) {
+ if (_pendingEvents.size() < MAX_PENDING_EVENTS)
+ _pendingEvents.push(PendingEvent(keyState));
+}
+
+void EventsManager::addEvent(bool leftButton, bool rightButton) {
+ if (_pendingEvents.size() < MAX_PENDING_EVENTS)
+ _pendingEvents.push(PendingEvent(leftButton, rightButton));
+}
+
+
+bool EventsManager::getEvent(PendingEvent &pe) {
+ if (_pendingEvents.empty()) {
return false;
} else {
- key = _keys.pop();
+ pe = _pendingEvents.pop();
return true;
}
}
-bool EventsManager::isKeyPending() const {
- return !_keys.empty();
-}
-
bool EventsManager::isKeyMousePressed() {
- bool result = _leftButton || _rightButton || isKeyPending();
+ bool result = isEventPending();
debounceMouse();
clearEvents();
@@ -144,7 +151,7 @@ bool EventsManager::isKeyMousePressed() {
bool EventsManager::wait(uint numFrames, bool interruptable) {
while (!_vm->shouldExit() && timeElapsed() < numFrames) {
pollEventsAndWait();
- if (interruptable && (_leftButton || _rightButton || isKeyPending()))
+ if (interruptable && isEventPending())
return true;
}
@@ -200,9 +207,4 @@ void EventsManager::nextFrame() {
_vm->_screen->update();
}
-/*------------------------------------------------------------------------*/
-
-GameEvent::GameEvent() {
-}
-
} // End of namespace Xeen
diff --git a/engines/xeen/events.h b/engines/xeen/events.h
index 0ef2c3a9e7..6775b95ddf 100644
--- a/engines/xeen/events.h
+++ b/engines/xeen/events.h
@@ -32,9 +32,30 @@ namespace Xeen {
#define GAME_FRAME_RATE (1000 / 50)
#define GAME_FRAME_TIME 50
+#define MAX_PENDING_EVENTS 5
class XeenEngine;
+struct PendingEvent {
+ Common::KeyState _keyState;
+ bool _leftButton;
+ bool _rightButton;
+
+ PendingEvent() : _leftButton(false), _rightButton(false) {}
+ PendingEvent(const Common::KeyState &keyState) : _keyState(keyState), _leftButton(false), _rightButton(false) {}
+ PendingEvent(bool leftButton, bool rightButton) : _leftButton(leftButton), _rightButton(rightButton) {}
+
+ /**
+ * Returns true if a keyboard event is pending
+ */
+ bool isKeyboard() const { return _keyState.keycode != Common::KEYCODE_INVALID; }
+
+ /**
+ * Returns ture if a mouse button event is pending
+ */
+ bool isMouse() const { return _leftButton || _rightButton; }
+};
+
class EventsManager {
private:
XeenEngine *_vm;
@@ -43,19 +64,18 @@ private:
uint32 _gameCounter;
uint32 _gameCounters[6];
uint32 _playTime;
- Common::Queue<Common::KeyState> _keys;
+ Common::Queue<PendingEvent> _pendingEvents;
SpriteResource _sprites;
+ bool _mousePressed;
/**
* Handles moving to the next game frame
*/
void nextFrame();
public:
- bool _leftButton, _rightButton;
Common::Point _mousePos;
public:
EventsManager(XeenEngine *vm);
-
~EventsManager();
/*
@@ -78,17 +98,45 @@ public:
*/
bool isCursorVisible();
+ /**
+ * Polls the ScummVM backend for any pending events
+ */
void pollEvents();
+ /**
+ * Polls for events, and wait a slight delay. This ensures the game doesn't use up 100% of the CPU
+ */
void pollEventsAndWait();
+ /**
+ * Clears all pending events
+ */
void clearEvents();
+ /**
+ * Waits for a mouse press to be released
+ */
void debounceMouse();
- bool getKey(Common::KeyState &key);
+ /**
+ * Adds a keyboard event to the queue
+ */
+ void addEvent(const Common::KeyState &keyState);
- bool isKeyPending() const;
+ /**
+ * Adds a mouse button event to the queue
+ */
+ void addEvent(bool leftButton, bool rightButton);
+
+ /**
+ * Returns the next pending key/mouse press, if any
+ */
+ bool getEvent(PendingEvent &pe);
+
+ /**
+ * Returns true if a key or mouse event is pending
+ */
+ bool isEventPending() const { return !_pendingEvents.empty(); }
/**
* Returns true if a key or mouse press is pending
@@ -141,11 +189,6 @@ public:
void waitForPress();
};
-class GameEvent {
-public:
- GameEvent();
-};
-
} // End of namespace Xeen
#endif /* XEEN_EVENTS_H */
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp
index 5cf38f3221..0fce5b3741 100644
--- a/engines/xeen/files.cpp
+++ b/engines/xeen/files.cpp
@@ -504,6 +504,7 @@ void SaveArchive::load(Common::SeekableReadStream &stream) {
void SaveArchive::reset(CCArchive *src) {
Common::MemoryWriteStreamDynamic saveFile(DisposeAfterUse::YES);
File fIn;
+ _newData.clear();
g_vm->_files->setGameCc(g_vm->getGameID() == GType_DarkSide ? 1 : 0);
const int RESOURCES[6] = { 0x2A0C, 0x2A1C, 0x2A2C, 0x2A3C, 0x284C, 0x2A5C };
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index 8e52aae7ae..e986b9f2c1 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -262,7 +262,6 @@ void Interface::perform() {
Party &party = *_vm->_party;
Scripts &scripts = *_vm->_scripts;
Sound &sound = *_vm->_sound;
- const Common::Rect WAIT_BOUNDS(8, 8, 224, 140);
do {
// Draw the next frame
@@ -276,10 +275,7 @@ void Interface::perform() {
if (g_vm->shouldExit() || g_vm->isLoadPending() || party._dead)
return;
- if (events._leftButton && WAIT_BOUNDS.contains(events._mousePos))
- _buttonValue = Common::KEYCODE_SPACE;
- else
- checkEvents(g_vm);
+ checkEvents(g_vm);
} while (!_buttonValue && events.timeElapsed() < 1);
} while (!_buttonValue);
@@ -516,21 +512,18 @@ void Interface::perform() {
}
break;
- case Common::KEYCODE_c: {
+ case Common::KEYCODE_c:
// Cast spell
if (_tillMove) {
combat.moveMonsters();
draw3d(true);
}
- int result = CastSpell::show(_vm);
-
- if (result == 1) {
+ if (CastSpell::show(_vm) != -1) {
chargeStep();
doStepCode();
}
break;
- }
case Common::KEYCODE_i:
// Show Info dialog
@@ -566,7 +559,7 @@ void Interface::perform() {
if (combat._attackMonsters[0] != -1 || combat._attackMonsters[1] != -1
|| combat._attackMonsters[2] != -1) {
- if ((_vm->_mode == MODE_1 || _vm->_mode == MODE_SLEEPING)
+ if ((_vm->_mode == MODE_INTERACTIVE || _vm->_mode == MODE_SLEEPING)
&& !combat._monstersAttacking && !_charsShooting) {
doCombat();
}
@@ -772,8 +765,8 @@ void Interface::startFalling(bool flag) {
break;
}
} else {
- if (party._mazeId > 89 && party._mazeId < 113) {
- party._mazeId += 168;
+ if (party._mazeId > 88 && party._mazeId < 114) {
+ party._mazeId -= 88;
} else {
switch (party._mazeId - 25) {
case 0:
@@ -1006,7 +999,7 @@ void Interface::rest() {
map.cellFlagLookup(party._mazePosition);
if ((map._currentCantRest || (map.mazeData()._mazeFlags & RESTRICTION_REST))
- && _vm->_mode != MODE_12) {
+ && _vm->_mode != MODE_INTERACTIVE2) {
ErrorScroll::show(_vm, Res.TOO_DANGEROUS_TO_REST, WT_NONFREEZED_WAIT);
} else {
// Check whether any character is in danger of dying
@@ -1032,14 +1025,14 @@ void Interface::rest() {
Mode oldMode = _vm->_mode;
_vm->_mode = MODE_SLEEPING;
- if (oldMode == MODE_12) {
+ if (oldMode == MODE_INTERACTIVE2) {
party.changeTime(8 * 60);
} else {
for (int idx = 0; idx < 10; ++idx) {
chargeStep();
draw3d(true);
- if (_vm->_mode == MODE_1) {
+ if (_vm->_mode == MODE_INTERACTIVE) {
_vm->_mode = oldMode;
return;
}
@@ -1197,7 +1190,7 @@ void Interface::draw3d(bool updateFlag, bool pauseFlag) {
_flipUIFrame = (_flipUIFrame + 1) % 4;
if (_flipUIFrame == 0)
_flipWater = !_flipWater;
- if (_tillMove && (_vm->_mode == MODE_1 || _vm->_mode == MODE_COMBAT) &&
+ if (_tillMove && (_vm->_mode == MODE_INTERACTIVE || _vm->_mode == MODE_COMBAT) &&
!combat._monstersAttacking && combat._moveMonsters) {
if (--_tillMove == 0)
combat.moveMonsters();
@@ -1233,7 +1226,7 @@ void Interface::draw3d(bool updateFlag, bool pauseFlag) {
if (combat._attackMonsters[0] != -1 || combat._attackMonsters[1] != -1
|| combat._attackMonsters[2] != -1) {
- if ((_vm->_mode == MODE_1 || _vm->_mode == MODE_SLEEPING) &&
+ if ((_vm->_mode == MODE_INTERACTIVE || _vm->_mode == MODE_SLEEPING) &&
!combat._monstersAttacking && !_charsShooting && combat._moveMonsters) {
doCombat();
if (scripts._eventSkipped)
@@ -1446,7 +1439,6 @@ void Interface::doCombat() {
Map &map = *_vm->_map;
Party &party = *_vm->_party;
Scripts &scripts = *_vm->_scripts;
- Spells &spells = *_vm->_spells;
Sound &sound = *_vm->_sound;
Windows &windows = *_vm->_windows;
bool upDoorText = _upDoorText;
@@ -1523,7 +1515,7 @@ void Interface::doCombat() {
} while (!_vm->shouldExit() && events.timeElapsed() < 1 && !_buttonValue);
} while (!_vm->shouldExit() && !_buttonValue);
if (_vm->shouldExit())
- return;
+ goto exit;
switch (_buttonValue) {
case Common::KEYCODE_TAB:
@@ -1560,10 +1552,7 @@ void Interface::doCombat() {
case Common::KEYCODE_c: {
// Cast spell
- int spellId = CastSpell::show(_vm);
- if (spellId != -1) {
- Character *c = combat._combatParty[combat._whosTurn];
- spells.castSpell(c, (MagicSpell)spellId);
+ if (CastSpell::show(_vm) != -1) {
nextChar();
} else {
highlightChar(combat._whosTurn);
@@ -1600,7 +1589,7 @@ void Interface::doCombat() {
combat.run();
nextChar();
- if (_vm->_mode == MODE_1) {
+ if (_vm->_mode == MODE_INTERACTIVE) {
party._treasure._gems = 0;
party._treasure._gold = 0;
party._treasure._hasItems = false;
@@ -1691,7 +1680,7 @@ void Interface::doCombat() {
break;
}
- _vm->_mode = MODE_1;
+ _vm->_mode = MODE_INTERACTIVE;
if (combat._partyRan && (combat._attackMonsters[0] != -1 ||
combat._attackMonsters[1] != -1 || combat._attackMonsters[2] != -1)) {
party.checkPartyDead();
@@ -1705,14 +1694,14 @@ void Interface::doCombat() {
}
}
}
-
+exit:
w.close();
events.clearEvents();
_vm->_mode = MODE_COMBAT;
draw3d(true);
party.giveTreasure();
- _vm->_mode = MODE_1;
+ _vm->_mode = MODE_INTERACTIVE;
party._stepped = true;
unhighlightChar();
@@ -1725,21 +1714,23 @@ void Interface::doCombat() {
mainIconsPrint();
combat._monster2Attack = -1;
- if (upDoorText) {
- map.cellFlagLookup(party._mazePosition);
- if (map._currentIsEvent)
- scripts.checkEvents();
- }
+ if (!g_vm->isLoadPending()) {
+ if (upDoorText) {
+ map.cellFlagLookup(party._mazePosition);
+ if (map._currentIsEvent)
+ scripts.checkEvents();
+ }
- if (reloadMap) {
- sound.playFX(51);
- map._loadCcNum = _vm->getGameID() != GType_WorldOfXeen ? 1 : 0;
- map.load(_vm->getGameID() == GType_WorldOfXeen ? 28 : 29);
- party._mazeDirection = _vm->getGameID() == GType_WorldOfXeen ?
- DIR_EAST : DIR_SOUTH;
+ if (reloadMap) {
+ sound.playFX(51);
+ map._loadCcNum = _vm->getGameID() != GType_WorldOfXeen ? 1 : 0;
+ map.load(_vm->getGameID() == GType_WorldOfXeen ? 28 : 29);
+ party._mazeDirection = _vm->getGameID() == GType_WorldOfXeen ?
+ DIR_EAST : DIR_SOUTH;
+ }
}
- combat._combatMode = COMBATMODE_1;
+ combat._combatMode = COMBATMODE_INTERACTIVE;
}
void Interface::nextChar() {
@@ -1750,7 +1741,7 @@ void Interface::nextChar() {
return;
if ((combat._attackMonsters[0] == -1 && combat._attackMonsters[1] == -1 &&
combat._attackMonsters[2] == -1) || combat._combatParty.size() == 0) {
- _vm->_mode = MODE_1;
+ _vm->_mode = MODE_INTERACTIVE;
return;
}
@@ -1760,7 +1751,7 @@ void Interface::nextChar() {
// Check if party is dead
party.checkPartyDead();
if (party._dead) {
- _vm->_mode = MODE_1;
+ _vm->_mode = MODE_INTERACTIVE;
break;
}
diff --git a/engines/xeen/interface.h b/engines/xeen/interface.h
index 6de04495b2..5639171c40 100644
--- a/engines/xeen/interface.h
+++ b/engines/xeen/interface.h
@@ -164,7 +164,6 @@ private:
void nextChar();
public:
Obscurity _obscurity;
- Common::String _interfaceText;
FallState _falling;
int _face1State, _face2State;
int _face1UIFrame, _face2UIFrame;
diff --git a/engines/xeen/interface_minimap.cpp b/engines/xeen/interface_minimap.cpp
index 5ab10696bc..583156cf5a 100644
--- a/engines/xeen/interface_minimap.cpp
+++ b/engines/xeen/interface_minimap.cpp
@@ -141,7 +141,7 @@ void InterfaceMinimap::drawIndoorsMinimap() {
}
// Draw the specific surface type for each cell
- for (int yp = MINIMAP_YSTART + (TILE_HEIGHT / 2), mazeY = pt.y + MINIMAP_DIFF;
+ for (int yp = MINIMAP_YSTART + (TILE_HEIGHT / 2) + 1, mazeY = pt.y + MINIMAP_DIFF;
mazeY >= (pt.y - MINIMAP_DIFF); yp += TILE_HEIGHT, --mazeY) {
for (int xp = MINIMAP_XSTART + (TILE_WIDTH / 2), mazeX = pt.x - MINIMAP_DIFF;
mazeX <= (pt.x + MINIMAP_DIFF); xp += TILE_WIDTH, ++mazeX) {
@@ -166,8 +166,8 @@ void InterfaceMinimap::drawIndoorsMinimap() {
}
// Handle drawing surface sprites partially clipped at the left edge
- for (int yp = MINIMAP_YSTART, mazeY = pt.y + MINIMAP_DIFF; mazeY >= (pt.y - MINIMAP_DIFF);
- yp += TILE_HEIGHT, --mazeY) {
+ for (int yp = MINIMAP_YSTART + (TILE_HEIGHT / 2) + 1, mazeY = pt.y + MINIMAP_DIFF;
+ mazeY >= (pt.y - MINIMAP_DIFF); yp += TILE_HEIGHT, --mazeY) {
v = map.mazeLookup(Common::Point(pt.x - MINIMAP_DIFF - 1, mazeY), 0, 0xffff);
if (v != INVALID_CELL && map._currentSurfaceId &&
diff --git a/engines/xeen/interface_scene.cpp b/engines/xeen/interface_scene.cpp
index 2fcb378537..2c63e2c231 100644
--- a/engines/xeen/interface_scene.cpp
+++ b/engines/xeen/interface_scene.cpp
@@ -63,11 +63,11 @@ OutdoorDrawList::OutdoorDrawList() : _sky1(_data[0]), _sky2(_data[1]),
_data[25] = DrawStruct(0, 8, 109);
_data[26] = DrawStruct(0, 201, 109);
_data[27] = DrawStruct(0, 8, 109);
- _data[28] = DrawStruct(1, -64, 61, 14, SPRFLAG_SCENE_CLIPPED);
+ _data[28] = DrawStruct(1, -64, 61, 14);
_data[29] = DrawStruct(1, -40, 61, 14, 0);
_data[30] = DrawStruct(1, -16, 61, 14, 0);
_data[31] = DrawStruct(1, 8, 61, 14, 0);
- _data[32] = DrawStruct(1, 128, 61, 14, SPRFLAG_HORIZ_FLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[32] = DrawStruct(1, 128, 61, 14, SPRFLAG_HORIZ_FLIPPED);
_data[33] = DrawStruct(1, 104, 61, 14, SPRFLAG_HORIZ_FLIPPED);
_data[34] = DrawStruct(1, 80, 61, 14, SPRFLAG_HORIZ_FLIPPED);
_data[35] = DrawStruct(1, 56, 61, 14, SPRFLAG_HORIZ_FLIPPED);
@@ -123,10 +123,10 @@ OutdoorDrawList::OutdoorDrawList() : _sky1(_data[0]), _sky2(_data[1]),
_data[85] = DrawStruct(2, 146, 40, 0, SPRFLAG_HORIZ_FLIPPED);
_data[86] = DrawStruct(1, 32, 40, 6, 0);
_data[87] = DrawStruct(0, -7, 30, 7, 0);
- _data[88] = DrawStruct(0, -112, 30, 7, SPRFLAG_SCENE_CLIPPED);
- _data[89] = DrawStruct(0, 98, 30, 7, SPRFLAG_SCENE_CLIPPED);
- _data[90] = DrawStruct(0, -112, 30, 8, SPRFLAG_SCENE_CLIPPED);
- _data[91] = DrawStruct(0, 98, 30, 8, SPRFLAG_SCENE_CLIPPED);
+ _data[88] = DrawStruct(0, -112, 30, 7);
+ _data[89] = DrawStruct(0, 98, 30, 7);
+ _data[90] = DrawStruct(0, -112, 30, 8);
+ _data[91] = DrawStruct(0, 98, 30, 8);
_data[92] = DrawStruct(0, -38, 30, 8, 0);
_data[93] = DrawStruct(0, 25, 30, 8, 0);
_data[94] = DrawStruct(0, -7, 30, 8, 0);
@@ -141,22 +141,22 @@ OutdoorDrawList::OutdoorDrawList() : _sky1(_data[0]), _sky2(_data[1]),
_data[103] = DrawStruct(0, 8, 24);
_data[104] = DrawStruct(0, 169, 24, 0, SPRFLAG_HORIZ_FLIPPED);
_data[105] = DrawStruct(1, 32, 24);
- _data[106] = DrawStruct(0, -23, 40, 0, SPRFLAG_SCENE_CLIPPED);
- _data[107] = DrawStruct(0, 200, 40, 0, SPRFLAG_HORIZ_FLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[106] = DrawStruct(0, -23, 40, 0);
+ _data[107] = DrawStruct(0, 200, 40, 0, SPRFLAG_HORIZ_FLIPPED);
_data[108] = DrawStruct(0, 8, 47);
_data[109] = DrawStruct(0, 169, 47, 0, SPRFLAG_HORIZ_FLIPPED);
- _data[110] = DrawStruct(1, -56, -4, SCALE_ENLARGE, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
- _data[111] = DrawStruct(0, -5, 2, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
- _data[112] = DrawStruct(0, -67, 2, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[110] = DrawStruct(1, -56, -4, SCALE_ENLARGE, SPRFLAG_BOTTOM_CLIPPED);
+ _data[111] = DrawStruct(0, -5, 2, 0, SPRFLAG_BOTTOM_CLIPPED);
+ _data[112] = DrawStruct(0, -67, 2, 0, SPRFLAG_BOTTOM_CLIPPED);
_data[113] = DrawStruct(0, 44, 73);
_data[114] = DrawStruct(0, 44, 73);
- _data[115] = DrawStruct(0, 58, 14, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[115] = DrawStruct(0, 58, 14, 0, SPRFLAG_BOTTOM_CLIPPED);
_data[116] = DrawStruct(0, 169, 73);
_data[117] = DrawStruct(0, 169, 73);
- _data[118] = DrawStruct(0, -5, 14, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[118] = DrawStruct(0, -5, 14, 0, SPRFLAG_BOTTOM_CLIPPED);
_data[119] = DrawStruct(0, 110, 73);
_data[120] = DrawStruct(0, 110, 73);
- _data[121] = DrawStruct(0, -5, 14, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[121] = DrawStruct(0, -5, 14, 0, SPRFLAG_BOTTOM_CLIPPED);
_data[122] = DrawStruct(0, 110, 73);
_data[123] = DrawStruct(0, 110, 73);
_data[124] = DrawStruct(0, 72, 43);
@@ -167,6 +167,18 @@ OutdoorDrawList::OutdoorDrawList() : _sky1(_data[0]), _sky2(_data[1]),
_data[129] = DrawStruct(0, 47, 36, 0, SPRFLAG_HORIZ_FLIPPED);
_data[130] = DrawStruct(0, 118, 42);
_data[131] = DrawStruct(0, 26, 42, 0, SPRFLAG_HORIZ_FLIPPED);
+
+ for (int idx = 0; idx < 132; ++idx)
+ _data[idx]._flags |= SPRFLAG_SCENE_CLIPPED;
+}
+
+void OutdoorDrawList::draw() {
+ // Mark all items to be drawn as being clipped to the scene area
+ for (int idx = 0; idx < size(); ++idx)
+ _data[idx]._flags |= SPRFLAG_SCENE_CLIPPED;
+
+ // Draw the list
+ (*g_vm->_windows)[3].drawList(_data, size());
}
/*------------------------------------------------------------------------*/
@@ -283,16 +295,16 @@ IndoorDrawList::IndoorDrawList() :
_data[84] = DrawStruct(0, 71, 53, 12, SPRFLAG_HORIZ_FLIPPED);
_data[85] = DrawStruct(0, 80, 57, 12, 0);
_data[86] = DrawStruct(0, 64, 57, 12, SPRFLAG_HORIZ_FLIPPED);
- _data[87] = DrawStruct(7, -24, 52, 0, SPRFLAG_SCENE_CLIPPED);
+ _data[87] = DrawStruct(7, -24, 52, 0);
_data[88] = DrawStruct(7, 32, 52);
_data[89] = DrawStruct(7, 88, 52);
_data[90] = DrawStruct(0, 144, 52);
- _data[91] = DrawStruct(0, 200, 52, 0, SPRFLAG_SCENE_CLIPPED);
- _data[92] = DrawStruct(0, -79, 52, 11, SPRFLAG_SCENE_CLIPPED);
+ _data[91] = DrawStruct(0, 200, 52, 0);
+ _data[92] = DrawStruct(0, -79, 52, 11);
_data[93] = DrawStruct(0, -27, 52, 11, 0);
_data[94] = DrawStruct(0, 32, 52, 11, 0);
_data[95] = DrawStruct(0, 89, 52, 11, 0);
- _data[96] = DrawStruct(0, 145, 52, 11, SPRFLAG_SCENE_CLIPPED);
+ _data[96] = DrawStruct(0, 145, 52, 11);
_data[97] = DrawStruct(0, -8, 50, 12, 0);
_data[98] = DrawStruct(0, -65, 50, 12, 0);
_data[99] = DrawStruct(0, 49, 50, 12, 0);
@@ -315,17 +327,17 @@ IndoorDrawList::IndoorDrawList() :
_data[116] = DrawStruct(0, 63, 47, 8, SPRFLAG_HORIZ_FLIPPED);
_data[117] = DrawStruct(0, 94, 52, 8, 0);
_data[118] = DrawStruct(0, 50, 52, 8, SPRFLAG_HORIZ_FLIPPED);
- _data[119] = DrawStruct(6, -40, 40, 0, SPRFLAG_SCENE_CLIPPED);
+ _data[119] = DrawStruct(6, -40, 40, 0);
_data[120] = DrawStruct(6, 64, 40);
- _data[121] = DrawStruct(0, 168, 40, 0, SPRFLAG_SCENE_CLIPPED);
- _data[122] = DrawStruct(0, -72, 40, 6, SPRFLAG_SCENE_CLIPPED);
+ _data[121] = DrawStruct(0, 168, 40, 0);
+ _data[122] = DrawStruct(0, -72, 40, 6);
_data[123] = DrawStruct(0, 32, 40, 6, 0);
- _data[124] = DrawStruct(0, 137, 40, 6, SPRFLAG_SCENE_CLIPPED);
+ _data[124] = DrawStruct(0, 137, 40, 6);
_data[125] = DrawStruct(0, -7, 25, 7, 0);
- _data[126] = DrawStruct(0, -112, 25, 7, SPRFLAG_SCENE_CLIPPED);
- _data[127] = DrawStruct(0, 98, 25, 7, SPRFLAG_SCENE_CLIPPED);
- _data[128] = DrawStruct(0, -112, 29, 8, SPRFLAG_SCENE_CLIPPED);
- _data[129] = DrawStruct(0, 98, 29, 8, SPRFLAG_SCENE_CLIPPED);
+ _data[126] = DrawStruct(0, -112, 25, 7);
+ _data[127] = DrawStruct(0, 98, 25, 7);
+ _data[128] = DrawStruct(0, -112, 29, 8);
+ _data[129] = DrawStruct(0, 98, 29, 8);
_data[130] = DrawStruct(0, -38, 29, 8, 0);
_data[131] = DrawStruct(0, 25, 29, 8, 0);
_data[132] = DrawStruct(0, -7, 29, 8, 0);
@@ -339,23 +351,23 @@ IndoorDrawList::IndoorDrawList() :
_data[140] = DrawStruct(0, 55, 41, 4, SPRFLAG_HORIZ_FLIPPED);
_data[141] = DrawStruct(0, 106, 47, 4, 0);
_data[142] = DrawStruct(0, 38, 47, 4, SPRFLAG_HORIZ_FLIPPED);
- _data[143] = DrawStruct(0, -136, 24, 0, SPRFLAG_SCENE_CLIPPED);
+ _data[143] = DrawStruct(0, -136, 24, 0);
_data[144] = DrawStruct(0, 8, 12);
_data[145] = DrawStruct(0, 32, 24);
_data[146] = DrawStruct(0, 200, 12, 0, SPRFLAG_HORIZ_FLIPPED);
- _data[147] = DrawStruct(0, 200, 24, 0, SPRFLAG_SCENE_CLIPPED);
+ _data[147] = DrawStruct(0, 200, 24, 0);
_data[148] = DrawStruct(0, 32, 24);
- _data[149] = DrawStruct(0, -5, 2, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
- _data[150] = DrawStruct(0, -67, 10, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[149] = DrawStruct(0, -5, 2, 0, SPRFLAG_BOTTOM_CLIPPED);
+ _data[150] = DrawStruct(0, -67, 10, 0, SPRFLAG_BOTTOM_CLIPPED);
_data[151] = DrawStruct(0, 44, 73);
_data[152] = DrawStruct(0, 44, 73);
- _data[153] = DrawStruct(0, 58, 14, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[153] = DrawStruct(0, 58, 14, 0, SPRFLAG_BOTTOM_CLIPPED);
_data[154] = DrawStruct(0, 169, 73);
_data[155] = DrawStruct(0, 169, 73);
- _data[156] = DrawStruct(0, -5, 14, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[156] = DrawStruct(0, -5, 14, 0, SPRFLAG_BOTTOM_CLIPPED);
_data[157] = DrawStruct(0, 110, 73);
_data[158] = DrawStruct(0, 110, 73);
- _data[159] = DrawStruct(0, -5, 14, 0, SPRFLAG_BOTTOM_CLIPPED | SPRFLAG_SCENE_CLIPPED);
+ _data[159] = DrawStruct(0, -5, 14, 0, SPRFLAG_BOTTOM_CLIPPED);
_data[160] = DrawStruct(0, 110, 73);
_data[161] = DrawStruct(0, 110, 73);
_data[162] = DrawStruct(0, 72, 43);
@@ -368,6 +380,15 @@ IndoorDrawList::IndoorDrawList() :
_data[169] = DrawStruct(0, 26, 42, 0, SPRFLAG_HORIZ_FLIPPED);
}
+void IndoorDrawList::draw() {
+ // Mark all items to be drawn as being clipped to the scene area
+ for (int idx = 0; idx < size(); ++idx)
+ _data[idx]._flags |= SPRFLAG_SCENE_CLIPPED;
+
+ // Draw the list
+ (*g_vm->_windows)[3].drawList(_data, size());
+}
+
/*------------------------------------------------------------------------*/
InterfaceScene::InterfaceScene(XeenEngine *vm): _vm(vm) {
@@ -3544,7 +3565,6 @@ void InterfaceScene::setOutdoorsObjects() {
void InterfaceScene::drawIndoors() {
Map &map = *_vm->_map;
- Windows &windows = *_vm->_windows;
int surfaceId;
// Draw any surface tiles on top of the default ground
@@ -4379,7 +4399,7 @@ void InterfaceScene::drawIndoors() {
_indoorList._horizon._frame = 7;
// Finally draw the darn indoor scene
- windows[3].drawList(&_indoorList[0], _indoorList.size());
+ _indoorList.draw();
// Check for any character shooting
_isAttacking = false;
@@ -4394,7 +4414,6 @@ void InterfaceScene::drawIndoors() {
void InterfaceScene::drawOutdoors() {
Map &map = *_vm->_map;
Party &party = *_vm->_party;
- Windows &windows = *_vm->_windows;
int surfaceId;
// Draw any surface tiles on top of the default ground
@@ -4460,7 +4479,7 @@ void InterfaceScene::drawOutdoors() {
_outdoorList._groundSprite._flags = _flipWater ? SPRFLAG_HORIZ_FLIPPED : 0;
// Finally render the outdoor scene
- windows[3].drawList(&_outdoorList[0], _outdoorList.size());
+ _outdoorList.draw();
// Check for any character shooting
_isAttacking = false;
diff --git a/engines/xeen/interface_scene.h b/engines/xeen/interface_scene.h
index 0c181522bb..18f1f58a36 100644
--- a/engines/xeen/interface_scene.h
+++ b/engines/xeen/interface_scene.h
@@ -42,14 +42,28 @@ public:
DrawStruct * const _attackImgs3;
DrawStruct * const _attackImgs4;
public:
+ /**
+ * Constructor
+ */
OutdoorDrawList();
+ /**
+ * Get a draw list entry
+ */
DrawStruct &operator[](int idx) {
assert(idx < size());
return _data[idx];
}
+ /**
+ * Return the size of the list
+ */
int size() const { return 132; }
+
+ /**
+ * Draw the list to the scene
+ */
+ void draw();
};
class IndoorDrawList {
@@ -80,12 +94,23 @@ public:
public:
IndoorDrawList();
+ /**
+ * Get a draw list entry
+ */
DrawStruct &operator[](int idx) {
assert(idx < size());
return _data[idx];
}
+ /**
+ * Return the size of the list
+ */
int size() const { return 170; }
+
+ /**
+ * Draw the list to the scene
+ */
+ void draw();
};
class InterfaceScene {
diff --git a/engines/xeen/item.cpp b/engines/xeen/item.cpp
index 6a37fa1d92..a364dad928 100644
--- a/engines/xeen/item.cpp
+++ b/engines/xeen/item.cpp
@@ -86,7 +86,10 @@ AttributeCategory XeenItem::getAttributeCategory() const {
}
const char *XeenItem::getItemName(ItemCategory category, uint id) {
- if (id < 82) {
+ const char **questItems = (g_vm->getGameID() == GType_Swords) ? Res.QUEST_ITEM_NAMES_SWORDS : Res.QUEST_ITEM_NAMES;
+ const uint QUEST_OFFSET = g_vm->getGameID() == GType_Swords ? 88 : 82;
+
+ if (id < QUEST_OFFSET) {
switch (category) {
case CATEGORY_WEAPON:
assert(id < 41);
@@ -102,18 +105,16 @@ const char *XeenItem::getItemName(ItemCategory category, uint id) {
return Res.MISC_NAMES[id];
}
} else {
- const char **questItems = (g_vm->getGameID() == GType_Swords) ? Res.QUEST_ITEM_NAMES_SWORDS : Res.QUEST_ITEM_NAMES;
-
switch (category) {
case CATEGORY_WEAPON:
- return questItems[id - 82];
+ return questItems[id - QUEST_OFFSET];
case CATEGORY_ARMOR:
- return questItems[id - 82 + 35];
+ return questItems[id - QUEST_OFFSET + 35];
case CATEGORY_ACCESSORY:
- return questItems[id - 82 + 35 + 14];
+ return questItems[id - QUEST_OFFSET + 35 + 14];
default:
assert(g_vm->getGameID() != GType_Swords);
- return questItems[id - 82 + 35 + 14 + 11];
+ return questItems[id - QUEST_OFFSET + 35 + 14 + 11];
}
}
}
@@ -595,6 +596,8 @@ void AccessoryItems::equipItem(int itemIndex) {
return;
}
}
+
+ item._frame = 12;
} else if (item._id <= 7) {
int count = 0;
for (uint idx = 0; idx < size(); ++idx) {
diff --git a/engines/xeen/locations.cpp b/engines/xeen/locations.cpp
index ca7682b923..e2359df69c 100644
--- a/engines/xeen/locations.cpp
+++ b/engines/xeen/locations.cpp
@@ -497,7 +497,7 @@ GuildLocation::GuildLocation() : BaseLocation(GUILD) {
addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_b);
addButton(Common::Rect(234, 74, 308, 82), Common::KEYCODE_s);
addButton(Common::Rect(234, 84, 308, 92), 0);
- g_vm->_mode = MODE_17;
+ g_vm->_mode = MODE_INTERACTIVE7;
_vocName = _ccNum ? "parrot1.voc" : "guild10.voc";
}
@@ -560,7 +560,7 @@ TavernLocation::TavernLocation() : BaseLocation(TAVERN) {
addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_f);
addButton(Common::Rect(234, 74, 308, 82), Common::KEYCODE_t);
addButton(Common::Rect(234, 84, 308, 92), Common::KEYCODE_r);
- g_vm->_mode = MODE_17;
+ g_vm->_mode = MODE_INTERACTIVE7;
_vocName = _ccNum ? "hello1.voc" : "hello.voc";
}
@@ -713,7 +713,7 @@ Character *TavernLocation::doOptions(Character *c) {
party._activeParty[idx]._xeenSide = map._loadCcNum;
}
- g_vm->_mode = MODE_17;
+ g_vm->_mode = MODE_INTERACTIVE7;
party.addTime(1440);
party._mazeId = 0;
@@ -1143,9 +1143,9 @@ int ArenaLocation::show() {
}
Common::String format = map._events._text[3];
- Common::String count = Common::String::format("%05u", party._activeParty[0]._awards[WARZONE_AWARD]);
- int numIdx = count[3] == '1' ? 0 : count[4] - '0';
- Common::String msg = Common::String::format(format.c_str(), count.c_str(), SUFFIXES[numIdx]);
+ int count = party._activeParty[0]._awards[WARZONE_AWARD];
+ int suffixNum = (count < 10) ? count : 0;
+ Common::String msg = Common::String::format(format.c_str(), count, SUFFIXES[suffixNum]);
LocationMessage::show(27, Res.WARZONE_BATTLE_MASTER, msg, 1);
@@ -1161,8 +1161,7 @@ int ArenaLocation::show() {
}
}
- check = LocationMessage::show(27, Res.WARZONE_BATTLE_MASTER,
- map._events._text[0].c_str(), 300);
+ check = LocationMessage::show(27, Res.WARZONE_BATTLE_MASTER, map._events._text[0].c_str(), 0);
if (!check) {
LocationMessage::show(27, Res.WARZONE_BATTLE_MASTER,
map._events._text[1].c_str(), 300);
@@ -1187,7 +1186,7 @@ int ArenaLocation::show() {
if (howMany == 0)
goto exit;
- LocationMessage::show(27, Res.WARZONE_BATTLE_MASTER, map._events._text[2], 300);
+ LocationMessage::show(27, Res.WARZONE_BATTLE_MASTER, map._events._text[2], 1);
// Clear monsters array
party._mazeDirection = DIR_EAST;
@@ -1232,7 +1231,7 @@ exit:
/*------------------------------------------------------------------------*/
-CutsceneLocation::CutsceneLocation(LocationAction action) : BaseLocation(action), _mazeFlag(false) {
+CutsceneLocation::CutsceneLocation(LocationAction action) : BaseLocation(action), _keyFound(false) {
Party &party = *g_vm->_party;
_mazeId = party._mazeId;
_mazePos = party._mazePosition;
@@ -1321,8 +1320,13 @@ int ReaperCutscene::show() {
sprites1.draw(0, party._isNight ? 3 : 2);
}
- _subtitles.setLine(_mazeFlag ? 5 : 6);
- sound.playVoice(_mazeFlag ? "reaper12.voc" : "reaper14.voc");
+ if (!_ccNum) {
+ _subtitles.setLine(_keyFound ? 5 : 6);
+ sound.playVoice(_keyFound ? "reaper12.voc" : "reaper14.voc");
+ } else if (_keyFound) {
+ _subtitles.setLine(2);
+ sound.playVoice("howdid1.voc");
+ }
do {
events.updateGameCounter();
@@ -1346,11 +1350,13 @@ int ReaperCutscene::show() {
windows[0].update();
WAIT(7);
- sound.playVoice(_mazeFlag ? "reaper12.voc" : "reaper14.voc");
- if (_mazeFlag)
+ if (_keyFound) {
sound.playVoice(_ccNum ? "goin1.voc" : "reaper13.voc");
- else
+ } else {
+ if (_ccNum)
+ _subtitles.setLine(3);
sound.playVoice(_ccNum ? "needkey1.voc" : "reaper15.voc");
+ }
do {
events.updateGameCounter();
@@ -1372,7 +1378,7 @@ int ReaperCutscene::show() {
windows[0].update();
WAIT(1);
- if (_mazeFlag) {
+ if (_keyFound) {
for (int idx = 0; idx < 14; ++idx) {
events.updateGameCounter();
screen.blitFrom(savedBg);
@@ -1419,7 +1425,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 57;
_mazePos = Common::Point(11, 8);
_mazeDir = DIR_WEST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1428,7 +1434,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 55;
_mazePos = Common::Point(3, 8);
_mazeDir = DIR_EAST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1437,7 +1443,16 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 69;
_mazePos = Common::Point(7, 4);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
+ }
+ break;
+
+ case 16:
+ if (party._questItems[41]) {
+ _mazeId = 61;
+ _mazePos = Common::Point(7, 12);
+ _mazeDir = DIR_SOUTH;
+ _keyFound = true;
}
break;
@@ -1446,7 +1461,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 65;
_mazePos = Common::Point(3, 8);
_mazeDir = DIR_EAST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1455,7 +1470,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 53;
_mazePos = Common::Point(11, 8);
_mazeDir = DIR_WEST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1470,7 +1485,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 113;
_mazePos = Common::Point(7, 4);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1479,7 +1494,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 55;
_mazePos = Common::Point(3, 8);
_mazeDir = DIR_EAST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1489,7 +1504,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 117;
_mazePos = Common::Point(7, 4);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1498,7 +1513,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 59;
_mazePos = Common::Point(11, 8);
_mazeDir = DIR_WEST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1507,7 +1522,7 @@ void ReaperCutscene::getNewLocation() {
_mazeId = 51;
_mazePos = Common::Point(7, 12);
_mazeDir = DIR_SOUTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1550,6 +1565,7 @@ int GolemCutscene::show() {
// Save the screen
Graphics::ManagedSurface savedBg;
savedBg.copyFrom(screen);
+ getNewLocation();
for (int idx = (_ccNum ? 8 : 11); idx >= 0; --idx) {
events.updateGameCounter();
@@ -1563,7 +1579,7 @@ int GolemCutscene::show() {
WAIT(1);
}
- if (_ccNum)
+ if (!_ccNum)
sound.playSound("ogre.voc");
for (int idx = -200; idx < 0; idx += 16) {
@@ -1592,12 +1608,18 @@ int GolemCutscene::show() {
windows[0].update();
while (sound.isSoundPlaying()) {
+ _subtitles.show();
WAIT(1);
}
sound.setMusicPercent(38);
- _subtitles.setLine(_mazeFlag ? 8 : 7);
- sound.playVoice(_mazeFlag ? "golem15.voc" : "golem13.voc");
+ if (_ccNum) {
+ _subtitles.setLine(_keyFound ? 5 : 4);
+ sound.playVoice("what2.voc");
+ } else {
+ _subtitles.setLine(_keyFound ? 8 : 7);
+ sound.playVoice(_keyFound ? "golem15.voc" : "golem13.voc");
+ }
do {
events.updateGameCounter();
@@ -1607,7 +1629,7 @@ int GolemCutscene::show() {
if (_ccNum) {
int frame = g_vm->getRandomNumber(6);
sprites2[0].draw(0, frame, Common::Point(0, 0));
- sprites2[1].draw(1, frame, Common::Point(160, 0));
+ sprites2[1].draw(0, frame, Common::Point(160, 0));
} else {
sprites2[0].draw(0, 0, Common::Point(0, 0));
sprites2[0].draw(0, 1, Common::Point(160, 0));
@@ -1615,6 +1637,7 @@ int GolemCutscene::show() {
g_vm->getRandomNumber(9) - 3));
}
+ _subtitles.show();
WAIT(1);
} while (sound.isSoundPlaying());
@@ -1627,16 +1650,17 @@ int GolemCutscene::show() {
windows[0].update();
events.updateGameCounter();
- events.wait(_ccNum ? 10 : 1);
+ if (_subtitles.wait(_ccNum ? 10 : 1))
+ goto exit;
- if (!_ccNum) {
+ if (_ccNum) {
+ sound.playVoice(_keyFound ? "go2.voc" : "key2.voc");
+ } else {
sound.playVoice("ogre.voc");
while (sound.isSoundPlaying())
events.pollEventsAndWait();
- sound.playVoice(_mazeFlag ? "golem16.voc" : "golem14.voc");
- } else {
- sound.playVoice(_mazeFlag ? "go2.voc" : "key2.voc");
+ sound.playVoice(_keyFound ? "golem16.voc" : "golem14.voc");
}
do {
@@ -1647,7 +1671,7 @@ int GolemCutscene::show() {
if (_ccNum) {
int frame = g_vm->getRandomNumber(6);
sprites2[0].draw(0, frame, Common::Point(0, 0));
- sprites2[1].draw(1, frame, Common::Point(160, 0));
+ sprites2[1].draw(0, frame, Common::Point(160, 0));
} else {
sprites2[0].draw(0, 0, Common::Point(0, 0));
sprites2[0].draw(0, 1, Common::Point(160, 0));
@@ -1656,8 +1680,9 @@ int GolemCutscene::show() {
}
windows[0].update();
+ _subtitles.show();
WAIT(1);
- } while (sound.isSoundPlaying());
+ } while (_subtitles.lineActive());
sprites1.draw(0, 0, Common::Point(0, 0));
sprites1.draw(0, 1, Common::Point(160, 0));
@@ -1665,15 +1690,11 @@ int GolemCutscene::show() {
sprites2[_ccNum].draw(0, 1 - _ccNum, Common::Point(160, 0));
if (!_ccNum)
sprites2[0].draw(0, 2);
-
windows[0].update();
- while (_subtitles.lineActive()) {
- WAIT(1);
- }
sound.setMusicPercent(75);
- if (!_mazeFlag) {
+ if (!_keyFound) {
for (int idx = 0; !g_vm->shouldExit() && idx < (_ccNum ? 9 : 12); ++idx) {
events.updateGameCounter();
screen.blitFrom(savedBg);
@@ -1716,7 +1737,7 @@ void GolemCutscene::getNewLocation() {
_mazeId = 73;
_mazePos = Common::Point(0, 7);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1725,7 +1746,7 @@ void GolemCutscene::getNewLocation() {
_mazeId = 83;
_mazePos = Common::Point(11, 1);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1734,7 +1755,7 @@ void GolemCutscene::getNewLocation() {
_mazeId = 121;
_mazePos = Common::Point(18, 0);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1743,7 +1764,7 @@ void GolemCutscene::getNewLocation() {
_mazeId = 78;
_mazePos = Common::Point(8, 14);
_mazeDir = DIR_SOUTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1757,7 +1778,7 @@ void GolemCutscene::getNewLocation() {
_mazeId = 81;
_mazePos = Common::Point(1, 17);
_mazeDir = DIR_EAST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1766,7 +1787,7 @@ void GolemCutscene::getNewLocation() {
_mazeId = 80;
_mazePos = Common::Point(29, 16);
_mazeDir = DIR_WEST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1776,7 +1797,7 @@ void GolemCutscene::getNewLocation() {
_mazeId = 121;
_mazePos = Common::Point(18, 0);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1785,7 +1806,7 @@ void GolemCutscene::getNewLocation() {
_mazeId = 79;
_mazePos = Common::Point(5, 16);
_mazeDir = DIR_EAST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1873,7 +1894,10 @@ int DwarfCutscene::show() {
screen.blitFrom(savedBg);
sprites2.draw(0, 0);
windows[0].update();
- _subtitles.setLine(_ccNum ? 0 : 4);
+ if (_ccNum)
+ _subtitles.setLine(_keyFound ? 7 : 8);
+ else
+ _subtitles.setLine(4);
for (int idx = 0; idx < (_ccNum ? 2 : 3); ++idx) {
switch (idx) {
@@ -1892,7 +1916,7 @@ int DwarfCutscene::show() {
WAIT(1);
}
- sound.playSound(_mazeFlag ? "ok2.voc" : "back2.voc");
+ sound.playSound(_keyFound ? "ok2.voc" : "back2.voc");
} else {
sound.playSound("dwarf11.voc");
}
@@ -1948,7 +1972,7 @@ void DwarfCutscene::getNewLocation() {
_mazeId = 29;
_mazePos = Common::Point(15, 31);
_mazeDir = DIR_SOUTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1957,7 +1981,7 @@ void DwarfCutscene::getNewLocation() {
_mazeId = 35;
_mazePos = Common::Point(15, 8);
_mazeDir = DIR_WEST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1966,7 +1990,7 @@ void DwarfCutscene::getNewLocation() {
_mazeId = 31;
_mazePos = Common::Point(31, 16);
_mazeDir = DIR_WEST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1975,7 +1999,7 @@ void DwarfCutscene::getNewLocation() {
_mazeId = 33;
_mazePos = Common::Point(0, 3);
_mazeDir = DIR_EAST;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1984,7 +2008,7 @@ void DwarfCutscene::getNewLocation() {
_mazeId = 37;
_mazePos = Common::Point(7, 0);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -1997,7 +2021,7 @@ void DwarfCutscene::getNewLocation() {
_mazeId = 37;
_mazePos = Common::Point(1, 4);
_mazeDir = DIR_EAST;
- _mazeFlag = true;
+ _keyFound = true;
break;
case 18:
@@ -2010,7 +2034,7 @@ void DwarfCutscene::getNewLocation() {
_mazePos = Common::Point(7, 1);
_mazeDir = DIR_NORTH;
}
- _mazeFlag = true;
+ _keyFound = true;
break;
case 23:
@@ -2023,7 +2047,7 @@ void DwarfCutscene::getNewLocation() {
_mazePos = Common::Point(7, 30);
_mazeDir = DIR_SOUTH;
}
- _mazeFlag = true;
+ _keyFound = true;
break;
default:
@@ -2066,14 +2090,14 @@ int SphinxCutscene::show() {
sound.setMusicPercent(38);
- for (int idx = 0; idx < (_mazeFlag ? 3 : 2); ++idx) {
+ for (int idx = 0; idx < (_keyFound ? 3 : 2); ++idx) {
switch (idx) {
case 0:
- _subtitles.setLine(_mazeFlag ? 9 : 10);
- sound.playSound(_mazeFlag ? "sphinx10.voc" : "sphinx13.voc");
+ _subtitles.setLine(_keyFound ? 9 : 10);
+ sound.playSound(_keyFound ? "sphinx10.voc" : "sphinx13.voc");
break;
case 1:
- sound.playSound(_mazeFlag ? "sphinx11.voc" : "sphinx14.voc");
+ sound.playSound(_keyFound ? "sphinx11.voc" : "sphinx14.voc");
break;
case 2:
sound.playSound("sphinx12.voc");
@@ -2097,7 +2121,7 @@ int SphinxCutscene::show() {
sound.setMusicPercent(75);
- if (!_mazeFlag) {
+ if (!_keyFound) {
for (int idx = 0; idx < 8; ++idx) {
screen.blitFrom(bgSurface);
sprites1.draw(0, 0, Common::Point(SPHINX_X1[idx], SPHINX_Y1[idx]), 0, idx);
@@ -2136,7 +2160,7 @@ void SphinxCutscene::getNewLocation() {
_mazeId = 125;
_mazePos = Common::Point(7, 6);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -2145,7 +2169,7 @@ void SphinxCutscene::getNewLocation() {
_mazeId = 82;
_mazePos = Common::Point(7, 5);
_mazeDir = DIR_NORTH;
- _mazeFlag = true;
+ _keyFound = true;
}
break;
@@ -2216,9 +2240,12 @@ int PyramidLocation::show() {
LocationManager::LocationManager() : _location(nullptr) {
}
-int LocationManager::doAction(LocationAction actionId) {
+int LocationManager::doAction(int actionId) {
+ LocationAction action = (g_vm->getGameID() == GType_Swords && actionId > 13 && actionId < 18) ?
+ BLACKSMITH : (LocationAction)actionId;
+
// Create the desired location
- switch (actionId) {
+ switch (action) {
case BANK:
_location = new Locations::BankLocation();
break;
@@ -2353,21 +2380,18 @@ bool LocationMessage::execute(int portrait, const Common::String &name, const Co
do {
events.clearEvents();
- events.updateGameCounter();
- if (msgEnd)
- clearButtons();
+ clearEvents();
do {
- events.pollEventsAndWait();
- checkEvents(_vm);
-
- if (_vm->shouldExit())
- return false;
-
- while (events.timeElapsed() >= 3) {
- drawAnim(false);
- events.updateGameCounter();
+ events.updateGameCounter();
+ while (!_buttonValue && events.timeElapsed() < 3) {
+ events.pollEventsAndWait();
+ checkEvents(_vm);
+ if (g_vm->shouldExit())
+ return false;
}
+
+ drawAnim(false);
} while (!_buttonValue);
if (msgEnd)
diff --git a/engines/xeen/locations.h b/engines/xeen/locations.h
index 3bbd29e7e4..ad0a8e2cee 100644
--- a/engines/xeen/locations.h
+++ b/engines/xeen/locations.h
@@ -253,7 +253,7 @@ protected:
int _mazeId;
Direction _mazeDir;
Common::Point _mazePos;
- bool _mazeFlag;
+ bool _keyFound;
protected:
/**
* Sets the new location
@@ -364,7 +364,7 @@ public:
/**
* Show a given location, and return any result
*/
- int doAction(LocationAction actionId);
+ int doAction(int actionId);
/**
* Returns true if a town location (bank, blacksmith, etc.) is currently active
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index b0c269cdab..6e859e17ba 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -463,8 +463,6 @@ void MonsterObjectData::synchronize(XeenSerializer &s, MonsterData &monsterData)
if (obj._id < (int)_objectSprites.size()) {
obj._spriteId = _objectSprites[obj._id]._spriteId;
obj._sprites = &_objectSprites[obj._id]._sprites;
- } else {
- assert(!obj._id);
}
_objects.push_back(obj);
@@ -525,7 +523,8 @@ void MonsterObjectData::clearMonsterSprites() {
void MonsterObjectData::addMonsterSprites(MazeMonster &monster) {
Map &map = *g_vm->_map;
- int imgNumber = map._monsterData[monster._spriteId]._imageNumber;
+ monster._monsterData = &map._monsterData[monster._spriteId];
+ int imgNumber = monster._monsterData->_imageNumber;
uint idx;
// Find the sprites for the monster, loading them in if necessary
@@ -629,6 +628,7 @@ void Map::load(int mapId) {
FileManager &files = *g_vm->_files;
Interface &intf = *g_vm->_interface;
Party &party = *g_vm->_party;
+ Patcher &patcher = *g_vm->_patcher;
Sound &sound = *g_vm->_sound;
IndoorDrawList &indoorList = intf._indoorList;
OutdoorDrawList &outdoorList = intf._outdoorList;
@@ -795,7 +795,7 @@ void Map::load(int mapId) {
for (uint i = 0; i < _mobData._objectSprites.size(); ++i) {
files.setGameCc(_sideObjects);
- if (party._cloudsEnd && _mobData._objectSprites[i]._spriteId == 85 &&
+ if (party._cloudsCompleted && _mobData._objectSprites[i]._spriteId == 85 &&
mapId == 27 && ccNum) {
_mobData._objects[29]._spriteId = 0;
_mobData._objects[29]._id = 8;
@@ -983,6 +983,7 @@ void Map::load(int mapId) {
}
}
+ patcher.patch();
loadSky();
files.setGameCc(ccNum);
@@ -1053,7 +1054,8 @@ int Map::mazeLookup(const Common::Point &pt, int layerShift, int wallMask) {
_currentSurfaceId = _mazeData[_mazeDataIndex]._cells[pos.y][pos.x]._surfaceId;
}
- if (_currentSurfaceId == SURFTYPE_SPACE || _currentSurfaceId == SURFTYPE_SKY) {
+ if (mazeData()._surfaceTypes[_currentSurfaceId] == SURFTYPE_SPACE ||
+ mazeData()._surfaceTypes[_currentSurfaceId] == SURFTYPE_SKY) {
_currentSteppedOn = true;
} else {
_currentSteppedOn = _mazeData[_mazeDataIndex]._steppedOnTiles[pos.y][pos.x];
@@ -1223,7 +1225,8 @@ void Map::setWall(const Common::Point &pt, Direction dir, int v) {
}
int Map::getCell(int idx) {
- int mapId = _vm->_party->_mazeId;
+ Party &party = *g_vm->_party;
+ int mapId = party._mazeId;
Direction dir = _vm->_party->_mazeDirection;
Common::Point pt(
_vm->_party->_mazePosition.x + Res.SCREEN_POSITIONING_X[_vm->_party->_mazeDirection][idx],
@@ -1257,6 +1260,8 @@ int Map::getCell(int idx) {
}
if (!mapId) {
+ mapId = party._mazeId;
+
if (_isOutdoors) {
_currentSurfaceId = SURFTYPE_SPACE;
_currentWall = 0;
@@ -1291,6 +1296,8 @@ int Map::getCell(int idx) {
}
if (!mapId) {
+ mapId = party._mazeId;
+
if (_isOutdoors) {
_currentSurfaceId = SURFTYPE_SPACE;
_currentWall = 0;
diff --git a/engines/xeen/map.h b/engines/xeen/map.h
index a84c338d41..ef27bdb8ce 100644
--- a/engines/xeen/map.h
+++ b/engines/xeen/map.h
@@ -47,6 +47,10 @@ enum MonsterType {
MONSTER_DRAGON = 6
};
+enum MapId {
+ XEEN_CASTLE1 = 75, XEEN_CASTLE4 = 78
+};
+
class MonsterStruct {
public:
Common::String _name;
@@ -165,16 +169,16 @@ enum SurfaceType {
union MazeWallLayers {
struct MazeWallIndoors {
- int _wallNorth : 4;
- int _wallEast : 4;
- int _wallSouth : 4;
- int _wallWest : 4;
+ uint _wallNorth : 4;
+ uint _wallEast : 4;
+ uint _wallSouth : 4;
+ uint _wallWest : 4;
} _indoors;
struct MazeWallOutdoors {
- SurfaceType _surfaceId : 4;
- int _iMiddle : 4;
- int _iTop : 4;
- int _iOverlay : 4;
+ uint _surfaceId : 4; // SurfaceType, but needs to be unsigned
+ uint _iMiddle : 4;
+ uint _iTop : 4;
+ uint _iOverlay : 4;
} _outdoors;
uint16 _data;
};
diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk
index 9f6075b5f6..66091681b2 100644
--- a/engines/xeen/module.mk
+++ b/engines/xeen/module.mk
@@ -47,6 +47,7 @@ MODULE_OBJS := \
locations.o \
map.o \
party.o \
+ patcher.o \
resources.o \
saves.o \
screen.o \
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index d92a4952cc..83763a863e 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -87,6 +87,12 @@ void Treasure::clear() {
}
}
+void Treasure::reset() {
+ clear();
+ _hasItems = false;
+ _gold = _gems = 0;
+}
+
/*------------------------------------------------------------------------*/
const int BLACKSMITH_DATA1[4][4] = {
@@ -212,9 +218,9 @@ Party::Party(XeenEngine *vm) {
_holyBonus = 0;
_heroism = 0;
_difficulty = ADVENTURER;
- _cloudsEnd = false;
- _darkSideEnd = false;
- _worldEnd = false;
+ _cloudsCompleted = false;
+ _darkSideCompleted = false;
+ _worldCompleted = false;
_ctr24 = 0;
_day = 0;
_year = 0;
@@ -299,9 +305,9 @@ void Party::synchronize(Common::Serializer &s) {
_blacksmithWares.synchronize(s, 0);
- s.syncAsUint16LE(_cloudsEnd);
- s.syncAsUint16LE(_darkSideEnd);
- s.syncAsUint16LE(_worldEnd);
+ s.syncAsUint16LE(_cloudsCompleted);
+ s.syncAsUint16LE(_darkSideCompleted);
+ s.syncAsUint16LE(_worldCompleted);
s.syncAsUint16LE(_ctr24);
s.syncAsUint16LE(_day);
s.syncAsUint16LE(_year);
@@ -518,7 +524,7 @@ void Party::addTime(int numMinutes) {
_newDay = true;
if (_newDay && _minutes >= 300) {
- if (_vm->_mode != MODE_RECORD_EVENTS && _vm->_mode != MODE_17) {
+ if (_vm->_mode != MODE_SCRIPT_IN_PROGRESS && _vm->_mode != MODE_INTERACTIVE7) {
resetTemps();
if (_rested || _vm->_mode == MODE_SLEEPING) {
_rested = false;
@@ -689,11 +695,8 @@ void Party::giveTreasure() {
if (!_treasure._hasItems && !_treasure._gold && !_treasure._gems)
return;
- bool monstersPresent = false;
- for (int idx = 0; idx < 26 && !monstersPresent; ++idx)
- monstersPresent = combat._attackMonsters[idx] != -1;
-
- if (_vm->_mode != MODE_RECORD_EVENTS && monstersPresent)
+ bool monstersPresent = combat.areMonstersPresent();
+ if (_vm->_mode != MODE_SCRIPT_IN_PROGRESS && monstersPresent)
return;
combat.clearShooting();
@@ -778,7 +781,7 @@ void Party::giveTreasure() {
events.clearEvents();
if (_vm->_mode != MODE_COMBAT)
- _vm->_mode = MODE_1;
+ _vm->_mode = MODE_INTERACTIVE;
w.close();
_gold += _treasure._gold;
@@ -821,9 +824,17 @@ void Party::giveTreasureToCharacter(Character &c, ItemCategory category, int ite
w.update();
events.ipause(5);
- const char *itemName = XeenItem::getItemName(category, (category == CATEGORY_MISC) ?
- treasureItem._material : treasureItem._id);
- w.writeString(Common::String::format(Res.X_FOUND_Y, c._name.c_str(), itemName));
+ int index = (category == CATEGORY_MISC) ? treasureItem._material : treasureItem._id;
+ const char *itemName = XeenItem::getItemName(category, index);
+
+ if (index >= (_vm->getGameID() == GType_Swords ? 88 : 82)) {
+ // Quest item, give an extra '*' prefix
+ Common::String format = Common::String::format("\f04 * \fd%s", itemName);
+ w.writeString(Common::String::format(Res.X_FOUND_Y, c._name.c_str(), format.c_str()));
+ } else {
+ w.writeString(Common::String::format(Res.X_FOUND_Y, c._name.c_str(), itemName));
+ }
+
w.update();
c._items[category].sort();
events.ipause(8);
@@ -886,7 +897,7 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int
ps._tempAge -= takeVal;
break;
case 13:
- ps._skills[THIEVERY] = 0;
+ ps._skills[takeVal] = 0;
break;
case 15:
ps.setAward(takeVal, false);
@@ -915,45 +926,46 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int
case 20:
_gameFlags[files._ccNum][takeVal] = false;
break;
- case 21: {
- bool found = false;
- for (int idx = 0; idx < 9; ++idx) {
- if (takeVal < 35) {
- if (ps._weapons[idx]._id == takeVal) {
- ps._weapons[idx].clear();
- ps._weapons.sort();
- found = true;
- break;
- }
- } else if (takeVal < 49) {
- if (ps._armor[idx]._id == (takeVal - 35)) {
- ps._armor[idx].clear();
- ps._armor.sort();
- found = true;
- break;
- }
- } else if (takeVal < 60) {
- if (ps._accessories[idx]._id == (takeVal - 49)) {
- ps._accessories[idx].clear();
- ps._accessories.sort();
- found = true;
- break;
- }
- } else if (takeVal < 82) {
- if (ps._misc[idx]._material == ((int)takeVal - 60)) {
- ps._misc[idx].clear();
- ps._misc.sort();
- found = true;
- break;
+ case 21:
+ if (takeVal >= 82) {
+ _questItems[takeVal - 82]--;
+ } else {
+ bool found = false;
+ for (int idx = 0; idx < 9; ++idx) {
+ if (takeVal < 35) {
+ if (ps._weapons[idx]._id == takeVal) {
+ ps._weapons[idx].clear();
+ ps._weapons.sort();
+ found = true;
+ break;
+ }
+ } else if (takeVal < 49) {
+ if (ps._armor[idx]._id == (takeVal - 35)) {
+ ps._armor[idx].clear();
+ ps._armor.sort();
+ found = true;
+ break;
+ }
+ } else if (takeVal < 60) {
+ if (ps._accessories[idx]._id == (takeVal - 49)) {
+ ps._accessories[idx].clear();
+ ps._accessories.sort();
+ found = true;
+ break;
+ }
+ } else {
+ if (ps._misc[idx]._material == ((int)takeVal - 60)) {
+ ps._misc[idx].clear();
+ ps._misc.sort();
+ found = true;
+ break;
+ }
}
- } else {
- _questItems[takeVal - 82]--;
}
+ if (!found)
+ return true;
}
- if (!found)
- return true;
break;
- }
case 25:
changeTime(takeVal);
break;
@@ -1156,14 +1168,16 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int
ps._currentHp = 0;
break;
case 19: {
+ // Give spell to character
SpellsCategory category = ps.getSpellsCategory();
- assert(category != SPELLCAT_INVALID);
- for (int idx = 0; idx < SPELLS_PER_CLASS; ++idx) {
- if (Res.SPELLS_ALLOWED[category][idx] == (int)giveVal) {
- ps._spells[idx] = true;
- intf.spellFX(&ps);
- break;
+ if (category != SPELLCAT_INVALID) {
+ for (int idx = 0; idx < SPELLS_PER_CLASS; ++idx) {
+ if (Res.SPELLS_ALLOWED[category][idx] == (int)giveVal) {
+ ps._spells[idx] = true;
+ intf.spellFX(&ps);
+ break;
+ }
}
}
break;
@@ -1172,35 +1186,40 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int
_gameFlags[files._ccNum][giveVal] = true;
break;
case 21: {
+ const uint WEAPONS_END = _vm->getGameID() != GType_Swords ? 35 : 41;
+ const uint ARMOR_END = _vm->getGameID() != GType_Swords ? 49 : 55;
+ const uint ACCESSORIES_END = _vm->getGameID() != GType_Swords ? 60 : 66;
+ const uint MISC_END = _vm->getGameID() != GType_Swords ? 82 : 88;
+
int idx;
- if (giveVal >= 82) {
- _questItems[giveVal - 82]++;
+ if (giveVal >= MISC_END) {
+ _questItems[giveVal - MISC_END]++;
}
- if (giveVal < 35 || giveVal >= 82) {
- for (idx = 0; idx < 10 && _treasure._weapons[idx]._id; ++idx);
- if (idx < 10) {
+ if (giveVal < WEAPONS_END || giveVal >= MISC_END) {
+ for (idx = 0; idx < MAX_TREASURE_ITEMS && !_treasure._weapons[idx].empty(); ++idx);
+ if (idx < MAX_TREASURE_ITEMS) {
_treasure._weapons[idx]._id = giveVal;
_treasure._hasItems = true;
return false;
}
- } else if (giveVal < 49) {
- for (idx = 0; idx < 10 && _treasure._armor[idx]._id; ++idx);
- if (idx < 10) {
- _treasure._armor[idx]._id = giveVal - 35;
+ } else if (giveVal < ARMOR_END) {
+ for (idx = 0; idx < MAX_TREASURE_ITEMS && !_treasure._armor[idx].empty(); ++idx);
+ if (idx < MAX_TREASURE_ITEMS) {
+ _treasure._armor[idx]._id = giveVal - WEAPONS_END;
_treasure._hasItems = true;
return false;
}
- } else if (giveVal < 60) {
- for (idx = 0; idx < 10 && _treasure._accessories[idx]._id; ++idx);
- if (idx < 10) {
- _treasure._accessories[idx]._id = giveVal - 49;
+ } else if (giveVal < ACCESSORIES_END) {
+ for (idx = 0; idx < MAX_TREASURE_ITEMS && !_treasure._accessories[idx].empty(); ++idx);
+ if (idx < MAX_TREASURE_ITEMS) {
+ _treasure._accessories[idx]._id = giveVal - ARMOR_END;
_treasure._hasItems = true;
return false;
}
} else {
- for (idx = 0; idx < 10 && _treasure._misc[idx]._material; ++idx);
- if (idx < 10) {
- _treasure._accessories[idx]._material = giveVal - 60;
+ for (idx = 0; idx < MAX_TREASURE_ITEMS && _treasure._misc[idx]._material; ++idx);
+ if (idx < MAX_TREASURE_ITEMS) {
+ _treasure._accessories[idx]._material = giveVal - ACCESSORIES_END;
_treasure._hasItems = true;
return false;
}
@@ -1412,16 +1431,16 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int
_gold += _vm->getRandomNumber(1, giveVal);
break;
case 103:
- assert(takeVal < 128);
- _worldFlags[takeVal] = true;
+ assert(giveVal < 128);
+ _worldFlags[giveVal] = true;
break;
case 104:
assert(giveVal < 30);
_questFlags[files._ccNum][giveVal] = true;
break;
case 107:
- assert(takeVal < 24);
- _characterFlags[ps._rosterId][takeVal] = true;
+ assert(giveVal < 24);
+ _characterFlags[ps._rosterId][giveVal] = true;
break;
default:
break;
@@ -1437,9 +1456,10 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint
Map &map = *g_vm->_map;
Scripts &scripts = *g_vm->_scripts;
Sound &sound = *g_vm->_sound;
- Character &c = _itemsCharacter;
- if (intf._objNumber != -1 && !scripts._animCounter) {
+ // WORKAROUND: Ali Baba's chest in Dark Side requires the character in the first slot to have Lockpicking.
+ // This is obviously a mistake, since the chest is meant to be opened via a password
+ if (intf._objNumber != -1 && !scripts._animCounter && !(files._ccNum && _mazeId == 63 && intf._objNumber == 15)) {
MazeObject &obj = map._mobData._objects[intf._objNumber];
switch (obj._spriteId) {
case 15:
@@ -1449,7 +1469,8 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint
case 16:
case 58:
- case 73:
+ case 73: {
+ Character &c = _activeParty[charId];
obj._frame = 1;
if (obj._position.x != 20) {
@@ -1480,6 +1501,11 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint
return true;
}
}
+ break;
+ }
+
+ default:
+ break;
}
}
@@ -1497,7 +1523,7 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint
break;
case 66:
- c.clear();
+ _itemsCharacter.clear();
if (giveTake(0, 0, mode, val, charId))
return true;
diff --git a/engines/xeen/party.h b/engines/xeen/party.h
index b0be1a2f21..3d6142451c 100644
--- a/engines/xeen/party.h
+++ b/engines/xeen/party.h
@@ -87,6 +87,11 @@ public:
* Clears the treasure list
*/
void clear();
+
+ /**
+ * Completely reset the treasure data
+ */
+ void reset();
};
/**
@@ -190,9 +195,9 @@ public:
int _heroism;
Difficulty _difficulty;
BlacksmithWares _blacksmithWares;
- bool _cloudsEnd;
- bool _darkSideEnd;
- bool _worldEnd;
+ bool _cloudsCompleted;
+ bool _darkSideCompleted;
+ bool _worldCompleted;
int _ctr24; // Unused counter
int _day;
uint _year;
diff --git a/engines/xeen/patcher.cpp b/engines/xeen/patcher.cpp
new file mode 100644
index 0000000000..280724cb78
--- /dev/null
+++ b/engines/xeen/patcher.cpp
@@ -0,0 +1,86 @@
+/* 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 "xeen/patcher.h"
+#include "xeen/xeen.h"
+#include "xeen/map.h"
+#include "xeen/party.h"
+#include "common/memstream.h"
+#include "common/serializer.h"
+
+namespace Xeen {
+
+struct ScriptEntry {
+ uint _gameId;
+ int _mapId;
+ const byte *_data;
+};
+
+const byte DS_MAP54_LINE8[] = { 8, 10, 10, DIR_EAST, 8, OP_MoveWallObj, 20, 100, 100 };
+const byte SW_MAP53_LINE8[] = { 5, 14, 6, DIR_EAST, 8, OP_Exit };
+
+#define SCRIPT_PATCHES_COUNT 2
+static const ScriptEntry SCRIPT_PATCHES[] = {
+ { GType_DarkSide, 54, DS_MAP54_LINE8 }, // Fix curtain on level 2 of Ellinger's Tower
+ { GType_Swords, 53, SW_MAP53_LINE8 } // Fix chest in Hart having gems, but saying "Nothing Here"
+};
+
+/*------------------------------------------------------------------------*/
+
+void Patcher::patch() {
+ patchScripts();
+}
+
+void Patcher::patchScripts() {
+ FileManager &files = *g_vm->_files;
+ Map &map = *g_vm->_map;
+ Party &party = *g_vm->_party;
+
+ uint gameId = g_vm->getGameID();
+ if (gameId == GType_WorldOfXeen)
+ gameId = files._ccNum ? GType_DarkSide : GType_Clouds;
+
+ for (int patchIdx = 0; patchIdx < SCRIPT_PATCHES_COUNT; ++patchIdx) {
+ const ScriptEntry &se = SCRIPT_PATCHES[patchIdx];
+ if (se._gameId != gameId || se._mapId != party._mazeId)
+ continue;
+
+ MazeEvent evt;
+ Common::MemoryReadStream memStream(se._data, se._data[0] + 1);
+ Common::Serializer s(&memStream, nullptr);
+ evt.synchronize(s);
+
+ // Scan through the events to find a matching line
+ int idx = 0;
+ while (idx < (int)map._events.size() && (evt._position != map._events[idx]._position
+ || evt._direction != map._events[idx]._direction || evt._line != map._events[idx]._line))
+ ++idx;
+
+ // Set the event
+ if (idx == (int)map._events.size())
+ map._events.push_back(evt);
+ else
+ map._events[idx] = evt;
+ }
+}
+
+} // End of namespace Xeen
diff --git a/engines/xeen/patcher.h b/engines/xeen/patcher.h
new file mode 100644
index 0000000000..f0d4267320
--- /dev/null
+++ b/engines/xeen/patcher.h
@@ -0,0 +1,48 @@
+/* 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 XEEN_PATCHER_H
+#define XEEN_PATCHER_H
+
+namespace Xeen {
+
+class Patcher {
+private:
+ /**
+ * Patches incorrect script lines
+ */
+ void patchScripts();
+public:
+ /**
+ * Constructor
+ */
+ Patcher() {}
+
+ /**
+ * Called after a map is loaded to patch any problems
+ */
+ void patch();
+};
+
+} // End of namespace Xeen
+
+#endif /* XEEN_PATCHER_H */
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index c599480e2f..fbb0a063a3 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -315,6 +315,7 @@ void Resources::loadData() {
file.syncString(QUESTS_DIALOG_TEXT);
file.syncString(CLOUDS_OF_XEEN_LINE);
file.syncString(DARKSIDE_OF_XEEN_LINE);
+ file.syncString(SWORDS_OF_XEEN_LINE);
file.syncString(NO_QUEST_ITEMS);
file.syncString(NO_CURRENT_QUESTS);
file.syncString(NO_AUTO_NOTES);
@@ -364,7 +365,8 @@ void Resources::loadData() {
file.syncString(LLOYDS_BEACON);
file.syncString(HOW_MANY_SQUARES);
file.syncString(TOWN_PORTAL);
- file.syncNumbers2D((int *)TOWN_MAP_NUMBERS, 2, 5);
+ file.syncString(TOWN_PORTAL_SWORDS);
+ file.syncNumbers2D((int *)TOWN_MAP_NUMBERS, 3, 5);
file.syncString(MONSTER_DETAILS);
file.syncStrings(MONSTER_SPECIAL_ATTACKS, 23);
file.syncString(IDENTIFY_MONSTERS);
@@ -398,6 +400,7 @@ void Resources::loadData() {
file.syncStrings(MUSIC_FILES1, 5);
file.syncStrings2D(&MUSIC_FILES2[0][0], 6, 7);
file.syncString(DIFFICULTY_TEXT);
+ file.syncString(SAVE_OFF_LIMITS);
}
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index bfd5cce41b..1567caae00 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -370,6 +370,7 @@ public:
const char *QUESTS_DIALOG_TEXT;
const char *CLOUDS_OF_XEEN_LINE;
const char *DARKSIDE_OF_XEEN_LINE;
+ const char *SWORDS_OF_XEEN_LINE;
const char *NO_QUEST_ITEMS;
const char *NO_CURRENT_QUESTS;
const char *NO_AUTO_NOTES;
@@ -419,7 +420,8 @@ public:
const char *LLOYDS_BEACON;
const char *HOW_MANY_SQUARES;
const char *TOWN_PORTAL;
- int TOWN_MAP_NUMBERS[2][5];
+ const char *TOWN_PORTAL_SWORDS;
+ int TOWN_MAP_NUMBERS[3][5];
const char *MONSTER_DETAILS;
const char *MONSTER_SPECIAL_ATTACKS[23];
const char *IDENTIFY_MONSTERS;
@@ -453,6 +455,7 @@ public:
const char *MUSIC_FILES1[5];
const char *MUSIC_FILES2[6][7];
const char *DIFFICULTY_TEXT;
+ const char *SAVE_OFF_LIMITS;
public:
/**
* Constructor
diff --git a/engines/xeen/saves.cpp b/engines/xeen/saves.cpp
index a055627af4..60cac91b75 100644
--- a/engines/xeen/saves.cpp
+++ b/engines/xeen/saves.cpp
@@ -48,9 +48,8 @@ SavesManager::~SavesManager() {
const char *const SAVEGAME_STR = "XEEN";
#define SAVEGAME_STR_SIZE 6
-bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header) {
+WARN_UNUSED_RESULT bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -68,9 +67,9 @@ bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader
header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
@@ -153,6 +152,7 @@ Common::Error SavesManager::saveGameState(int slot, const Common::String &desc)
}
Common::Error SavesManager::loadGameState(int slot) {
+ Combat &combat = *g_vm->_combat;
EventsManager &events = *g_vm->_events;
FileManager &files = *g_vm->_files;
Map &map = *g_vm->_map;
@@ -168,11 +168,6 @@ Common::Error SavesManager::loadGameState(int slot) {
if (!readSavegameHeader(saveFile, header))
error("Invalid savegame");
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
// Set the total play time
events.setPlayTime(header._totalFrames);
@@ -193,6 +188,10 @@ Common::Error SavesManager::loadGameState(int slot) {
// Read in miscellaneous
files.load(*saveFile);
+ // Reset any combat information from the previous game
+ combat.reset();
+ party._treasure.reset();
+
// Load the new map
map.clearMaze();
map._loadCcNum = files._ccNum;
@@ -212,6 +211,10 @@ void SavesManager::newGame() {
File::_xeenSave = nullptr;
File::_darkSave = nullptr;
+ // Reset any combat information from the previous game
+ g_vm->_combat->reset();
+
+ // Reset the game states
if (g_vm->getGameID() != GType_Clouds) {
File::_darkSave = new SaveArchive(g_vm->_party);
File::_darkSave->reset(File::_darkCc);
@@ -258,18 +261,24 @@ bool SavesManager::loadGame() {
}
bool SavesManager::saveGame() {
- if (!g_vm->canSaveGameStateCurrently())
+ Map &map = *g_vm->_map;
+
+ if (map.mazeData()._mazeFlags & RESTRICTION_SAVE) {
+ ErrorScroll::show(g_vm, Res.SAVE_OFF_LIMITS, WT_NONFREEZED_WAIT);
return false;
+ } else if (!g_vm->canSaveGameStateCurrently()) {
+ return false;
+ } else {
+ GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
+ int slotNum = dialog->runModalWithCurrentTarget();
+ Common::String saveName = dialog->getResultString();
+ delete dialog;
- GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
- int slotNum = dialog->runModalWithCurrentTarget();
- Common::String saveName = dialog->getResultString();
- delete dialog;
-
- if (slotNum != -1)
- saveGameState(slotNum, saveName);
+ if (slotNum != -1)
+ saveGameState(slotNum, saveName);
- return slotNum != -1;
+ return slotNum != -1;
+ }
}
} // End of namespace Xeen
diff --git a/engines/xeen/saves.h b/engines/xeen/saves.h
index b18e04a822..9b1bea62a3 100644
--- a/engines/xeen/saves.h
+++ b/engines/xeen/saves.h
@@ -65,7 +65,7 @@ public:
/**
* Read in a savegame header
*/
- static bool readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header, bool skipThumbnail = true);
/**
* Write out a savegame header
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 7f78f5bf2c..f126a658a2 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -186,7 +186,7 @@ int Scripts::checkEvents() {
if (event._position == _currentPos && event._line == _lineNum &&
(party._mazeDirection | _currentPos.x | _currentPos.y)) {
if (event._direction == party._mazeDirection || event._direction == DIR_ALL) {
- _vm->_mode = MODE_RECORD_EVENTS;
+ _vm->_mode = MODE_SCRIPT_IN_PROGRESS;
_scriptExecuted = true;
doOpcode(event);
break;
@@ -214,7 +214,7 @@ int Scripts::checkEvents() {
MazeObject &selectedObj = map._mobData._objects[intf._objNumber];
if (selectedObj._spriteId == (ccNum ? 15 : 16)) {
- for (uint idx = 0; idx < 16; ++idx) {
+ for (int idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) {
MazeObject &obj = map._mobData._objects[idx];
if (obj._spriteId == (ccNum ? 62 : 57)) {
selectedObj._id = idx;
@@ -223,7 +223,7 @@ int Scripts::checkEvents() {
}
}
} else if (selectedObj._spriteId == 73) {
- for (uint idx = 0; idx < 16; ++idx) {
+ for (int idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) {
MazeObject &obj = map._mobData._objects[idx];
if (obj._spriteId == 119) {
selectedObj._id = idx;
@@ -496,7 +496,7 @@ bool Scripts::cmdTeleport(ParamsIterator &params) {
party._stepped = true;
if (mapId != party._mazeId) {
- int spriteId = (intf._objNumber == -1) ? -1 : map._mobData._objects[intf._objNumber - 1]._spriteId;
+ int spriteId = (intf._objNumber == -1) ? -1 : map._mobData._objects[intf._objNumber]._spriteId;
switch (spriteId) {
case 47:
@@ -596,7 +596,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
Combat &combat = *_vm->_combat;
Party &party = *_vm->_party;
Windows &windows = *_vm->_windows;
- int mode1, mode2, mode3, param2;
+ int mode1, mode2, mode3;
uint32 val1, val2, val3;
_refreshIcons = true;
@@ -618,7 +618,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
break;
}
- param2 = mode2 = params.readByte();
+ mode2 = params.readByte();
switch (mode2) {
case 16:
case 34:
@@ -711,7 +711,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
if (_charIndex == 0 || _charIndex == 8) {
for (uint idx = 0; idx < party._activeParty.size(); ++idx) {
if (_charIndex == 0 || (_charIndex == 8 && (int)idx != combat._combatTarget)) {
- party.giveTake(mode1, val1, mode2, val2, idx);
+ bool flag = party.giveTake(mode1, val1, mode2, val2, idx);
switch (mode1) {
case 8:
@@ -719,7 +719,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
// fall through
case 21:
case 66:
- if (param2) {
+ if (flag) {
switch (mode2) {
case 82:
mode1 = 0;
@@ -732,13 +732,18 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
case 100:
case 101:
case 106:
- if (param2)
+ if (flag)
continue;
// Break out of character loop
idx = party._activeParty.size();
break;
+ default:
+ break;
}
+ } else {
+ // Break out of character loop
+ idx = party._activeParty.size();
}
break;
@@ -748,7 +753,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
case 100:
case 101:
case 106:
- if (param2) {
+ if (flag) {
_lineNum = -1;
return false;
}
@@ -770,7 +775,7 @@ bool Scripts::cmdTakeOrGive(ParamsIterator &params) {
case 100:
case 101:
case 106:
- if (param2)
+ if (flag)
continue;
// Break out of character loop
@@ -849,7 +854,7 @@ bool Scripts::cmdSpawn(ParamsIterator &params) {
}
bool Scripts::cmdDoTownEvent(ParamsIterator &params) {
- _scriptResult = _vm->_locations->doAction((LocationAction)params.readByte());
+ _scriptResult = _vm->_locations->doAction(params.readByte());
_vm->_party->_stepped = true;
_refreshIcons = true;
@@ -934,18 +939,24 @@ bool Scripts::cmdConfirmWord(ParamsIterator &params) {
int param2 = params.readByte();
int param3 = params.readByte();
- Common::String msg1 = param2 ? map._events._text[param2] : _message;
- Common::String msg2;
+ Common::String expected2;
+ Common::String title;
if (_event->_opcode == OP_ConfirmWord_2) {
- msg2 = "";
+ title = "";
} else if (param3) {
- msg2 = map._events._text[param3];
+ title = map._events._text[param3];
} else {
- msg2 = Res.WHATS_THE_PASSWORD;
+ title = Res.WHATS_THE_PASSWORD;
}
- _mirrorId = StringInput::show(_vm, inputType, msg1, msg2, _event->_opcode);
+ if (!param2) {
+ expected2 = _message;
+ } else if (param2 < (int)map._events._text.size()) {
+ expected2 = map._events._text[param2];
+ }
+
+ _mirrorId = StringInput::show(_vm, inputType, expected2, title, _event->_opcode);
if (_mirrorId) {
if (_mirrorId == 33 && files._ccNum) {
doDarkSideEnding();
@@ -1037,11 +1048,16 @@ bool Scripts::cmdCallEvent(ParamsIterator &params) {
}
bool Scripts::cmdReturn(ParamsIterator &params) {
- StackEntry se = _stack.pop();
- _currentPos = se;
- _lineNum = se.line;
+ if (_stack.empty()) {
+ // WORKAROUND: Some scripts in Swords of Xeen use cmdReturn as a substitute for cmdExit
+ return cmdExit(params);
+ } else {
+ StackEntry se = _stack.pop();
+ _currentPos = se;
+ _lineNum = se.line;
- return true;
+ return true;
+ }
}
bool Scripts::cmdSetVar(ParamsIterator &params) {
@@ -1124,11 +1140,11 @@ bool Scripts::cmdRndDamage(ParamsIterator &params) {
bool Scripts::cmdMoveWallObj(ParamsIterator &params) {
Map &map = *_vm->_map;
- int itemNum = params.readByte();
+ int index = params.readByte();
int x = params.readShort();
int y = params.readShort();
- map._mobData._wallItems[itemNum]._position = Common::Point(x, y);
+ map._mobData._wallItems[index]._position = Common::Point(x, y);
return true;
}
@@ -1207,14 +1223,25 @@ bool Scripts::cmdDisplayBottom(ParamsIterator &params) {
bool Scripts::cmdIfMapFlag(ParamsIterator &params) {
Map &map = *_vm->_map;
- MazeMonster &monster = map._mobData._monsters[params.readByte()];
+ int monsterNum = params.readByte();
+ int lineNum = params.readByte();
- if (monster._position.x >= 32 || monster._position.y >= 32) {
- _lineNum = params.readByte();
- return false;
+ if (monsterNum == 0xff) {
+ for (monsterNum = 0; monsterNum < (int)map._mobData._monsters.size(); ++monsterNum) {
+ MazeMonster &monster = map._mobData._monsters[monsterNum];
+
+ if ((uint)monster._position.x < 32 && (uint)monster._position.y < 32)
+ return true;
+ }
+ } else {
+ MazeMonster &monster = map._mobData._monsters[monsterNum];
+
+ if ((uint)monster._position.x < 32 && (uint)monster._position.y < 32)
+ return true;
}
- return true;
+ _lineNum = lineNum;
+ return false;
}
bool Scripts::cmdSelectRandomChar(ParamsIterator &params) {
@@ -1224,24 +1251,25 @@ bool Scripts::cmdSelectRandomChar(ParamsIterator &params) {
bool Scripts::cmdGiveEnchanted(ParamsIterator &params) {
Party &party = *_vm->_party;
+ int itemOffset = _vm->getGameID() == GType_Swords ? 6 : 0;
XeenItem *item;
int invIndex;
int id = params.readByte();
// Get category of item to add
ItemCategory cat = CATEGORY_WEAPON;
- if (id < 35) {
- } else if (id < 49) {
+ if (id < (35 + itemOffset)) {
+ } else if (id < (49 + itemOffset)) {
cat = CATEGORY_ARMOR;
- id -= 35;
- } else if (id < 60) {
+ id -= 35 + itemOffset;
+ } else if (id < (60 + itemOffset)) {
cat = CATEGORY_ACCESSORY;
- id -= 49;
- } else if (id < 82) {
+ id -= 49 + itemOffset;
+ } else if (id < (82 + itemOffset)) {
cat = CATEGORY_MISC;
- id -= 60;
+ id -= 60 + itemOffset;
} else {
- party._questItems[id - 82]++;
+ party._questItems[id - (82 + itemOffset)]++;
}
// Check for an empty slot
@@ -1377,6 +1405,8 @@ bool Scripts::cmdFallToMap(ParamsIterator &params) {
}
bool Scripts::cmdDisplayMain(ParamsIterator &params) {
+ _windowIndex = 11;
+
display(false, 0);
return true;
}
@@ -1401,7 +1431,7 @@ bool Scripts::cmdCutsceneEndDarkside(ParamsIterator &params) {
Party &party = *_vm->_party;
_vm->_saves->_wonDarkSide = true;
party._questItems[53] = 1;
- party._darkSideEnd = true;
+ party._darkSideCompleted = true;
party._mazeId = 29;
party._mazeDirection = DIR_NORTH;
party._mazePosition = Common::Point(25, 21);
@@ -1422,7 +1452,7 @@ bool Scripts::cmdCutsceneEndWorld(ParamsIterator &params) {
g_vm->saveSettings();
_vm->_saves->_wonWorld = true;
- _vm->_party->_worldEnd = true;
+ _vm->_party->_worldCompleted = true;
doWorldEnding();
return false;
@@ -1436,10 +1466,18 @@ bool Scripts::cmdFlipWorld(ParamsIterator &params) {
bool Scripts::cmdPlayCD(ParamsIterator &params) { error("TODO"); }
void Scripts::doCloudsEnding() {
+ g_vm->_party->_cloudsCompleted = true;
doEnding("ENDGAME");
+
+ g_vm->_mode = MODE_INTERACTIVE;
+ g_vm->_saves->saveGame();
+
+ g_vm->_gameMode = GMODE_MENU;
+ g_vm->_mode = MODE_STARTUP;
}
void Scripts::doDarkSideEnding() {
+ g_vm->_party->_darkSideCompleted = true;
doEnding("ENDGAME2");
}
@@ -1556,37 +1594,39 @@ bool Scripts::ifProc(int action, uint32 val, int mode, int charIndex) {
assert(val < 512);
v = party._gameFlags[val / 256][val % 256] ? val : 0xffffffff;
break;
- case 21:
+ case 21: {
// Scans inventories for given item number
+ uint itemOffset = _vm->getGameID() == GType_Swords ? 6 : 0;
v = 0xFFFFFFFF;
- if (val < 82) {
+ if (val < (82 + itemOffset)) {
for (int idx = 0; idx < 9; ++idx) {
- if (val == 35) {
+ if (val == (35 + itemOffset)) {
if (ps->_weapons[idx]._id == val) {
v = val;
break;
}
- } else if (val < 49) {
+ } else if (val < (49 + itemOffset)) {
if (ps->_armor[idx]._id == (val - 35)) {
v = val;
break;
}
- } else if (val < 60) {
- if (ps->_accessories[idx]._id == (val - 49)) {
+ } else if (val < (60 + itemOffset)) {
+ if (ps->_accessories[idx]._id == (val - (49 + itemOffset))) {
v = val;
break;
}
} else {
- if (ps->_misc[idx]._id == (val - 60)) {
+ if (ps->_misc[idx]._id == (val - (60 + itemOffset))) {
v = val;
break;
}
}
}
- } else if (party._questItems[val - 82]) {
+ } else if (party._questItems[val - (82 + itemOffset)]) {
v = val;
}
break;
+ }
case 25:
// Returns number of minutes elapsed in the day (0-1440)
v = party._minutes;
@@ -1600,7 +1640,7 @@ bool Scripts::ifProc(int action, uint32 val, int mode, int charIndex) {
v = party._gems;
break;
case 37:
- // Might bonus (extra beond base)
+ // Might bonus (extra beyond base)
v = ps->_might._temporary;
break;
case 38:
@@ -1802,7 +1842,7 @@ bool Scripts::ifProc(int action, uint32 val, int mode, int charIndex) {
break;
case 107:
// Get value of character flag
- error("Unused");
+ v = party._characterFlags[ps->_rosterId][val] ? val : 0xffffffff;
break;
default:
break;
diff --git a/engines/xeen/scripts.h b/engines/xeen/scripts.h
index f35aecedff..1bdf836287 100644
--- a/engines/xeen/scripts.h
+++ b/engines/xeen/scripts.h
@@ -220,7 +220,6 @@ private:
MazeEvent *_event;
Common::Point _currentPos;
Common::Stack<StackEntry> _stack;
- Common::String _message;
Common::String _displayMessage;
typedef EventParameters::Iterator ParamsIterator;
@@ -552,6 +551,7 @@ public:
DamageType _nEdamageType;
int _itemType;
Common::Array<MirrorEntry> _mirror;
+ Common::String _message;
public:
Scripts(XeenEngine *vm);
diff --git a/engines/xeen/sound.cpp b/engines/xeen/sound.cpp
index be15028f42..9800af5403 100644
--- a/engines/xeen/sound.cpp
+++ b/engines/xeen/sound.cpp
@@ -121,29 +121,29 @@ void Sound::updateSoundSettings() {
void Sound::loadEffectsData() {
// Stop any prior FX
stopFX();
- delete[] _effectsData;
- // Load in an entire driver so we have quick access to the effects data
- // that's hardcoded within it
- File file("blastmus");
- byte *effectsData = new byte[file.size()];
- file.seek(0);
- file.read(effectsData, file.size());
- file.close();
- _effectsData = effectsData;
-
- // Locate the playFX routine
- const byte *fx = effectsData + READ_LE_UINT16(effectsData + 10) + 12;
- assert(READ_BE_UINT16(fx + 28) == 0x81FB);
- uint numEffects = READ_LE_UINT16(fx + 30);
-
- assert(READ_BE_UINT16(fx + 36) == 0x8B87);
- const byte *table = effectsData + READ_LE_UINT16(fx + 38);
-
- // Extract the effects offsets
- _effectsOffsets.resize(numEffects);
- for (uint idx = 0; idx < numEffects; ++idx)
- _effectsOffsets[idx] = READ_LE_UINT16(&table[idx * 2]);
+ if (!_effectsData) {
+ // Load in an entire driver so we have quick access to the effects data that's hardcoded within it
+ File file("blastmus");
+ byte *effectsData = new byte[file.size()];
+ file.seek(0);
+ file.read(effectsData, file.size());
+ file.close();
+ _effectsData = effectsData;
+
+ // Locate the playFX routine
+ const byte *fx = effectsData + READ_LE_UINT16(effectsData + 10) + 12;
+ assert(READ_BE_UINT16(fx + 28) == 0x81FB);
+ uint numEffects = READ_LE_UINT16(fx + 30);
+
+ assert(READ_BE_UINT16(fx + 36) == 0x8B87);
+ const byte *table = effectsData + READ_LE_UINT16(fx + 38);
+
+ // Extract the effects offsets
+ _effectsOffsets.resize(numEffects);
+ for (uint idx = 0; idx < numEffects; ++idx)
+ _effectsOffsets[idx] = READ_LE_UINT16(&table[idx * 2]);
+ }
}
void Sound::playFX(uint effectId) {
diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp
index f5307504b2..7ebe9ad019 100644
--- a/engines/xeen/spells.cpp
+++ b/engines/xeen/spells.cpp
@@ -522,8 +522,8 @@ void Spells::elementalStorm() {
combat._monsterDamage = 150;
combat._damageType = (DamageType)_vm->getRandomNumber(DT_FIRE, DT_POISON);
combat._rangeType = RT_ALL;
- sound.playFX(STORM_FX_LIST[combat._damageType]);
- combat.rangedAttack(STORM_MA_LIST[combat._damageType]);
+ sound.playFX(STORM_FX_LIST[combat._damageType - DT_FIRE]);
+ combat.rangedAttack(STORM_MA_LIST[combat._damageType - DT_FIRE]);
}
void Spells::enchantItem() {
@@ -1150,7 +1150,7 @@ void Spells::superShelter() {
spellFailed();
} else {
Mode oldMode = _vm->_mode;
- _vm->_mode = MODE_12;
+ _vm->_mode = MODE_INTERACTIVE2;
sound.playFX(30);
intf.rest();
_vm->_mode = oldMode;
@@ -1250,9 +1250,14 @@ void Spells::townPortal() {
sound.playFX(51);
map._loadCcNum = map._sideTownPortal;
_vm->_files->_ccNum = map._sideTownPortal > 0;
- map.load(Res.TOWN_MAP_NUMBERS[map._sideTownPortal][townNumber - 1]);
- if (!_vm->_files->_ccNum) {
+ int arrIndex = _vm->getGameID() == GType_Swords ? 2 : map._sideTownPortal;
+ map.load(Res.TOWN_MAP_NUMBERS[arrIndex][townNumber - 1]);
+
+ if (_vm->getGameID() == GType_Swords) {
+ party._mazePosition = Common::Point(8, 3);
+ party._mazeDirection = DIR_NORTH;
+ } else if (!_vm->_files->_ccNum) {
party.moveToRunLocation();
} else {
switch (townNumber) {
diff --git a/engines/xeen/sprites.cpp b/engines/xeen/sprites.cpp
index adeb5671c1..7b484b53e3 100644
--- a/engines/xeen/sprites.cpp
+++ b/engines/xeen/sprites.cpp
@@ -147,8 +147,7 @@ void SpriteResource::drawOffset(XSurface &dest, uint16 offset, const Common::Poi
bounds = Common::Rect(0, 0, dest.w, dest.h);
}
if (flags & SPRFLAG_SCENE_CLIPPED) {
- bounds.top = 8;
- bounds.bottom = 149;
+ bounds.clip(Common::Rect(8, 8, 223, 141));
}
uint16 scaleMaskXCopy = scaleMaskX;
@@ -285,8 +284,7 @@ void SpriteResource::drawOffset(XSurface &dest, uint16 offset, const Common::Poi
if (bit) {
// Check whether there's a pixel to write, and we're within the allowable bounds. Note that for
// the SPRFLAG_SCENE_CLIPPED or when enlarging, we also have an extra horizontal bounds check
- if (*lineP != -1 && xp >= bounds.left && xp < bounds.right &&
- ((!(flags & SPRFLAG_SCENE_CLIPPED) && !enlarge) || (xp >= SCENE_CLIP_LEFT && xp < SCENE_CLIP_RIGHT))) {
+ if (*lineP != -1 && xp >= bounds.left && xp < bounds.right) {
drawBounds.left = MIN(drawBounds.left, xp);
drawBounds.right = MAX((int)drawBounds.right, xp + 1);
*destP = (byte)*lineP;
diff --git a/engines/xeen/worldofxeen/worldofxeen_menu.cpp b/engines/xeen/worldofxeen/worldofxeen_menu.cpp
index 8356794ef7..a4a4b0277b 100644
--- a/engines/xeen/worldofxeen/worldofxeen_menu.cpp
+++ b/engines/xeen/worldofxeen/worldofxeen_menu.cpp
@@ -110,11 +110,9 @@ void MainMenuContainer::execute() {
} else {
// No active dialog. If Escape pressed, exit game entirely. Otherwise,
// open up the main menu dialog
- if (events.isKeyPending()) {
- Common::KeyState key;
- if (events.getKey(key) && key.keycode == Common::KEYCODE_ESCAPE)
- g_vm->_gameMode = GMODE_QUIT;
- }
+ PendingEvent pe;
+ if (events.getEvent(pe) && pe._keyState.keycode == Common::KEYCODE_ESCAPE)
+ g_vm->_gameMode = GMODE_QUIT;
events.clearEvents();
showMenuDialog();
diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp
index 1d0e33d2b6..371f437172 100644
--- a/engines/xeen/xeen.cpp
+++ b/engines/xeen/xeen.cpp
@@ -49,6 +49,7 @@ XeenEngine::XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc)
_locations = nullptr;
_map = nullptr;
_party = nullptr;
+ _patcher = nullptr;
_resources = nullptr;
_saves = nullptr;
_screen = nullptr;
@@ -75,6 +76,7 @@ XeenEngine::~XeenEngine() {
delete _locations;
delete _map;
delete _party;
+ delete _patcher;
delete _saves;
delete _screen;
delete _scripts;
@@ -100,6 +102,7 @@ bool XeenEngine::initialize() {
_locations = new LocationManager();
_map = new Map(this);
_party = new Party(this);
+ _patcher = new Patcher();
_saves = new SavesManager(_targetName);
_screen = new Screen(this);
_scripts = new Scripts(this);
@@ -126,6 +129,7 @@ void XeenEngine::loadSettings() {
_finalScore = ConfMan.hasKey("final_score") ? ConfMan.getInt("final_score") : 0;
_extOptions._showItemCosts = ConfMan.hasKey("ShowItemCosts") && ConfMan.getBool("ShowItemCosts");
+ _extOptions._durableArmor = ConfMan.hasKey("DurableArmor") && ConfMan.getBool("DurableArmor");
// If requested, load a savegame instead of showing the intro
if (ConfMan.hasKey("save_slot")) {
@@ -189,11 +193,12 @@ Common::Error XeenEngine::loadGameState(int slot) {
}
bool XeenEngine::canLoadGameStateCurrently() {
- return _mode != MODE_COMBAT && _mode != MODE_STARTUP;
+ return _mode != MODE_STARTUP;
}
bool XeenEngine::canSaveGameStateCurrently() {
- return _mode != MODE_COMBAT && _mode != MODE_STARTUP;
+ return _mode != MODE_COMBAT && _mode != MODE_STARTUP && _mode != MODE_SCRIPT_IN_PROGRESS
+ && (_map->mazeData()._mazeFlags & RESTRICTION_SAVE) == 0;
}
void XeenEngine::playGame() {
@@ -218,6 +223,7 @@ void XeenEngine::play() {
_party->_mazePosition.y = 21;
}
+ _map->clearMaze();
if (_loadSaveSlot >= 0) {
_saves->newGame();
_saves->loadGameState(_loadSaveSlot);
@@ -238,7 +244,7 @@ void XeenEngine::play() {
_combat->_moveMonsters = true;
if (_mode == MODE_STARTUP) {
- _mode = MODE_1;
+ _mode = MODE_INTERACTIVE;
_screen->fadeIn();
}
@@ -255,7 +261,7 @@ void XeenEngine::play() {
void XeenEngine::gameLoop() {
// Main game loop
- while (!shouldExit()) {
+ while (isLoadPending() || !shouldExit()) {
if (isLoadPending()) {
// Load any pending savegame
int saveSlot = _loadSaveSlot;
@@ -267,7 +273,9 @@ void XeenEngine::gameLoop() {
_map->cellFlagLookup(_party->_mazePosition);
if (_map->_currentIsEvent) {
_gameMode = (GameMode)_scripts->checkEvents();
- if (shouldExit() || _gameMode)
+ if (isLoadPending())
+ continue;
+ if (shouldExit())
return;
}
_party->giveTreasure();
diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h
index b6a95f0d43..a092538d09 100644
--- a/engines/xeen/xeen.h
+++ b/engines/xeen/xeen.h
@@ -39,6 +39,7 @@
#include "xeen/locations.h"
#include "xeen/map.h"
#include "xeen/party.h"
+#include "xeen/patcher.h"
#include "xeen/resources.h"
#include "xeen/saves.h"
#include "xeen/screen.h"
@@ -77,7 +78,7 @@ enum XeenDebugChannels {
enum Mode {
MODE_FF = -1,
MODE_STARTUP = 0,
- MODE_1 = 1,
+ MODE_INTERACTIVE = 1,
MODE_COMBAT = 2,
MODE_3 = 3,
MODE_4 = 4,
@@ -85,11 +86,11 @@ enum Mode {
MODE_6 = 6,
MODE_7 = 7,
MODE_8 = 8,
- MODE_RECORD_EVENTS = 9,
+ MODE_SCRIPT_IN_PROGRESS = 9,
MODE_CHARACTER_INFO = 10,
- MODE_12 = 12,
+ MODE_INTERACTIVE2 = 12,
MODE_DIALOG_123 = 13,
- MODE_17 = 17,
+ MODE_INTERACTIVE7 = 17,
MODE_86 = 86
};
@@ -111,8 +112,9 @@ class XeenEngine : public Engine {
*/
struct ExtendedOptions {
bool _showItemCosts;
+ bool _durableArmor;
- ExtendedOptions() : _showItemCosts(false) {}
+ ExtendedOptions() : _showItemCosts(false), _durableArmor(false) {}
};
private:
const XeenGameDescription *_gameDescription;
@@ -183,6 +185,7 @@ public:
LocationManager *_locations;
Map *_map;
Party *_party;
+ Patcher *_patcher;
Resources *_resources;
SavesManager *_saves;
Screen *_screen;
@@ -191,7 +194,6 @@ public:
Spells *_spells;
Windows *_windows;
Mode _mode;
- GameEvent _gameEvent;
GameMode _gameMode;
bool _noDirectionSense;
bool _startupWindowActive;
@@ -220,9 +222,9 @@ public:
void GUIError(const char *msg, ...) GCC_PRINTF(2, 3);
/**
- * Returns true if the game should be exited (and likely return to game menu)
+ * Returns true if the game should be exited (either quitting, exiting to the main menu, or loading a savegame)
*/
- bool shouldExit() const { return _gameMode != GMODE_NONE || shouldQuit(); }
+ bool shouldExit() const { return _gameMode != GMODE_NONE || isLoadPending() || shouldQuit(); }
/**
* Returns true if a savegame load is pending
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index 5e535a9954..896ea52344 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -178,7 +178,7 @@ SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, in
// We only use readSaveGameHeader() here, which doesn't need an engine callback
ZVision::SaveManager *zvisionSaveMan = new ZVision::SaveManager(NULL);
- bool successfulRead = zvisionSaveMan->readSaveGameHeader(in, header);
+ bool successfulRead = zvisionSaveMan->readSaveGameHeader(in, header, false);
delete zvisionSaveMan;
delete in;
diff --git a/engines/zvision/detection_tables.h b/engines/zvision/detection_tables.h
index 3df8f280ee..cb813e6d5b 100644
--- a/engines/zvision/detection_tables.h
+++ b/engines/zvision/detection_tables.h
@@ -49,7 +49,7 @@ static const ADExtraGuiOptionsMap optionsList[] = {
GAMEOPTION_ORIGINAL_SAVELOAD,
{
_s("Use original save/load screens"),
- _s("Use the original save/load screens instead of the ScummVM interface"),
+ _s("Use the original save/load screens instead of the ScummVM ones"),
"originalsaveload",
false
}
diff --git a/engines/zvision/file/save_manager.cpp b/engines/zvision/file/save_manager.cpp
index 4259937a3b..4676272146 100644
--- a/engines/zvision/file/save_manager.cpp
+++ b/engines/zvision/file/save_manager.cpp
@@ -162,8 +162,6 @@ Common::Error SaveManager::loadGame(int slot) {
scriptManager->deserialize(saveFile);
delete saveFile;
- if (header.thumbnail)
- delete header.thumbnail;
if (_engine->getGameId() == GID_NEMESIS && scriptManager->getCurrentLocation() == "tv2f") {
// WORKAROUND for script bug #6793: location tv2f (stairs) has two states:
@@ -189,17 +187,20 @@ Common::Error SaveManager::loadGame(int slot) {
return Common::kNoError;
}
-bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
+bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail) {
+ header.saveYear = 0;
+ header.saveMonth = 0;
+ header.saveDay = 0;
+ header.saveHour = 0;
+ header.saveMinutes = 0;
+ header.saveName.clear();
+ header.thumbnail = nullptr;
+ header.version = 0;
+
uint32 tag = in->readUint32BE();
// Check if it's original savegame than fill header structure
if (tag == MKTAG('Z', 'N', 'S', 'G')) {
- header.saveYear = 0;
- header.saveMonth = 0;
- header.saveDay = 0;
- header.saveHour = 0;
- header.saveMinutes = 0;
header.saveName = "Original Save";
- header.thumbnail = NULL;
header.version = SAVE_ORIGINAL;
in->seek(-4, SEEK_CUR);
return true;
@@ -226,15 +227,14 @@ bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &hea
}
// Read in the save name
- header.saveName.clear();
char ch;
while ((ch = (char)in->readByte()) != '\0')
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
diff --git a/engines/zvision/file/save_manager.h b/engines/zvision/file/save_manager.h
index 9e816373ea..94885b650b 100644
--- a/engines/zvision/file/save_manager.h
+++ b/engines/zvision/file/save_manager.h
@@ -94,7 +94,7 @@ public:
Common::Error loadGame(int slot);
Common::SeekableReadStream *getSlotFile(uint slot);
- bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header);
+ bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header, bool skipThumbnail = true);
void prepareSaveBuffer();
void flushSaveBuffer();
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp
index 73dc6309b2..e92a09f8c9 100644
--- a/graphics/VectorRenderer.cpp
+++ b/graphics/VectorRenderer.cpp
@@ -143,7 +143,7 @@ void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect &
break;
case Graphics::DrawStep::kVectorAlignCenter:
- in_y = area.top + (area.height() / 2) - (in_h / 2) + ((step.padding.top + step.padding.bottom ) / 2) ;
+ in_y = area.top + (area.height() / 2) - (in_h / 2) + ((step.padding.top + step.padding.bottom ) / 2);
break;
case Graphics::DrawStep::kVectorAlignTop:
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index 2b84c21894..2abe0e0759 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -437,7 +437,7 @@ public:
void drawCallback_ALPHABITMAP(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
- blitAlphaBitmap(step.blitAlphaSrc, Common::Rect(x, y, x + w, y + h), step.autoscale, step.xAlign, step.yAlign); //TODO
+ blitAlphaBitmap(step.blitAlphaSrc, Common::Rect(x, y, x + w, y + h), step.autoscale, step.xAlign, step.yAlign); // TODO
}
void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step, const Common::Rect &clip) {
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp
index c66bb2e9af..e308dde821 100644
--- a/graphics/VectorRendererSpec.cpp
+++ b/graphics/VectorRendererSpec.cpp
@@ -419,7 +419,7 @@ inline frac_t fp_sqroot(uint32 x) {
x--; px -= pitch; \
} \
a2 = (T >> 8); \
- a1 = ~a2; \
+ a1 = ~a2; \
} while (0)
@@ -2680,7 +2680,7 @@ drawTriangleVertAlg(int x1, int y1, int w, int h, bool inverted, PixelType color
int gradient = (dx << 8) / (dy + 0x100);
int interx = (x1 << 8) + gradient;
#else
- double gradient = dx / (dy+1);
+ double gradient = dx / (dy + 1);
double interx = x1 + gradient;
#endif
@@ -2846,7 +2846,7 @@ drawTriangleVertAlgClip(int x1, int y1, int w, int h, bool inverted, PixelType c
break;
case kFillForeground:
case kFillBackground:
- colorFillClip<PixelType>(ptr_right + 1, ptr_left, color, x_right+1, y_right, _clippingArea);
+ colorFillClip<PixelType>(ptr_right + 1, ptr_left, color, x_right + 1, y_right, _clippingArea);
blendPixelPtrClip(ptr_right, color, rfpart(intery), x_right, y_right);
blendPixelPtrClip(ptr_left, color, rfpart(intery), x_left, y_left);
break;
@@ -2905,7 +2905,7 @@ drawTriangleVertAlgClip(int x1, int y1, int w, int h, bool inverted, PixelType c
break;
case kFillForeground:
case kFillBackground:
- colorFillClip<PixelType>(ptr_right + 1, ptr_left, color, x_right+1, y_right, _clippingArea);
+ colorFillClip<PixelType>(ptr_right + 1, ptr_left, color, x_right + 1, y_right, _clippingArea);
blendPixelPtrClip(ptr_right, color, rfpart(interx), x_right, y_right);
blendPixelPtrClip(ptr_left, color, rfpart(interx), x_left, y_left);
break;
@@ -2953,7 +2953,7 @@ drawTriangleVertAlgClip(int x1, int y1, int w, int h, bool inverted, PixelType c
break;
case kFillForeground:
case kFillBackground:
- colorFillClip<PixelType>(ptr_right + 1, ptr_left, color, x_right+1, y_right, _clippingArea);
+ colorFillClip<PixelType>(ptr_right + 1, ptr_left, color, x_right + 1, y_right, _clippingArea);
blendPixelPtrClip(ptr_right, color, rfpart(interx), x_right, y_right);
blendPixelPtrClip(ptr_left, color, rfpart(interx), x_left, y_left);
break;
@@ -3061,10 +3061,10 @@ drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color,
BE_RESET();
r--;
- int alphaStep_tr = ((alpha_t - alpha_r)/(y+1));
- int alphaStep_br = ((alpha_r - alpha_b)/(y+1));
- int alphaStep_bl = ((alpha_b - alpha_l)/(y+1));
- int alphaStep_tl = ((alpha_l - alpha_t)/(y+1));
+ int alphaStep_tr = ((alpha_t - alpha_r) / (y + 1));
+ int alphaStep_br = ((alpha_r - alpha_b) / (y + 1));
+ int alphaStep_bl = ((alpha_b - alpha_l) / (y + 1));
+ int alphaStep_tl = ((alpha_l - alpha_t) / (y + 1));
// Avoid blending the last pixels twice, since we have an alpha
while (x++ < (y - 2)) {
@@ -3970,10 +3970,10 @@ drawBorderRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color,
px = pitch * x;
py = 0;
- int alphaStep_tr = ((alpha_t - alpha_r)/(x+1));
- int alphaStep_br = ((alpha_r - alpha_b)/(x+1));
- int alphaStep_bl = ((alpha_b - alpha_l)/(x+1));
- int alphaStep_tl = ((alpha_l - alpha_t)/(x+1));
+ int alphaStep_tr = ((alpha_t - alpha_r) / (x + 1));
+ int alphaStep_br = ((alpha_r - alpha_b) / (x + 1));
+ int alphaStep_bl = ((alpha_b - alpha_l) / (x + 1));
+ int alphaStep_tl = ((alpha_l - alpha_t) / (x + 1));
while (x > y++) {
WU_ALGORITHM();
diff --git a/graphics/fonts/bdf.h b/graphics/fonts/bdf.h
index d99b5fd401..c903d52c55 100644
--- a/graphics/fonts/bdf.h
+++ b/graphics/fonts/bdf.h
@@ -85,9 +85,9 @@ private:
};
#define DEFINE_FONT(n) \
- const BdfFont *n = 0; \
+ const BdfFont *n = 0; \
void create_##n() { \
- n = new BdfFont(desc, DisposeAfterUse::NO); \
+ n = new BdfFont(desc, DisposeAfterUse::NO); \
}
#define FORWARD_DECLARE_FONT(n) \
diff --git a/graphics/nine_patch.cpp b/graphics/nine_patch.cpp
index 56e1202be3..ce82fff61e 100644
--- a/graphics/nine_patch.cpp
+++ b/graphics/nine_patch.cpp
@@ -156,7 +156,7 @@ NinePatchBitmap::NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bi
bmp->format.colorToARGB(*(uint32 *)bmp->getBasePtr(x, y), a, r, g, b); \
if (a != 0 && r + g + b + a != 4) goto bad_bitmap;
- _check_pixel(0,0);
+ _check_pixel(0, 0);
_check_pixel(bmp->w - 1, 0);
_check_pixel(0, bmp->h - 1);
_check_pixel(bmp->w - 1, bmp->h - 1);
diff --git a/graphics/primitives.cpp b/graphics/primitives.cpp
index 8663a61606..76c44b650d 100644
--- a/graphics/primitives.cpp
+++ b/graphics/primitives.cpp
@@ -262,13 +262,13 @@ void drawRoundRect(Common::Rect &rect, int arc, int color, bool filled, void (*p
do {
if (filled) {
- drawHLine(rect.left+x+r, rect.right-x-r, rect.top-y+r-stop, color, plotProc, data);
- drawHLine(rect.left+x+r, rect.right-x-r, rect.bottom+y-r+stop, color, plotProc, data);
+ drawHLine(rect.left + x + r, rect.right - x - r, rect.top - y + r - stop, color, plotProc, data);
+ drawHLine(rect.left + x + r, rect.right - x - r, rect.bottom + y - r + stop, color, plotProc, data);
} else {
- (*plotProc)(rect.left+x+r, rect.top-y+r-stop, color, data);
- (*plotProc)(rect.right-x-r, rect.top-y+r-stop, color, data);
- (*plotProc)(rect.left+x+r, rect.bottom+y-r+stop, color, data);
- (*plotProc)(rect.right-x-r, rect.bottom+y-r+stop, color, data);
+ (*plotProc)(rect.left + x + r, rect.top - y + r - stop, color, data);
+ (*plotProc)(rect.right - x - r, rect.top - y + r - stop, color, data);
+ (*plotProc)(rect.left + x + r, rect.bottom + y - r + stop, color, data);
+ (*plotProc)(rect.right - x - r, rect.bottom + y - r + stop, color, data);
lastx = x;
lasty = y;
@@ -284,15 +284,15 @@ void drawRoundRect(Common::Rect &rect, int arc, int color, bool filled, void (*p
x = lastx;
y = lasty;
- drawHLine(rect.left+x+r, rect.right-x-r, rect.top-y+r-stop, color, plotProc, data);
- drawHLine(rect.left+x+r, rect.right-x-r, rect.bottom+y-r+stop, color, plotProc, data);
+ drawHLine(rect.left + x + r, rect.right - x - r, rect.top - y + r - stop, color, plotProc, data);
+ drawHLine(rect.left + x + r, rect.right - x - r, rect.bottom + y - r + stop, color, plotProc, data);
}
for (int i = 0; i < dy; i++) {
if (filled) {
drawHLine(rect.left, rect.right, rect.top + r + i, color, plotProc, data);
} else {
- (*plotProc)(rect.left, rect.top + r + i, color, data);
+ (*plotProc)(rect.left, rect.top + r + i, color, data);
(*plotProc)(rect.right, rect.top + r + i, color, data);
}
}
@@ -307,13 +307,13 @@ void drawRoundRect(Common::Rect &rect, int arc, int color, bool filled, void (*p
do {
if (filled) {
- drawVLine(rect.left-x+r-stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
- drawVLine(rect.right+x-r+stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
+ drawVLine(rect.left - x + r - stop, rect.top + y + r, rect.bottom - y - r, color, plotProc, data);
+ drawVLine(rect.right + x - r + stop, rect.top + y + r, rect.bottom - y - r, color, plotProc, data);
} else {
- (*plotProc)(rect.left-x+r-stop, rect.top+y+r, color, data);
- (*plotProc)(rect.left-x+r-stop, rect.bottom-y-r, color, data);
- (*plotProc)(rect.right+x-r+stop, rect.top+y+r, color, data);
- (*plotProc)(rect.right+x-r+stop, rect.bottom-y-r, color, data);
+ (*plotProc)(rect.left - x + r - stop, rect.top + y + r, color, data);
+ (*plotProc)(rect.left - x + r - stop, rect.bottom - y - r, color, data);
+ (*plotProc)(rect.right + x - r + stop, rect.top + y + r, color, data);
+ (*plotProc)(rect.right + x - r + stop, rect.bottom - y - r, color, data);
lastx = x;
lasty = y;
@@ -329,15 +329,15 @@ void drawRoundRect(Common::Rect &rect, int arc, int color, bool filled, void (*p
if (!filled) {
x = lastx;
y = lasty;
- drawVLine(rect.left-x+r-stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
- drawVLine(rect.right+x-r+stop, rect.top+y+r, rect.bottom-y-r, color, plotProc, data);
+ drawVLine(rect.left - x + r - stop, rect.top + y + r, rect.bottom - y - r, color, plotProc, data);
+ drawVLine(rect.right + x - r + stop, rect.top + y + r, rect.bottom - y - r, color, plotProc, data);
}
for (int i = 0; i < dx; i++) {
if (filled) {
drawVLine(rect.left + r + i, rect.top, rect.bottom, color, plotProc, data);
} else {
- (*plotProc)(rect.left + r + i, rect.top, color, data);
+ (*plotProc)(rect.left + r + i, rect.top, color, data);
(*plotProc)(rect.left + r + i, rect.bottom, color, data);
}
}
@@ -385,14 +385,14 @@ void drawPolygonScan(int *polyX, int *polyY, int npoints, Common::Rect &bbox, in
// http://members.chello.at/easyfilter/bresenham.html
void drawEllipse(int x0, int y0, int x1, int y1, int color, bool filled, void (*plotProc)(int, int, int, void *), void *data) {
- int a = abs(x1-x0), b = abs(y1-y0), b1 = b&1; /* values of diameter */
- long dx = 4*(1-a)*b*b, dy = 4*(b1+1)*a*a; /* error increment */
- long err = dx+dy+b1*a*a, e2; /* error of 1.step */
+ int a = abs(x1 - x0), b = abs(y1 - y0), b1 = b & 1; /* values of diameter */
+ long dx = 4 * (1 - a) * b * b, dy = 4 * (b1 + 1) * a * a; /* error increment */
+ long err = dx + dy + b1 * a * a, e2; /* error of 1.step */
if (x0 > x1) { x0 = x1; x1 += a; } /* if called with swapped points */
if (y0 > y1) y0 = y1; /* .. exchange them */
- y0 += (b+1)/2; y1 = y0-b1; /* starting pixel */
- a *= 8*a; b1 = 8*b*b;
+ y0 += (b + 1) / 2; y1 = y0 - b1; /* starting pixel */
+ a *= 8 * a; b1 = 8 * b * b;
do {
if (filled) {
@@ -411,15 +411,15 @@ void drawEllipse(int x0, int y0, int x1, int y1, int color, bool filled, void (*
while (y0-y1 < b) { /* too early stop of flat ellipses a=1 */
if (filled) {
- drawHLine(x0-1, x0-1, y0, color, plotProc, data); /* -> finish tip of ellipse */
- drawHLine(x1+1, x1+1, y0, color, plotProc, data);
- drawHLine(x0-1, x0-1, y1, color, plotProc, data);
- drawHLine(x1+1, x1+1, y1, color, plotProc, data);
+ drawHLine(x0 - 1, x0 - 1, y0, color, plotProc, data); /* -> finish tip of ellipse */
+ drawHLine(x1 + 1, x1 + 1, y0, color, plotProc, data);
+ drawHLine(x0 - 1, x0 - 1, y1, color, plotProc, data);
+ drawHLine(x1 + 1, x1 + 1, y1, color, plotProc, data);
} else {
- (*plotProc)(x0-1, y0, color, data); /* -> finish tip of ellipse */
- (*plotProc)(x1+1, y0, color, data);
- (*plotProc)(x0-1, y1, color, data);
- (*plotProc)(x1+1, y1, color, data);
+ (*plotProc)(x0 - 1, y0, color, data); /* -> finish tip of ellipse */
+ (*plotProc)(x1 + 1, y0, color, data);
+ (*plotProc)(x0 - 1, y1, color, data);
+ (*plotProc)(x1 + 1, y1, color, data);
}
y0++;
y1--;
diff --git a/graphics/scaler.cpp b/graphics/scaler.cpp
index 745988cbd9..a3ac7fc107 100644
--- a/graphics/scaler.cpp
+++ b/graphics/scaler.cpp
@@ -107,12 +107,12 @@ void InitLUT(Graphics::PixelFormat format) {
hqx_low2bits = (3 << format.rShift) | (3 << format.gShift) | (3 << format.bShift),
hqx_low3bits = (7 << format.rShift) | (7 << format.gShift) | (7 << format.bShift),
- hqx_highbits = format.RGBToColor(255,255,255) ^ hqx_lowbits;
+ hqx_highbits = format.RGBToColor(255, 255, 255) ^ hqx_lowbits;
// FIXME: The following code only does the right thing
// if the color order is RGB or BGR, i.e., green is in the middle.
- hqx_greenMask = format.RGBToColor(0,255,0);
- hqx_redBlueMask = format.RGBToColor(255,0,255);
+ hqx_greenMask = format.RGBToColor( 0, 255, 0);
+ hqx_redBlueMask = format.RGBToColor(255, 0, 255);
hqx_green_redBlue_Mask = (hqx_greenMask << 16) | hqx_redBlueMask;
#endif
@@ -145,10 +145,10 @@ void InitScalers(uint32 BitFormat) {
#endif
// Build dotmatrix lookup table for the DotMatrix scaler.
- g_dotmatrix[0] = g_dotmatrix[10] = format.RGBToColor(0, 63, 0);
- g_dotmatrix[1] = g_dotmatrix[11] = format.RGBToColor(0, 0, 63);
- g_dotmatrix[2] = g_dotmatrix[8] = format.RGBToColor(63, 0, 0);
- g_dotmatrix[4] = g_dotmatrix[6] =
+ g_dotmatrix[0] = g_dotmatrix[10] = format.RGBToColor( 0, 63, 0);
+ g_dotmatrix[1] = g_dotmatrix[11] = format.RGBToColor( 0, 0, 63);
+ g_dotmatrix[2] = g_dotmatrix[ 8] = format.RGBToColor(63, 0, 0);
+ g_dotmatrix[4] = g_dotmatrix[ 6] =
g_dotmatrix[12] = g_dotmatrix[14] = format.RGBToColor(63, 63, 63);
}
diff --git a/graphics/scaler/intern.h b/graphics/scaler/intern.h
index eddc3c7f3d..213b69b049 100644
--- a/graphics/scaler/intern.h
+++ b/graphics/scaler/intern.h
@@ -195,18 +195,18 @@ static inline bool diffYUV(int yuv1, int yuv2) {
int mask;
diff = ((yuv1 & Umask) - (yuv2 & Umask));
- mask = diff >> 31; // -1 if value < 0, 0 otherwise
- diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value
+ mask = diff >> 31; // -1 if value < 0, 0 otherwise
+ diff = (diff ^ mask) - mask; // -1: ~value + 1; 0: value
if (diff > trU) return true;
diff = ((yuv1 & Vmask) - (yuv2 & Vmask));
- mask = diff >> 31; // -1 if value < 0, 0 otherwise
- diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value
+ mask = diff >> 31; // -1 if value < 0, 0 otherwise
+ diff = (diff ^ mask) - mask; // -1: ~value + 1; 0: value
if (diff > trV) return true;
diff = ((yuv1 & Ymask) - (yuv2 & Ymask));
- mask = diff >> 31; // -1 if value < 0, 0 otherwise
- diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value
+ mask = diff >> 31; // -1 if value < 0, 0 otherwise
+ diff = (diff ^ mask) - mask; // -1: ~value + 1; 0: value
if (diff > trY) return true;
return false;
diff --git a/graphics/scaler/scalebit.cpp b/graphics/scaler/scalebit.cpp
index c8b54f4b25..bcba5793e2 100644
--- a/graphics/scaler/scalebit.cpp
+++ b/graphics/scaler/scalebit.cpp
@@ -47,17 +47,17 @@
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row) {
switch (pixel) {
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
- case 1 : scale2x_8_mmx(DST(8,0), DST(8,1), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
- case 2 : scale2x_16_mmx(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
- case 4 : scale2x_32_mmx(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
+ case 1: scale2x_8_mmx( DST( 8,0), DST( 8,1), SRC( 8,0), SRC( 8,1), SRC( 8,2), pixel_per_row); break;
+ case 2: scale2x_16_mmx(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
+ case 4: scale2x_32_mmx(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
#elif defined(USE_ARM_SCALER_ASM)
- case 1 : scale2x_8_arm(DST(8,0), DST(8,1), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
- case 2 : scale2x_16_arm(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
- case 4 : scale2x_32_arm(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
+ case 1: scale2x_8_arm( DST( 8,0), DST( 8,1), SRC( 8,0), SRC( 8,1), SRC( 8,2), pixel_per_row); break;
+ case 2: scale2x_16_arm(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
+ case 4: scale2x_32_arm(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
#else
- case 1 : scale2x_8_def(DST(8,0), DST(8,1), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
- case 2 : scale2x_16_def(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
- case 4 : scale2x_32_def(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
+ case 1: scale2x_8_def( DST( 8,0), DST( 8,1), SRC( 8,0), SRC( 8,1), SRC( 8,2), pixel_per_row); break;
+ case 2: scale2x_16_def(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
+ case 4: scale2x_32_def(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
#endif
}
}
@@ -67,9 +67,9 @@ static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const
*/
static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row) {
switch (pixel) {
- case 1 : scale3x_8_def(DST(8,0), DST(8,1), DST(8,2), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
- case 2 : scale3x_16_def(DST(16,0), DST(16,1), DST(16,2), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
- case 4 : scale3x_32_def(DST(32,0), DST(32,1), DST(32,2), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
+ case 1: scale3x_8_def( DST( 8,0), DST( 8,1), DST( 8,2), SRC( 8,0), SRC( 8,1), SRC( 8,2), pixel_per_row); break;
+ case 2: scale3x_16_def(DST(16,0), DST(16,1), DST(16,2), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
+ case 4: scale3x_32_def(DST(32,0), DST(32,1), DST(32,2), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
}
}
@@ -281,12 +281,12 @@ int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned
return -1;
switch (scale) {
- case 2 :
- case 3 :
+ case 2:
+ case 3:
if (height < 2)
return -1;
break;
- case 4 :
+ case 4:
if (height < 4)
return -1;
break;
@@ -294,14 +294,14 @@ int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
switch (scale) {
- case 2 :
- case 4 :
+ case 2:
+ case 4:
if (width < (16 / pixel))
return -1;
if (width % (8 / pixel) != 0)
return -1;
break;
- case 3 :
+ case 3:
if (width < 2)
return -1;
break;
@@ -329,13 +329,13 @@ int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
switch (scale) {
- case 2 :
+ case 2:
scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
break;
- case 3 :
+ case 3:
scale3x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
break;
- case 4 :
+ case 4:
scale4x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
break;
}
diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp
index 45cf1cee90..877f314c69 100644
--- a/graphics/sjis.cpp
+++ b/graphics/sjis.cpp
@@ -334,16 +334,16 @@ const uint8 *FontTowns::getCharData(uint16 ch) const {
if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI;
if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) {
- c = 48; //correction
- p = -8; //correction
+ c = 48; // correction
+ p = -8; // correction
}
- if (kanjiType == KANA) {//Kana
+ if (kanjiType == KANA) {
chunk_f = (f - 0x81) * 2;
- } else if (kanjiType == KANJI) {//Standard Kanji
+ } else if (kanjiType == KANJI) { // Standard Kanji
p += f - 0x88;
chunk_f = c + 2 * p;
- } else if (kanjiType == EKANJI) {//Enhanced Kanji
+ } else if (kanjiType == EKANJI) { // Enhanced Kanji
p += f - 0xe0;
chunk_f = c + 2 * p;
}
@@ -360,37 +360,37 @@ const uint8 *FontTowns::getCharData(uint16 ch) const {
switch (base) {
case 0x3f:
- cr = 0; //3f
+ cr = 0; // 3f
if (kanjiType == KANA) chunk = 1;
else if (kanjiType == KANJI) chunk = 31;
else if (kanjiType == EKANJI) chunk = 111;
break;
case 0x5f:
- cr = 0; //5f
+ cr = 0; // 5f
if (kanjiType == KANA) chunk = 17;
else if (kanjiType == KANJI) chunk = 47;
else if (kanjiType == EKANJI) chunk = 127;
break;
case 0x7f:
- cr = -1; //80
+ cr = -1; // 80
if (kanjiType == KANA) chunk = 9;
else if (kanjiType == KANJI) chunk = 63;
else if (kanjiType == EKANJI) chunk = 143;
break;
case 0x9f:
- cr = 1; //9e
+ cr = 1; // 9e
if (kanjiType == KANA) chunk = 2;
else if (kanjiType == KANJI) chunk = 32;
else if (kanjiType == EKANJI) chunk = 112;
break;
case 0xbf:
- cr = 1; //be
+ cr = 1; // be
if (kanjiType == KANA) chunk = 18;
else if (kanjiType == KANJI) chunk = 48;
else if (kanjiType == EKANJI) chunk = 128;
break;
case 0xdf:
- cr = 1; //de
+ cr = 1; // de
if (kanjiType == KANA) chunk = 10;
else if (kanjiType == KANJI) chunk = 64;
else if (kanjiType == EKANJI) chunk = 144;
diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp
index a3037e5ad5..72a06f91ec 100644
--- a/graphics/thumbnail.cpp
+++ b/graphics/thumbnail.cpp
@@ -147,7 +147,11 @@ bool skipThumbnail(Common::SeekableReadStream &in) {
return true;
}
-Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
+bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail) {
+ if (skipThumbnail) {
+ return Graphics::skipThumbnail(in);
+ }
+
const uint32 position = in.pos();
ThumbnailHeader header;
HeaderState headerState = loadHeader(in, header, true);
@@ -160,32 +164,32 @@ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
// stream at this point then.
if (headerState == kHeaderNone) {
in.seek(position, SEEK_SET);
- return 0;
+ return false;
} else if (headerState == kHeaderUnsupported) {
in.seek(header.size - (in.pos() - position), SEEK_CUR);
- return 0;
+ return false;
}
if (header.format.bytesPerPixel != 2 && header.format.bytesPerPixel != 4) {
warning("trying to load thumbnail with unsupported bit depth %d", header.format.bytesPerPixel);
- return 0;
+ return false;
}
- Graphics::Surface *const to = new Graphics::Surface();
- to->create(header.width, header.height, header.format);
+ thumbnail = new Graphics::Surface();
+ thumbnail->create(header.width, header.height, header.format);
- for (int y = 0; y < to->h; ++y) {
+ for (int y = 0; y < thumbnail->h; ++y) {
switch (header.format.bytesPerPixel) {
case 2: {
- uint16 *pixels = (uint16 *)to->getBasePtr(0, y);
- for (uint x = 0; x < to->w; ++x) {
+ uint16 *pixels = (uint16 *)thumbnail->getBasePtr(0, y);
+ for (uint x = 0; x < thumbnail->w; ++x) {
*pixels++ = in.readUint16BE();
}
} break;
case 4: {
- uint32 *pixels = (uint32 *)to->getBasePtr(0, y);
- for (uint x = 0; x < to->w; ++x) {
+ uint32 *pixels = (uint32 *)thumbnail->getBasePtr(0, y);
+ for (uint x = 0; x < thumbnail->w; ++x) {
*pixels++ = in.readUint32BE();
}
} break;
@@ -194,7 +198,7 @@ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
assert(0);
}
}
- return to;
+ return true;
}
bool saveThumbnail(Common::WriteStream &out) {
diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h
index cec3d02800..17ce856e23 100644
--- a/graphics/thumbnail.h
+++ b/graphics/thumbnail.h
@@ -52,7 +52,7 @@ bool skipThumbnail(Common::SeekableReadStream &in);
/**
* Loads a thumbnail from the given input stream.
*/
-Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in);
+bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail = false);
/**
* Saves a thumbnail to the given write stream.
diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp
index 5650fd8e94..b01e4950d5 100644
--- a/gui/predictivedialog.cpp
+++ b/gui/predictivedialog.cpp
@@ -35,7 +35,7 @@
#include "common/file.h"
#include "common/savefile.h"
-#ifdef __DS__
+#if defined(__DS__) && defined(ENABLE_AGI)
#include "backends/platform/ds/arm9/source/wordcompletion.h"
#endif
@@ -945,7 +945,7 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict
while ((ptr = strchr(ptr, '\n'))) {
*ptr = 0;
ptr++;
-#ifdef __DS__
+#if defined(__DS__) && defined(ENABLE_AGI)
// Pass the line on to the DS word list
DS::addAutoCompleteLine(dict.dictLine[i - 1]);
#endif
@@ -960,7 +960,7 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict
// FIXME: We use binary search on _predictiveDict.dictLine, yet we make no at_tempt
// to ever sort this array (except for the DS port). That seems risky, doesn't it?
-#ifdef __DS__
+#if defined(__DS__) && defined(ENABLE_AGI)
// Sort the DS word completion list, to allow for a binary chop later (in the ds backend)
DS::sortAutoCompleteWordList();
#endif
diff --git a/gui/themes/translations.dat b/gui/themes/translations.dat
index abedbc75f1..99130dd147 100644
--- a/gui/themes/translations.dat
+++ b/gui/themes/translations.dat
Binary files differ
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index f356e87971..1c477c82d5 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -405,8 +405,13 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
_curFrame.height = stream.readUint16BE();
_curFrame.stripCount = stream.readUint16BE();
- if (!_curFrame.strips)
+ if (!_curFrame.strips) {
_curFrame.strips = new CinepakStrip[_curFrame.stripCount];
+ for (uint16 i = 0; i < _curFrame.stripCount; i++) {
+ initializeCodebook(i, 1);
+ initializeCodebook(i, 4);
+ }
+ }
debug(4, "Cinepak Frame: Width = %d, Height = %d, Strip Count = %d", _curFrame.width, _curFrame.height, _curFrame.stripCount);
@@ -499,6 +504,19 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
return _curFrame.surface;
}
+void CinepakDecoder::initializeCodebook(uint16 strip, byte codebookType) {
+ CinepakCodebook *codebook = (codebookType == 1) ? _curFrame.strips[strip].v1_codebook : _curFrame.strips[strip].v4_codebook;
+
+ for (uint16 i = 0; i < 256; i++) {
+ memset(codebook[i].y, 0, 4);
+ codebook[i].u = 0;
+ codebook[i].v = 0;
+
+ if (_ditherType == kDitherTypeQT)
+ ditherCodebookQT(strip, codebookType, i);
+ }
+}
+
void CinepakDecoder::loadCodebook(Common::SeekableReadStream &stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize) {
CinepakCodebook *codebook = (codebookType == 1) ? _curFrame.strips[strip].v1_codebook : _curFrame.strips[strip].v4_codebook;
diff --git a/image/codecs/cinepak.h b/image/codecs/cinepak.h
index 4efb1191cc..3b0fe477a6 100644
--- a/image/codecs/cinepak.h
+++ b/image/codecs/cinepak.h
@@ -94,6 +94,7 @@ private:
byte *_colorMap;
DitherType _ditherType;
+ void initializeCodebook(uint16 strip, byte codebookType);
void loadCodebook(Common::SeekableReadStream &stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize);
void decodeVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
diff --git a/image/codecs/indeo/indeo.cpp b/image/codecs/indeo/indeo.cpp
index 4826137358..80b424fb90 100644
--- a/image/codecs/indeo/indeo.cpp
+++ b/image/codecs/indeo/indeo.cpp
@@ -465,22 +465,26 @@ IVI45DecContext::IVI45DecContext() : _gb(nullptr), _frameNum(0), _frameType(0),
/*------------------------------------------------------------------------*/
IndeoDecoderBase::IndeoDecoderBase(uint16 width, uint16 height, uint bitsPerPixel) : Codec() {
- switch (bitsPerPixel) {
- case 15:
- _pixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0);
- break;
- case 16:
- _pixelFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
- break;
- case 24:
- _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0);
- break;
- case 32:
- _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
- break;
- default:
- error("Invalid color depth");
- break;
+ _pixelFormat = g_system->getScreenFormat();
+
+ if (_pixelFormat.bytesPerPixel == 1) {
+ switch (bitsPerPixel) {
+ case 15:
+ _pixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0);
+ break;
+ case 16:
+ _pixelFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+ break;
+ case 24:
+ _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0);
+ break;
+ case 32:
+ _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+ break;
+ default:
+ error("Invalid color depth");
+ break;
+ }
}
_surface.create(width, height, _pixelFormat);
diff --git a/image/codecs/indeo3.cpp b/image/codecs/indeo3.cpp
index 1aa1ef73b6..2b681c98ce 100644
--- a/image/codecs/indeo3.cpp
+++ b/image/codecs/indeo3.cpp
@@ -44,22 +44,26 @@ Indeo3Decoder::Indeo3Decoder(uint16 width, uint16 height, uint bitsPerPixel) : _
_iv_frame[0].the_buf = 0;
_iv_frame[1].the_buf = 0;
- switch (bitsPerPixel) {
- case 15:
- _pixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0);
- break;
- case 16:
- _pixelFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
- break;
- case 24:
- _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0);
- break;
- case 32:
- _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
- break;
- default:
- error("Invalid color depth");
- break;
+ _pixelFormat = g_system->getScreenFormat();
+
+ if (_pixelFormat.bytesPerPixel == 1) {
+ switch (bitsPerPixel) {
+ case 15:
+ _pixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 0, 5, 10, 0);
+ break;
+ case 16:
+ _pixelFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+ break;
+ case 24:
+ _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0);
+ break;
+ case 32:
+ _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+ break;
+ default:
+ error("Invalid color depth");
+ break;
+ }
}
_surface = new Graphics::Surface;
diff --git a/po/be_BY.po b/po/be_BY.po
index 2e97526e6b..4fe66e572b 100644
--- a/po/be_BY.po
+++ b/po/be_BY.po
@@ -6,9 +6,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.8.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-11-28 19:36+0300\n"
-"Last-Translator: Ivan Lukyanov <greencis@mail.ru>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:07+0000\n"
+"Last-Translator: Adrian Fruehwirth <bonki@scummvm.org>\n"
"Language-Team: Belarusian <https://translations.scummvm.org/projects/scummvm/"
"scummvm/be/>\n"
"Language: be_BY\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Poedit 2.0.4\n"
+"X-Generator: Weblate 2.9\n"
"X-Language-name: Belarusian\n"
#: gui/about.cpp:94
@@ -168,7 +168,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1836,7 +1836,7 @@ msgstr "Г~а~лоўнае меню"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1857,7 +1857,7 @@ msgstr "Захаваць гульню:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1980,18 +1980,26 @@ msgstr "Усё адно запусціць"
msgid "AdLib Emulator"
msgstr "Эмулятар AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Эмулятар MAME OPL"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Эмулятар DOSBox OPL"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Эмулятар Nuked OPL"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "Прамы FM ALSA"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr ""
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2785,7 +2793,7 @@ msgstr "Правяраю абнаўленні..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2793,7 +2801,7 @@ msgstr "Не атрымалася знайсці файл рухавічка %s."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2838,6 +2846,7 @@ msgstr "Выкарыстоўваць арыгінальныя экраны запісу/чытання гульні"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Выкарыстоўваць арыгінальныя экраны чытання/захавання гульні замест ScummVM"
@@ -2890,7 +2899,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2904,7 +2913,7 @@ msgstr "Узнавіць гульню:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4469,14 +4478,14 @@ msgstr "Уступ з дыскет"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Выкарыстоўваць уступ з гнуткіх дыскаў (толькі для CD-версіі гульні)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, fuzzy, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
"Няправільная версія файла рухавічка %s. Чакалася %d.%d, але знойдзена %d.%d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, fuzzy, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "Не атрымалася знайсці файл рухавічка %s."
@@ -4616,21 +4625,23 @@ msgstr "Білінейная фільтрацыя спрайтаў (марудна)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Ужываць білінейную фільтрацыю для індывідуальных спрайтаў"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Выкарыстоўваць арыгінальныя экраны запісу і захавання гульні замест "
-"зробленых у ScummVM"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4666,7 +4677,7 @@ msgstr ""
"Выкарыстоўваць відэа MPEG з DVD-версіі замест відэа нізкага адрознення ў "
"фармаце AVI"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4675,6 +4686,11 @@ msgstr ""
"Гэты файл захаванай гульні мае версію %u, але рухавічок падтрымвае версіі да "
"%d. Вам патрэбна новая версія ScummVM для карыстання гэтым файлам."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Выкарыстоўваць арыгінальныя экраны запісу і захавання гульні замест "
+#~ "зробленых у ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(Вы заўсёды можаце ўключыць яе ў наладах на закладцы \"Рознае\")"
diff --git a/po/ca_ES.po b/po/ca_ES.po
index f17e1ffcef..0dd30e7abe 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.6.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-02-20 14:15+0000\n"
-"Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:09+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Catalan <https://translations.scummvm.org/projects/scummvm/"
"scummvm/ca/>\n"
"Language: ca_ES\n"
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "D'acord"
@@ -1832,7 +1832,7 @@ msgstr "~R~etorna al Llanчador"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1853,7 +1853,7 @@ msgstr "Desa la partida:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1974,18 +1974,26 @@ msgstr "Inicia de totes maneres"
msgid "AdLib Emulator"
msgstr "Emulador d'AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Emulador OPL de MAME"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Emulador OPL de DOSBox"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Emulador OPL de Nuked"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr ""
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2774,7 +2782,7 @@ msgstr "Comprova les actualitzacions..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2782,7 +2790,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2827,6 +2835,7 @@ msgstr "Utilitza les pantalles originals de desat/cрrrega"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
#, fuzzy
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
@@ -2874,7 +2883,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2888,7 +2897,7 @@ msgstr "Recupera la partida:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4419,13 +4428,13 @@ msgid "Use the floppy version's intro (CD version only)"
msgstr ""
"Utilitza la introducciѓ de la versiѓ de disquets (nomщs per a la versiѓ CD)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4571,21 +4580,23 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-#, fuzzy
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Utilitza les pantalles originals de desat/cрrrega, en lloc de les de ScummVM"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4624,13 +4635,19 @@ msgstr ""
"Utilitza el conjunt alternatiu de cursors platejats, en lloc dels normals "
"daurats"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
"%d. You will need an updated version of the engine to use this saved game."
msgstr ""
+#, fuzzy
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Utilitza les pantalles originals de desat/cрrrega, en lloc de les de "
+#~ "ScummVM"
+
#~ msgid "Check for updates automatically"
#~ msgstr "Comprova les actualitzacions automрticament"
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index d84a3f6c13..c5e517ff40 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.7.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-11-29 07:42+0000\n"
-"Last-Translator: Zbynьk Schwarz <zbynek.schwarz@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:09+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Czech <https://translations.scummvm.org/projects/scummvm/"
"scummvm/cs/>\n"
"Language: cs_CZ\n"
@@ -171,7 +171,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1840,7 +1840,7 @@ msgstr "~N~сvrat do SpouЙtьшe"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1861,7 +1861,7 @@ msgstr "UloОit hru:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1983,18 +1983,26 @@ msgstr "Pјesto spustit"
msgid "AdLib Emulator"
msgstr "AdLib Emulсtor"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL Emulсtor"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL Emulсtor"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL Emulсtor"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Pјэmс FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2789,7 +2797,7 @@ msgstr "Zkontrolovat Aktualizace..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2797,7 +2805,7 @@ msgstr "Nelze najэt datovщ soubory jсdra '%s'."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2842,6 +2850,7 @@ msgstr "PouОэt pљvodnэ obrazovky naшtenэ/uloОenэ"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr "PouОэt pљvodnэ obrazovky naшtenэ/uloОenэ mэsto ze ScummVM"
@@ -2891,7 +2900,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2905,7 +2914,7 @@ msgstr "Obnovit hru:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4462,14 +4471,14 @@ msgstr "кvod z diskety"
msgid "Use the floppy version's intro (CD version only)"
msgstr "PouОэt verzi њvodu z diskety (Pouze verze CD)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, fuzzy, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
"Nalezena data jсdra '%s' s nesprсvnou verzэ. Oшekсvсna %d.%d, ale byla %d.%d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, fuzzy, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "Nelze najэt datovщ soubory jсdra '%s'."
@@ -4603,19 +4612,23 @@ msgstr "Bilineсrnэ filtrovсnэ spritљ (POMALЩ)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "U kaОdщho spritu pouОэt bilineсrnэ filtrovсnэ"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
-msgstr "PouОэt pљvodnэ obrazovky naшtenэ/uloОenэ mэsto rozhranэ ScummVM"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
+msgstr ""
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4651,7 +4664,7 @@ msgstr ""
"PouОэt video MPEG pochсzejэcэ z DVD verze namэsto videa AVI v nэzkщm "
"rozliЙenэ"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4660,6 +4673,9 @@ msgstr ""
"Tato uloОenс hra je z verze %u, ale nejvyЙЙэ verze, kterщ toto jсdro "
"podporuje, je %d. Abyste tuto hru naшetli, musэte zэskat novьjЙэ verzi jсdra."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr "PouОэt pљvodnэ obrazovky naшtenэ/uloОenэ mэsto rozhranэ ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(Toto nastavenэ vОdy mљОete zmьnit ve Volbсch v kartь Rљznщ)"
diff --git a/po/da_DK.po b/po/da_DK.po
index 46897d09be..e2f6fe2d0c 100644
--- a/po/da_DK.po
+++ b/po/da_DK.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-12-07 19:59+0000\n"
-"Last-Translator: stevenew <steffen@nyeland.dk>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:10+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Danish <https://translations.scummvm.org/projects/scummvm/"
"scummvm/da/>\n"
"Language: da_DK\n"
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1834,7 +1834,7 @@ msgstr "~R~etur til oversigt"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1855,7 +1855,7 @@ msgstr "Gemmer:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1977,18 +1977,26 @@ msgstr "Start alligevel"
msgid "AdLib Emulator"
msgstr "AdLib emulator"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL emulator"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulator"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL emulator"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2781,7 +2789,7 @@ msgstr "Sјg efter opdateringer..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2789,7 +2797,7 @@ msgstr "Kan ikke finde '%s' \"motorens\" data fil."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2835,6 +2843,7 @@ msgstr "Brug original gem/indlцs skцrme"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr "Brug de originale gem/indlцs skцrme, istedet for dem fra ScummVM"
@@ -2884,7 +2893,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2898,7 +2907,7 @@ msgstr "Gendan spil:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4465,7 +4474,7 @@ msgstr "Diskette intro"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Brug diskette versionens intro (kun CD version)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, fuzzy, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4473,7 +4482,7 @@ msgstr ""
"Ukorrekt version af '%s' \"motorens\" data fil fundet. Forventet %d.%d, men "
"fandt %d.%d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, fuzzy, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "Kan ikke finde '%s' \"motorens\" data fil."
@@ -4610,21 +4619,23 @@ msgstr "Sprite bilineцr filtrering (langsom)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Anvend bilinцr filtrering til individuelle sprites"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Brug de originale gem/indlцs skцrme, i stedet for dem fra ScummVM "
-"brugerfladen"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4658,7 +4669,7 @@ msgstr "Brug hјj oplјsning MPEG-video"
msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr "Brug MPEG-video fra DVD-versionen, i stedet for lavere oplјsning AVI"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4668,6 +4679,11 @@ msgstr ""
"til version %d. Du skal bruge en opdateret version af \"motoren\" for at "
"bruge dette gemte spil."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Brug de originale gem/indlцs skцrme, i stedet for dem fra ScummVM "
+#~ "brugerfladen"
+
#, fuzzy
#~ msgid "Check for updates automatically"
#~ msgstr "Sјg efter opdateringer..."
diff --git a/po/de_DE.po b/po/de_DE.po
index 2ba225f2f0..3c7d9a11c1 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -7,11 +7,11 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.10.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2018-03-31 07:48+0000\n"
-"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
-"Language-Team: German "
-"<https://translations.scummvm.org/projects/scummvm/scummvm/de/>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-16 22:20+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
+"Language-Team: German <https://translations.scummvm.org/projects/scummvm/"
+"scummvm/de/>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
@@ -114,8 +114,8 @@ msgid ""
"It looks like your connection is limited. Do you really want to download "
"files with it?"
msgstr ""
-"Ihre Internetverbindung ist scheinbar eingeschrфnkt. Mіchten Sie mit dieser "
-"Verbindung wirklich die Dateien herunterladen?"
+"Ihre Internetverbindung ist scheinbar eingeschrфnkt. Mіchten Sie die Dateien "
+"wirklich ќber diese Verbindung herunterladen?"
#: gui/downloaddialog.cpp:119 gui/downloaddialog.cpp:153
#: gui/filebrowser-dialog.cpp:133 gui/fluidsynth-dialog.cpp:218
@@ -172,7 +172,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -201,7 +201,7 @@ msgstr "Spiel"
#: gui/editgamedialog.cpp:137
msgid "ID:"
-msgstr "Kennung:"
+msgstr "ID:"
#: gui/editgamedialog.cpp:137 gui/editgamedialog.cpp:139
#: gui/editgamedialog.cpp:140
@@ -209,13 +209,13 @@ msgid ""
"Short game identifier used for referring to saved games and running the game "
"from the command line"
msgstr ""
-"Kurzer Spielname, um die Spielstфnde zuzuordnen und das Spiel von der "
+"Kurzer Spielname, um Spielstфnde zuzuordnen und das Spiel von der "
"Kommandozeile aus starten zu kіnnen"
#: gui/editgamedialog.cpp:139
msgctxt "lowres"
msgid "ID:"
-msgstr "Kennung:"
+msgstr "ID:"
#: gui/editgamedialog.cpp:144 gui/editrecorddialog.cpp:59
msgid "Name:"
@@ -224,7 +224,7 @@ msgstr "Name:"
#: gui/editgamedialog.cpp:144 gui/editgamedialog.cpp:146
#: gui/editgamedialog.cpp:147
msgid "Full title of the game"
-msgstr "Voller Name des Spiels"
+msgstr "Vollstфndiger Name des Spiels"
#: gui/editgamedialog.cpp:146
msgctxt "lowres"
@@ -422,12 +422,12 @@ msgid ""
"want your saved games to sync, use default directory."
msgstr ""
"Spielstand-Synchronisierung funktioniert nicht mit anderen Verzeichnissen. "
-"Wenn SieIhre Spielstфnde synchronisieren mіchten, verwenden Sie das Standard-"
-"Verzeichnis."
+"Wenn Sie Ihre Spielstфnde synchronisieren mіchten, verwenden Sie das "
+"Standard-Verzeichnis."
#: gui/editgamedialog.cpp:535
msgid "This game ID is already taken. Please choose another one."
-msgstr "Diese Spielkennung ist schon vergeben. Bitte eine andere wфhlen."
+msgstr "Diese Spiel-ID ist bereits vergeben. Bitte eine andere wфhlen."
#: gui/editrecorddialog.cpp:58
msgid "Author:"
@@ -479,7 +479,7 @@ msgstr "Intensitфt:"
#: gui/fluidsynth-dialog.cpp:101
msgid "Chorus"
-msgstr "Chor"
+msgstr "Chorus"
#: gui/fluidsynth-dialog.cpp:105
msgid "N:"
@@ -731,7 +731,7 @@ msgstr ""
#: gui/launcher.cpp:530
msgid "ScummVM could not find any engine capable of running the selected game!"
-msgstr "ScummVM konnte keine Engine finden, um das Spiel zu starten!"
+msgstr "ScummVM konnte keine passende Engine fќr dieses Spiel finden!"
#: gui/launcher.cpp:581
msgid "ScummVM could not find any game in the specified directory!"
@@ -852,7 +852,7 @@ msgstr "Zeiger-Geschw.:"
#: gui/options.cpp:943 gui/options.cpp:945 gui/options.cpp:946
msgid "Speed for keyboard/joystick mouse pointer control"
-msgstr "Zeiger-Geschwindigkeit der Tastatur-/Joystick-Maus"
+msgstr "Zeiger-Geschwindigkeit der Tastatur- bzw. Joystick-Maus"
#: gui/options.cpp:945
msgctxt "lowres"
@@ -900,7 +900,7 @@ msgstr "Render-Modus:"
#: gui/options.cpp:1006 gui/options.cpp:1007
msgid "Special dithering modes supported by some games"
-msgstr "Spezielle Farbmischungsmethoden werden von manchen Spielen unterstќtzt"
+msgstr "Spezielle Dithering-Methoden unterstќtzt von manchen Spielen"
#: gui/options.cpp:1018 backends/graphics/openglsdl/openglsdl-graphics.cpp:588
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2590
@@ -934,7 +934,7 @@ msgstr "Musikgerфt:"
#: gui/options.cpp:1032 gui/options.cpp:1034
msgid "Specifies preferred sound device or sound card emulator"
msgstr ""
-"Legt das bevorzugte Tonwiedergabe-Gerфt oder den Soundkarten-Emulator fest"
+"Legt das bevorzugte Audio-Wiedergabegerфt oder den Soundkarten-Emulator fest"
#: gui/options.cpp:1032 gui/options.cpp:1034 gui/options.cpp:1035
msgid "Specifies output sound device or sound card emulator"
@@ -1008,8 +1008,8 @@ msgstr "MT-32-Gerфt:"
#: gui/options.cpp:1130
msgid "Specifies default sound device for Roland MT-32/LAPC1/CM32l/CM64 output"
msgstr ""
-"Legt das standardmфпige Tonwiedergabe-Gerфt fќr die Ausgabe von Roland MT-32/"
-"LAPC1/CM32l/CM64 fest"
+"Legt das standardmфпige Audio-Wiedergabegerфt fќr die Ausgabe von Roland "
+"MT-32/LAPC1/CM32l/CM64 fest"
#: gui/options.cpp:1135
msgid "True Roland MT-32 (disable GM emulation)"
@@ -1140,12 +1140,12 @@ msgstr "FluidSynth-Einstellungen"
#: gui/options.cpp:1505
msgid "Theme Path:"
-msgstr "Themen:"
+msgstr "Themes:"
#: gui/options.cpp:1507
msgctxt "lowres"
msgid "Theme Path:"
-msgstr "Themen:"
+msgstr "Themes:"
#: gui/options.cpp:1513 gui/options.cpp:1515 gui/options.cpp:1516
msgid "Specifies path to additional data used by all games or ScummVM"
@@ -1169,7 +1169,7 @@ msgstr "Andere"
#: gui/options.cpp:1537
msgid "Theme:"
-msgstr "Design:"
+msgstr "Theme:"
#: gui/options.cpp:1541
msgid "GUI Renderer:"
@@ -1244,7 +1244,7 @@ msgstr "Belegter Speicher:"
#: gui/options.cpp:1639
msgid "Space used by ScummVM's saved games on this storage"
msgstr ""
-"Von ScummVM-Spielstфnden beleger Speicherplatz auf diesem Cloud-Speicher"
+"Von ScummVM-Spielstфnden belegter Speicherplatz auf diesem Cloud-Speicher"
#: gui/options.cpp:1642
msgid "Last sync time:"
@@ -1356,7 +1356,7 @@ msgstr ""
#: gui/options.cpp:1944
msgid "Select directory for GUI themes"
-msgstr "Verzeichnis fќr Oberflфchen-Themen"
+msgstr "Verzeichnis fќr Oberflфchen-Themes"
#: gui/options.cpp:1954
msgid "Select directory for extra files"
@@ -1364,7 +1364,7 @@ msgstr "Verzeichnis fќr zusфtzliche Dateien auswфhlen"
#: gui/options.cpp:1965
msgid "Select directory for plugins"
-msgstr "Verzeichnis fќr Erweiterungen auswфhlen"
+msgstr "Verzeichnis fќr Plugins auswфhlen"
#: gui/options.cpp:1977
msgid "Select directory for Files Manager /root/"
@@ -1615,7 +1615,7 @@ msgstr ""
#: gui/themebrowser.cpp:45
msgid "Select a Theme"
-msgstr "Design auswфhlen"
+msgstr "Theme auswфhlen"
#: gui/ThemeEngine.cpp:258
msgid "Disabled GFX"
@@ -1710,7 +1710,7 @@ msgstr "Spieldateien nicht gefunden"
#: common/error.cpp:42
msgid "Game id not supported"
-msgstr "Spielkennung nicht unterstќtzt"
+msgstr "Spiel-ID nicht unterstќtzt"
#: common/error.cpp:44
msgid "Unsupported color mode"
@@ -1730,7 +1730,7 @@ msgstr "Verzeichnis existiert nicht"
#: common/error.cpp:54
msgid "Path not a directory"
-msgstr "Ungќltiges Verzeichnis"
+msgstr "Pfad ist kein Verzeichnis"
#: common/error.cpp:56
msgid "Path not a file"
@@ -1767,11 +1767,11 @@ msgstr "Unbekannter Fehler"
#. I18N: Hercules is graphics card name
#: common/rendermode.cpp:35
msgid "Hercules Green"
-msgstr "Hercules Grќn"
+msgstr "Hercules-Grќn"
#: common/rendermode.cpp:36
msgid "Hercules Amber"
-msgstr "Hercules Bernstein"
+msgstr "Hercules-Bernstein"
#: common/rendermode.cpp:42
msgid "PC-9821 (256 Colors)"
@@ -1784,24 +1784,24 @@ msgstr "PC-9801 (16 Farben)"
#: common/rendermode.cpp:73
msgctxt "lowres"
msgid "Hercules Green"
-msgstr "Hercules Grќn"
+msgstr "Hercules-Grќn"
#: common/rendermode.cpp:74
msgctxt "lowres"
msgid "Hercules Amber"
-msgstr "Hercules Bernst."
+msgstr "Hercules-Bernst."
#: common/updates.cpp:58
msgid "Daily"
-msgstr "tфglich"
+msgstr "Tфglich"
#: common/updates.cpp:60
msgid "Weekly"
-msgstr "wіchentlich"
+msgstr "Wіchentlich"
#: common/updates.cpp:62
msgid "Monthly"
-msgstr "monatlich"
+msgstr "Monatlich"
#: common/updates.cpp:64
msgid "<Bad value>"
@@ -1820,11 +1820,11 @@ msgstr ""
"\n"
"Bitte teilen Sie dem ScummVM-Team unter %s die folgenden Informationen "
"zusammen mit dem Namen, der Version und der Sprache des Spiels, welches Sie "
-"hinzufuegen moechten, mit:"
+"hinzufќgen mіchten, mit:"
#: engines/advancedDetector.cpp:338
msgid "Matched game IDs:"
-msgstr "Uebereinstimmende Spiele-Kennungen:"
+msgstr "мbereinstimmende Spiele-IDs:"
#: engines/dialogs.cpp:85
msgid "~R~esume"
@@ -1862,7 +1862,7 @@ msgstr "Zur Spiele~l~iste"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1883,7 +1883,7 @@ msgstr "Speichern:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1903,7 +1903,7 @@ msgid ""
"the README for basic information, and for instructions on how to obtain "
"further assistance."
msgstr ""
-"Leider bietet diese Engine keine Spielhilfe. Bitte lesen Sie die Liesmich-"
+"Leider bietet diese Engine keine Spielhilfe. Bitte lesen Sie die LIESMICH-"
"Datei fќr grundlegende Informationen und Anweisungen zu weiterer Hilfe."
#: engines/dialogs.cpp:234 engines/pegasus/pegasus.cpp:395
@@ -2008,18 +2008,26 @@ msgstr "Trotzdem starten"
msgid "AdLib Emulator"
msgstr "AdLib-Emulator"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
-msgstr "MAME-OPL-Emulator"
+msgstr "MAME OPL-Emulator"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
-msgstr "DOSBox-OPL-Emulator"
+msgstr "DOSBox OPL-Emulator"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL-Emulator"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2071,11 +2079,11 @@ msgstr "Keine Musik"
#: audio/softsynth/appleiigs.cpp:33
msgid "Apple II GS Emulator (NOT IMPLEMENTED)"
-msgstr "Apple-II-GS-Emulator (NICHT INTEGRIERT)"
+msgstr "Apple II GS-Emulator (NICHT INTEGRIERT)"
#: audio/softsynth/cms.cpp:350
msgid "Creative Music System Emulator"
-msgstr "Creative-Music-System-Emulator"
+msgstr "Creative Music System-Emulator"
#: audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp:33
msgid "FM-Towns Audio"
@@ -2091,7 +2099,7 @@ msgstr "Initialisiere MT-32-Emulator"
#: audio/softsynth/mt32.cpp:437
msgid "MT-32 Emulator"
-msgstr "MT-32-Emulation"
+msgstr "MT-32-Emulator"
#: audio/softsynth/pcspk.cpp:139
msgid "PC Speaker Emulator"
@@ -2099,7 +2107,7 @@ msgstr "PC-Lautsprecher-Emulator"
#: audio/softsynth/pcspk.cpp:158
msgid "IBM PCjr Emulator"
-msgstr "IBM-PCjr-Emulator"
+msgstr "IBM PCjr-Emulator"
#: audio/softsynth/sid.cpp:1430
msgid "C64 Audio Emulator"
@@ -2163,19 +2171,19 @@ msgstr "Beenden"
#: backends/events/gph/gph-events.cpp:434
#: backends/events/openpandora/op-events.cpp:174
msgid "Touchscreen 'Tap Mode' - Left Click"
-msgstr "Berќhrungsbildschirm-Tipp-Modus - Linksklick"
+msgstr "Touchscreen-Tipp-Modus - Linksklick"
#: backends/events/gph/gph-events.cpp:393
#: backends/events/gph/gph-events.cpp:436
#: backends/events/openpandora/op-events.cpp:176
msgid "Touchscreen 'Tap Mode' - Right Click"
-msgstr "Berќhrungsbildschirm-Tipp-Modus - Rechtsklick"
+msgstr "Touchscreen-Tipp-Modus - Rechtsklick"
#: backends/events/gph/gph-events.cpp:395
#: backends/events/gph/gph-events.cpp:438
#: backends/events/openpandora/op-events.cpp:178
msgid "Touchscreen 'Tap Mode' - Hover (No Click)"
-msgstr "Berќhrungsbildschirm-Tipp-Modus - schweben (kein Klick)"
+msgstr "Touchscreen-Tipp-Modus - schweben (kein Klick)"
#: backends/events/gph/gph-events.cpp:415
msgid "Maximum Volume"
@@ -2203,7 +2211,7 @@ msgstr "Klicken deaktiviert"
#: backends/events/openpandora/op-events.cpp:180
msgid "Touchscreen 'Tap Mode' - Hover (DPad Clicks)"
-msgstr "Berќhrungsbildschirm-Tipp-Modus - schweben (DPad-Klicks)"
+msgstr "Touchscreen-Tipp-Modus - schweben (DPad-Klicks)"
#: backends/events/symbiansdl/symbiansdl-events.cpp:192
msgid "Do you want to quit ?"
@@ -2387,7 +2395,7 @@ msgstr "Helligkeit:"
#: backends/platform/ds/arm9/source/dsoptions.cpp:121
msgid "High quality audio (slower) (reboot)"
-msgstr "Hohe Audioqualitфt (lansamer) (erfordert Neustart)"
+msgstr "Hohe Audioqualitфt (langsamer) (erfordert Neustart)"
#: backends/platform/ds/arm9/source/dsoptions.cpp:122
msgid "Disable power off"
@@ -2814,7 +2822,7 @@ msgstr "Suche nach Aktualisierungen..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2822,7 +2830,7 @@ msgstr "Engine-Datendatei '%s' kann nicht gefunden werden."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2868,6 +2876,7 @@ msgstr "Originale Spielstand-Menќs"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Verwende die originalen Speicher- und Lade-Menќs statt der Menќs von ScummVM"
@@ -2914,13 +2923,13 @@ msgid ""
"Shows a command prompt window and pauses the game (like in SCI) instead of a "
"real-time prompt."
msgstr ""
-"Zeige eine Fenster mit einer Kommandozeile und pausiere das Spiel (wie in "
+"Zeige ein Fenster mit einer Kommandozeile und pausiere das Spiel (wie in "
"SCI) anstelle einer Eingabe in Echtzeit."
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2934,7 +2943,7 @@ msgstr "Spiel laden:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -3215,10 +3224,10 @@ msgid ""
"General MIDI ones. It is still possible that\n"
"some tracks sound incorrect."
msgstr ""
-"Sie scheinen ein General-MIDI-Gerфt zu\n"
+"Sie scheinen ein General MIDI-Gerфt zu\n"
"verwenden, aber das Spiel unterstќtzt nur\n"
"Roland MT32 MIDI. Es wird versucht, die\n"
-"Roland-MT32-Instrumente denen von\n"
+"Roland MT32-Instrumente denen von\n"
"General MIDI zuzuordnen. Es ist dennoch\n"
"mіglich, dass ein paar Musikstќcke nicht\n"
"richtig abgespielt werden."
@@ -3285,7 +3294,7 @@ msgstr "Animierte Spieloberflфche"
#: engines/mads/detection.cpp:121 engines/mads/detection.cpp:122
msgid "Naughty game mode"
-msgstr "Unanstфndiger Spiel-Modus"
+msgstr "Unanstфndiger Spielmodus"
#: engines/mohawk/detection.cpp:169
msgid "Play the Myst fly by movie"
@@ -3422,7 +3431,7 @@ msgid ""
"Can't save game in slot %i\n"
"\n"
msgstr ""
-"Kann Spiel nicht speichern auf Speicherplatz %i\n"
+"Kann Spiel nicht auf Speicherplatz %i speichern\n"
"\n"
#: engines/parallaction/saveload.cpp:194
@@ -3559,7 +3568,7 @@ msgstr "Digitale Gerфusch-Effekte bevorzugen"
#: engines/sci/detection.cpp:443
msgid "Prefer digital sound effects instead of synthesized ones"
-msgstr "Bevorzugt digitale Gerфusch-Effekte statt synthethisierter"
+msgstr "Bevorzugt digitale Gerфusch-Effekte statt synthetisierter"
#: engines/sci/detection.cpp:462
msgid "Use IMF/Yamaha FB-01 for MIDI output"
@@ -3570,7 +3579,7 @@ msgid ""
"Use an IBM Music Feature card or a Yamaha FB-01 FM synth module for MIDI "
"output"
msgstr ""
-"Verwendet eine Music-Feature-Karte von IBM oder ein Yamaha-FB-01-FM-"
+"Verwendet eine Music Feature-Karte von IBM oder ein Yamaha FB-01 FM-"
"Synthetisierungsmodul fќr die MIDI-Ausgabe"
#: engines/sci/detection.cpp:473
@@ -3739,9 +3748,9 @@ msgid ""
"to add and its version, language, etc.:\n"
msgstr ""
"Ihre Spiel-Version ist offenbar unbekannt. Wenn es sich *NICHT* um eine\n"
-"von Fans modifizierte Version (z.B. eine Fan-Uebersetzung) handelt, teilen\n"
+"von Fans modifizierte Version (z.B. eine Fan-мbersetzung) handelt, teilen\n"
"Sie bitte dem ScummVM-Team die folgenden Daten sowie den Namen des Spiels,\n"
-"welches Sie hinzufuegen wollten, dessen Version, Sprache usw. mit:\n"
+"welches Sie hinzufќgen wollten, dessen Version, Sprache usw. mit:\n"
#: engines/scumm/detection.cpp:1144
msgid ""
@@ -3807,7 +3816,7 @@ msgstr "Sie mќssen eine Bezeichnung eingeben"
#: engines/scumm/dialogs.cpp:192
msgid "The game was NOT saved (disk full?)"
-msgstr "Spiel wurde NICHT gespeichert. (Datentrфger voll?)"
+msgstr "Spiel wurde NICHT gespeichert (Datentrфger voll?)"
#: engines/scumm/dialogs.cpp:193
msgid "The game was NOT loaded"
@@ -3868,7 +3877,7 @@ msgstr "Wфhle einen Schwierigkeitsgrad."
#: engines/scumm/dialogs.cpp:657
msgid "Refer to your Loom(TM) manual for help."
-msgstr "Fќr Hilfe schauen Sie ins Loom-Handbuch."
+msgstr "Fќr Hilfe schauen Sie ins Loom(TM)-Handbuch."
#: engines/scumm/dialogs.cpp:661
msgid "Practice"
@@ -4149,7 +4158,7 @@ msgstr "spiele A auf Stab"
#: engines/scumm/help.cpp:186
msgid "play B on distaff"
-msgstr "spiele B auf Stab"
+msgstr "spiele H auf Stab"
#: engines/scumm/help.cpp:187
msgid "play C major on distaff"
@@ -4474,14 +4483,14 @@ msgstr "Bei Szenenwechseln wird ein zufфlliger Pixelќbergang verwendet"
#: engines/sherlock/detection.cpp:91
msgid "Don't show hotspots when moving mouse"
-msgstr "Bei Mausbewegung keine Klickpunkte anzeigen"
+msgstr "Bei Mausbewegung keine Hotspots anzeigen"
#: engines/sherlock/detection.cpp:92
msgid ""
"Only show hotspot names after you actually click on a hotspot or action "
"button"
msgstr ""
-"Zeigt Klickpunktnamen nur nach Klick auf selbigen oder auf einen Aktionspunkt"
+"Zeigt Hotspot-Namen nur nach Klick auf selbigen oder auf einen Aktionspunkt"
#: engines/sherlock/detection.cpp:101
msgid "Show character portraits"
@@ -4519,7 +4528,7 @@ msgstr "Vorspann der Diskettenversion"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Verwendet den Vorspann der Diskettenversion (nur bei CD-Version)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4527,7 +4536,7 @@ msgstr ""
"Falsche Version der Engine-Datendatei '%s' gefunden. %d erwartet, aber %d "
"bekommen."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4658,7 +4667,7 @@ msgstr "Schnellladen des Spielstandes #%d nicht mіglich"
#: engines/wintermute/detection.cpp:58
msgid "Show FPS-counter"
-msgstr "Zфhler fќr Bilder pro Sekunde anzeigen"
+msgstr "FPS-Zфhler anzeigen"
#: engines/wintermute/detection.cpp:59
msgid "Show the current number of frames per second in the upper left corner"
@@ -4673,11 +4682,11 @@ msgstr "Bilineare Filterung fќr Sprites (LANGSAM)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Bilineare Filterung auf einzelne Sprites anwenden"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr "Item-Kosten im Standard-Inventarmodus anzeigen"
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
@@ -4685,10 +4694,15 @@ msgstr ""
"Zeigt die Gegenstandskosten im Standard-Inventarmodus an, um einen Vergleich "
"der Gegenstфnde zu ermіglichen"
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr "Widerstandsfфhigere Rќstung"
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Verwendet die originalen Menќs zum Speichern und Laden statt der von ScummVM"
+"Rќstung zerbricht erst, wenn der Charakter -80HP besitzt und nicht bereits "
+"bei -10HP"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4724,7 +4738,7 @@ msgstr ""
"Verwende die hochauflіsendenden MPEG-Filme der DVD-Version anstelle der "
"niedriger aufgelіsten AVI-Filme"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4734,6 +4748,11 @@ msgstr ""
"Spielstфnde bis zu Version %d. Sie benіtigen eine aktualisierte Version der "
"Engine, um diesen Spielstand zu verwenden."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Verwendet die originalen Menќs zum Speichern und Laden statt der von "
+#~ "ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr ""
#~ "(Sie kіnnen diese auch jederzeit im Options-Dialog unter dem Reiter "
diff --git a/po/el.po b/po/el.po
index 73821ca0a7..84a19b5b9e 100644
--- a/po/el.po
+++ b/po/el.po
@@ -6,9 +6,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.10.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-04-28 11:12+0000\n"
-"Last-Translator: Arius <alidop@pathfinder.gr>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:19+0000\n"
+"Last-Translator: Adrian Fruehwirth <bonki@scummvm.org>\n"
"Language-Team: Greek <https://translations.scummvm.org/projects/scummvm/"
"scummvm/el/>\n"
"Language: el\n"
@@ -168,7 +168,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1867,7 +1867,7 @@ msgstr "Х№щѓ~є~ё. ѓєяэ Яфчучєо"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1888,7 +1888,7 @@ msgstr "С№яшоъхѕѓч №сщїэщфщя§:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -2014,18 +2014,26 @@ msgstr "Хъъпэчѓч я§єљђ о мыыљђ"
msgid "AdLib Emulator"
msgstr "Хюяьящљєођ Adlib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Хюяьящљєођ MAME OPL"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Хюяьящљєођ DOSBox OPL"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Хюяьящљєођ Nuked OPL"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2820,7 +2828,7 @@ msgstr "Иыхуїяђ Хэчьхёўѓхљэ..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2828,7 +2836,7 @@ msgstr "Фхэ оєсэ фѕэсєо ч х§ёхѓч єяѕ сёїхпяѕ №сщїэщфщя§ '%s'."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2874,6 +2882,7 @@ msgstr "зёоѓч сёїщъўэ яшяэўэ с№яшоъхѕѓчђ/іќёєљѓчђ"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"зёоѓч єљэ сёїщъўэ яшяэўэ с№яшоъхѕѓчђ/іќёєљѓчђ сэєп ущс сѕєнђ єяѕ ScummVM"
@@ -2926,7 +2935,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2940,7 +2949,7 @@ msgstr "Х№сэсіяём №сщїэщфщя§:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4491,7 +4500,7 @@ msgstr "Хщѓсуљуо нъфяѓчђ фщѓънєсђ"
msgid "Use the floppy version's intro (CD version only)"
msgstr "зёоѓч єчђ хщѓсуљуођ с№ќ єчэ нъфяѓч фщѓънєсђ (нъфяѓч CD ьќэя)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, fuzzy, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4499,7 +4508,7 @@ msgstr ""
"Тёншчъх ысэшсѓьнэч нъфяѓч єяѕ '%s' сёїхпяѕ №сщїэщфщя§. Сэсьхэќьхэч %d.%d "
"сыым тёншчъх ч %d.%d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, fuzzy, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "Фхэ оєсэ фѕэсєо ч х§ёхѓч єяѕ сёїхпяѕ №сщїэщфщя§ '%s'."
@@ -4644,20 +4653,23 @@ msgstr "Фщуёсььщъќ іщыєёмёщѓьс ѓєящїхпљэ (СбУЯ)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Хісёьяуо фщуёсььщъя§ іщыєёсёпѓьсєяђ ѓх ьхьяэљьнэс ѓєящїхпс"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"зёчѓщья№ящоѓєх єщђ сёїщънђ яшќэхђ с№яшоъхѕѓчђ/іќёєљѓчђ сэєп сѕєўэ єяѕ ScummVM"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4692,7 +4704,7 @@ msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr ""
"зёоѓч тпэєхя MPEG с№ќ єчэ нъфяѓч DVD сэєп ущс єя їсьчыќєхёчђ сэмыѕѓчђ AVI"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4702,6 +4714,11 @@ msgstr ""
"ѕ№яѓєчёпцхщ ьќэя ьнїёщ єчэ нъфяѓч%d. Шс їёхщсѓєхпєх ьщс хэчьхёљьнэч нъфяѓч "
"єчђ ьчїсэођ ущс эс їёчѓщья№ящоѓхєх сѕєќ єя с№яшчъхѕьнэя №сщїэпфщ."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "зёчѓщья№ящоѓєх єщђ сёїщънђ яшќэхђ с№яшоъхѕѓчђ/іќёєљѓчђ сэєп сѕєўэ єяѕ "
+#~ "ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr ""
#~ "(Ь№яёхпєх №мэєс эс єчэ хэхёуя№ящоѓхєх ѓєя №сёмшѕёя фщсыќуяѕ Х№щыяунђ ѓєчэ "
diff --git a/po/es_ES.po b/po/es_ES.po
index 7c28b7747a..b3217ba5e7 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.4.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-12-01 22:51+0000\n"
-"Last-Translator: TomasM <truido@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:10+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Spanish <https://translations.scummvm.org/projects/scummvm/"
"scummvm/es/>\n"
"Language: es_ES\n"
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "Aceptar"
@@ -1332,7 +1332,7 @@ msgstr "ЁEl Tema no soporta el lenguaje seleccionado!"
#: gui/options.cpp:1896
msgid "Theme cannot be loaded!"
-msgstr "No se ha podido cargar el tema."
+msgstr "ЁNo se ha podido cargar el tema!"
#: gui/options.cpp:1899
msgid ""
@@ -1850,7 +1850,7 @@ msgstr "~V~olver al lanzador"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1871,7 +1871,7 @@ msgstr "Guardar partida:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1993,18 +1993,26 @@ msgstr "Jugar aun asэ"
msgid "AdLib Emulator"
msgstr "Emulador de AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Emulador OPL de MAME"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Emulador OPL de DOSBox"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Emulador OPL de Nuked"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2798,7 +2806,7 @@ msgstr "Buscar actualizaciones..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2806,7 +2814,7 @@ msgstr "No se puede localizar el archivo de datos del motor '%s'."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2852,6 +2860,7 @@ msgstr "Usar pantallas de guardar/cargar originales"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr "Usar los menњs originales de guardar/cargar en vez de los de ScummVM"
@@ -2901,7 +2910,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2915,7 +2924,7 @@ msgstr "Cargar partida:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4485,7 +4494,7 @@ msgid "Use the floppy version's intro (CD version only)"
msgstr ""
"Usa la introducciѓn de la versiѓn en disquete (solo para la versiѓn CD)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, fuzzy, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4493,7 +4502,7 @@ msgstr ""
"Se ha encontrado una versiѓn incorrecta del archivo de datos del motor '%s'. "
"Se esperaba %d.%d pero se encontrѓ %d.%d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, fuzzy, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "No se puede localizar el archivo de datos del motor '%s'."
@@ -4636,20 +4645,23 @@ msgstr "Filtrado bilineal de sprites (LENTO)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Aplicar filtrado bilineal a sprites individuales"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Usar los menњs originales para guardar/cargar, en vez de los de ScummVM"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4684,7 +4696,7 @@ msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr ""
"Usar los vэdeos MPEG de la versiѓn DVD en vez de los AVI de baja resoluciѓn"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4694,6 +4706,10 @@ msgstr ""
"versiѓn %d. Serс necesaria una versiѓn atualizada del motor para poder "
"usarla."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Usar los menњs originales para guardar/cargar, en vez de los de ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr ""
#~ "(Puedes activar esta funciѓn en la pestaёa Otras del menњ de opciones)"
diff --git a/po/eu.po b/po/eu.po
index 682cf72e36..4317b8b64e 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.5.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2016-12-04 13:27+0000\n"
-"Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:12+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Basque <https://translations.scummvm.org/projects/scummvm/"
"scummvm/eu/>\n"
"Language: eu\n"
@@ -166,7 +166,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "Ados"
@@ -1837,7 +1837,7 @@ msgstr "It~z~uli abiarazlera"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1858,7 +1858,7 @@ msgstr "Gorde jokoa:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1980,18 +1980,26 @@ msgstr "Jolastu berdin-berdin"
msgid "AdLib Emulator"
msgstr "AdLib emuladorea"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL emuladorea"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emuladorea"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL emuladorea"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA FM zuzena"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2786,7 +2794,7 @@ msgstr "Eguneraketak bilatzen..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2794,7 +2802,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2840,6 +2848,7 @@ msgstr "Erabili jatorrizko gorde/kargatu pantailak"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
#, fuzzy
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
@@ -2890,7 +2899,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2904,7 +2913,7 @@ msgstr "Jokoa kargatu:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4442,13 +4451,13 @@ msgstr "Floppy introa"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Erabili floppy bertsioko sarrera (CD bertsioa soilik)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4591,20 +4600,23 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Erabili jatorrizko gorde/kargatu pantailak ScummVM interfazearenak beharrean"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4639,13 +4651,18 @@ msgstr "Erabili bereizmen altuko MPEG bideoa"
msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr "Erabili DVD bertsioko MPEG bideoa, bereizmen baxuagoko AVI-a beharrean"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
"%d. You will need an updated version of the engine to use this saved game."
msgstr ""
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Erabili jatorrizko gorde/kargatu pantailak ScummVM interfazearenak "
+#~ "beharrean"
+
#, fuzzy
#~ msgid "Check for updates automatically"
#~ msgstr "Eguneraketak bilatzen..."
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 6d8843a475..37c427d4fe 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -7,11 +7,11 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.6.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2018-03-31 12:53+0000\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-14 11:03+0000\n"
"Last-Translator: Timo Mikkolainen <tmikkola@gmail.com>\n"
-"Language-Team: Finnish "
-"<https://translations.scummvm.org/projects/scummvm/scummvm/fi/>\n"
+"Language-Team: Finnish <https://translations.scummvm.org/projects/scummvm/"
+"scummvm/fi/>\n"
"Language: fi_FI\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
@@ -168,7 +168,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1839,7 +1839,7 @@ msgstr "Palaa p~e~livalitsimeen"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1860,7 +1860,7 @@ msgstr "Tallenna peli:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1979,18 +1979,26 @@ msgstr "Pelaa silti"
msgid "AdLib Emulator"
msgstr "AdLib emulaattori"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL emulaattori"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulaattori"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL emulaattori"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2787,7 +2795,7 @@ msgstr "Tarkista pфivitykset..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2795,7 +2803,7 @@ msgstr "\"%s\" pelimoottorin datatiedostoa ei lіydetty."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2841,6 +2849,7 @@ msgstr "Kфytф alkuperфisiф tallenna/lataa valikkoja"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr "Kфytф alkuperфisiф tallenna/lataa valikkoja ScummVM valikoiden sijaan"
@@ -2889,7 +2898,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2903,7 +2912,7 @@ msgstr "Lataa pelitallenne:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4459,7 +4468,7 @@ msgstr "Levykeversion intro"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Kфytф levykeversion introa (vain CD versiossa)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4467,7 +4476,7 @@ msgstr ""
"Pelimoottorin \"%s\" datatiedostosta lіytyi vффrф versio. Odotettu versio "
"%d, lіytynyt versio %d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "Kielen %s tekstejф ei lіydetty tiedostosta '%s'."
@@ -4606,11 +4615,11 @@ msgstr "Spritejen bilineaarinen suodatus (HIDAS)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Kфytф bilineaarista suodatusta yksittфisiin spriteihin"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr "Nфytф esineiden hinnat normaalissa inventoriossa"
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
@@ -4618,14 +4627,18 @@ msgstr ""
"Nфyttфф esineiden hinnat normaalissa inventoriossa, mahdollistaen arvojen "
"vertailun"
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr "Kestфvфmmфt suojavarusteet"
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Kфytф alkuperфisiф tallenna/lataa valikkoja ScummVM kфyttіliittymфn sijaan"
+"Suojavaruste hajoaa vasta hahmon ollessa -80HP:ssф normaalin -10HP sijasta"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
-msgstr "Tupla FPS"
+msgstr "Kaksinkertaista FPS"
#: engines/zvision/detection_tables.h:62
msgid "Increase framerate from 30 to 60 FPS"
@@ -4657,7 +4670,7 @@ msgstr ""
"Kфytф DVD-version MPEG videoita matalampiresoluutioisten AVI-tiedostojen "
"sijaan"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4667,6 +4680,10 @@ msgstr ""
"vain versioon %d asti. Tarvitset pфivitetyn version tфstф pelimoottorista "
"kфyttффksesi tфtф pelitallennusta."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Kфytф alkuperфisiф tallenna/lataa valikkoja ScummVM kфyttіliittymфn sijaan"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(Voit aina laittaa sen pффlle asetusvalikon \"Muut\"-vфlilehdestф)"
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 5d7978ab2c..cd2f29062f 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.8.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2018-03-09 21:04+0000\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-08 14:32+0000\n"
"Last-Translator: Thierry Crozat <criezy@scummvm.org>\n"
"Language-Team: French <https://translations.scummvm.org/projects/scummvm/"
"scummvm/fr/>\n"
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1857,7 +1857,7 @@ msgstr "Retour au ~L~anceur"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1878,7 +1878,7 @@ msgstr "Sauvegarde :"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -2000,18 +2000,26 @@ msgstr "Je comprends"
msgid "AdLib Emulator"
msgstr "Щmulateur AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Щmulateur MAME OPL"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Щmulateur DOSBox OPL"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Щmulateur OPL Nuked"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2806,7 +2814,7 @@ msgstr "Recherche des mises р jour..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2814,7 +2822,7 @@ msgstr "Le fichier de donnщes '%s' n'a pu ъtre trouvщ."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2860,6 +2868,7 @@ msgstr "Dialogues sauvegarde/chargement d'origine"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Utiliser les dialogues sauvegarde/chargement d'origine plutєt que ceux de "
@@ -2912,7 +2921,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2926,7 +2935,7 @@ msgstr "Charger le jeu :"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4510,7 +4519,7 @@ msgstr "Intro disquette"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Utiliser l'intro de la version disquette (version CD uniquement)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4518,7 +4527,7 @@ msgstr ""
"La bonne version du fichier de donnщes '%s' n'a pu ъtre trouvщe. Version "
"attendue : %d ; version trouvщe : %d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4665,21 +4674,25 @@ msgstr "Filtrage bilinщaire des images-objets (LENT)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Applique un filtrage bilinщaire р chaque image-objet"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
-msgstr ""
+msgstr "Afficher le prix des objets dans l'inventaire en mode standard"
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
+"Affiche le prix des objets dans l'inventaire en mode standard, ce qui permet "
+"de comparer la valeur des objets"
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Utiliser les dialogues sauvegarde/chargement d'origine plutєt que ceux de "
-"ScummVM"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4715,7 +4728,7 @@ msgstr ""
"Utiliser les vidщos MPEG du DVD р la place des vidщos AVI de plus basse "
"rщsolution"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4725,6 +4738,11 @@ msgstr ""
"les versions %d ou infщrieures. Vous devez utiliser une version plus rщcente "
"de ScummVM pour pouvoir charger cette sauvegarde."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Utiliser les dialogues sauvegarde/chargement d'origine plutєt que ceux de "
+#~ "ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr ""
#~ "(Vous pouvez aussi activer cette option dans le tab 'Divers'\n"
diff --git a/po/gl_ES.po b/po/gl_ES.po
index dc885b625e..2ae1b41600 100644
--- a/po/gl_ES.po
+++ b/po/gl_ES.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.8.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-11-23 12:42+0000\n"
-"Last-Translator: Santiago G. Sanz <santiagogarciasanz@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:12+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Galician <https://translations.scummvm.org/projects/scummvm/"
"scummvm/gl/>\n"
"Language: gl_ES\n"
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "Aceptar"
@@ -1843,7 +1843,7 @@ msgstr "~V~olver ao Iniciador"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1864,7 +1864,7 @@ msgstr "Gardar partida:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1986,18 +1986,26 @@ msgstr "Iniciar de todos os xeitos"
msgid "AdLib Emulator"
msgstr "Emulador de AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Emulador de OPL de MAME"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Emulador de OPL de DOSBox"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Emulador de OPL de Nuked"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2790,7 +2798,7 @@ msgstr "Buscar actualizaciѓns..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2798,7 +2806,7 @@ msgstr "Non se puido localizar o ficheiro de datos do motor %s."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2844,6 +2852,7 @@ msgstr "Empregar pantallas orixinais de gardado e carga"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Emprega as pantallas orixinais de gardado e carga, no canto das de ScummVM."
@@ -2894,7 +2903,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2908,7 +2917,7 @@ msgstr "Restaurar xogo:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4475,7 +4484,7 @@ msgstr "Intro de disquete"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Emprega a introduciѓn da versiѓn en disquete (sѓ versiѓn en CD)."
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, fuzzy, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4483,7 +4492,7 @@ msgstr ""
"Atopouse unha versiѓn incorrecta do ficheiro de datos do motor %s. Ficheiro "
"esperado: %d.%d. Ficheiro atopado: %d.%d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, fuzzy, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "Non se puido localizar o ficheiro de datos do motor %s."
@@ -4624,21 +4633,23 @@ msgstr "Filtraxe bilineal de sprites (LENTA)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Aplica a flitraxe bilineal a cada sprite."
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Empregar as pantallas orixinais de gardado e carga, no canto da interface de "
-"ScummVM"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4673,7 +4684,7 @@ msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr ""
"Emprega o vэdeo MPEG da versiѓn en DVD, no canto do AVI de menor resoluciѓn."
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4683,6 +4694,11 @@ msgstr ""
"compatэbel atщ a versiѓn %d. Cѓmpre descargar unha versiѓn actualizada do "
"motor para empregar esta partida gardada."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Empregar as pantallas orixinais de gardado e carga, no canto da interface "
+#~ "de ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(Podes actэvalo no diсlogo de opciѓn da pestana Misc.)"
diff --git a/po/hu_HU.po b/po/hu_HU.po
index 17906dfa5f..38f7726eae 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -6,11 +6,11 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2018-03-30 18:09+0000\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-14 08:44+0000\n"
"Last-Translator: George Kormendi <grubycza@hotmail.com>\n"
-"Language-Team: Hungarian "
-"<https://translations.scummvm.org/projects/scummvm/scummvm/hu/>\n"
+"Language-Team: Hungarian <https://translations.scummvm.org/projects/scummvm/"
+"scummvm/hu/>\n"
"Language: hu_HU\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-2\n"
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1832,7 +1832,7 @@ msgstr "Visszatщrщs az indэtѓba"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1853,7 +1853,7 @@ msgstr "Jсtщk mentщse:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1975,18 +1975,26 @@ msgstr "Indэtсs эgy is"
msgid "AdLib Emulator"
msgstr "AdLib Emulсtor"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL emulсtor"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulсtor"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL emulсtor"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2775,7 +2783,7 @@ msgstr "Frissэtщsek keresщse..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2783,7 +2791,7 @@ msgstr "Nem talсlhatѓ a(z) '%s' motorhoz adat fсjl."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2829,6 +2837,7 @@ msgstr "Eredeti ment/tіlt kщpernyѕk hasznсlata"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr "Hasznсld az eredeti mentщs/betіltщs kщpernyѕt a ScummVM fщle helyett"
@@ -2878,7 +2887,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2892,7 +2901,7 @@ msgstr "Jсtщkmenet visszaсllэtсsa:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4452,7 +4461,7 @@ msgstr "Floppy intro"
msgid "Use the floppy version's intro (CD version only)"
msgstr "A floppy verziѓ intro hasznсlata (csak CD verziѓnсl)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4460,7 +4469,7 @@ msgstr ""
"Hibсs verziѓjњ '%s' motor adatfсjlt talсltam. Elvсrt %d helyett ez %d "
"talсlhatѓ."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4601,11 +4610,11 @@ msgstr "Sprite bilineсris szћrщs (LASSк)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Bilineсris szћrщs alkalmazсsa egyes sprite-okhoz"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr "Elem kіltsщgek megjelenэtщse a szokсsos leltсri mѓdban"
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
@@ -4613,9 +4622,13 @@ msgstr ""
"Az elem kіltsщgeket a szokсsos leltсri mѓdban mutatja, lehetѕvщ tщve az elem "
"щrtщkek іsszehasonlэtсsсt"
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
-msgstr "Hasznсld az eredeti mentщs/tіltщs kщpet a ScummVM felќlet helyett"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr "Tartѓsabb pсncщl"
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
+msgstr "A pсncщl nem szakad el, karakter -80 HP-nсl, hanem csak -10 HP-nсl"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4650,7 +4663,7 @@ msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr ""
"A DVD verziѓ MPEG videѓjсnak hasznсlata, a kisebb felbontсsњ AVI helyett"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4660,6 +4673,9 @@ msgstr ""
"tсmogat. Szќksщged van a motor frissэtett verziѓjсra, hogy hasznсld a "
"mentett jсtщkсllсst."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr "Hasznсld az eredeti mentщs/tіltщs kщpet a ScummVM felќlet helyett"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(Bсrmikor engedщlyezheti a beсllэtсsok ablakban az Egyщb fќlnщl)"
diff --git a/po/it_IT.po b/po/it_IT.po
index ee69b9d1b7..fa25064b0e 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2018-03-21 14:26+0000\n"
-"Last-Translator: Walter Agazzi <tag2015@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-17 12:41+0000\n"
+"Last-Translator: Paolo Bossi <pbossi86@gmail.com>\n"
"Language-Team: Italian <https://translations.scummvm.org/projects/scummvm/"
"scummvm/it/>\n"
"Language: it_IT\n"
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1849,7 +1849,7 @@ msgstr "~V~ai a elenco giochi"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1870,7 +1870,7 @@ msgstr "Salva gioco:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1993,18 +1993,26 @@ msgstr "Avvia comunque"
msgid "AdLib Emulator"
msgstr "Emulatore AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Emulatore OPL MAME"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Emulatore OPL DOSBox"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Emulatore OPL Nuked"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2797,7 +2805,7 @@ msgstr "Cerca aggiornamenti..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2805,7 +2813,7 @@ msgstr "File dati del motore '%s' non trovato."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2851,6 +2859,7 @@ msgstr "Usa schermate di salvataggio originali"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Usa le schermate originali di salvataggio e caricamento, al posto di quelle "
@@ -2902,7 +2911,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2916,7 +2925,7 @@ msgstr "Ripristina partita:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4493,7 +4502,7 @@ msgstr "Intro floppy"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Usa la versione floppy dell'intro (solo versione CD)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4501,7 +4510,7 @@ msgstr ""
"Versione del file di dati del motore '%s' non corretta. La versione "
"compatibile ш la %d ma ш stata rilevata la %d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4649,21 +4658,27 @@ msgstr "Applica filtro bilineare agli sprite (LENTO)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Applica un filtro grafico bilineare ad ogni sprite"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
-msgstr ""
+msgstr "Mostra il prezzo degli oggetti nell'inventario in modalitр standard"
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
+"Mostra il prezzo degli oggetti nell'inventario in modalitр standard, "
+"permettendo cosь di confrontare il valore degli oggetti"
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr "Armatura piљ durevole"
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Usa le schermate originali di salvataggio e caricamento, al posto di quelle "
-"di ScummVM"
+"L'armatura non si romperр finchщ il personaggio non raggiungerр -80HP, "
+"anzichщ -10HP"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4699,7 +4714,7 @@ msgstr ""
"Usa i filmati MPEG della versione DVD, anzichщ i filmati AVI a risoluzione "
"inferiore"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4709,6 +4724,11 @@ msgstr ""
"versione %d o inferiori. Procurati una motore aggiornato per usare questo "
"salvataggio."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Usa le schermate originali di salvataggio e caricamento, al posto di "
+#~ "quelle di ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr ""
#~ "(E' possibile attivarla in qualsiasi momento tramite la scheda \"Varie\" "
diff --git a/po/nb_NO.po b/po/nb_NO.po
index 8fd50dafcc..db0992e5ae 100644
--- a/po/nb_NO.po
+++ b/po/nb_NO.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2016-12-26 17:36+0000\n"
-"Last-Translator: Einar Johan Trјan Sјmхen <einarjohants@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:01+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Norwegian Bokmхl <https://translations.scummvm.org/projects/"
"scummvm/scummvm/nb_NO/>\n"
"Language: nb_NO\n"
@@ -170,7 +170,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -476,7 +476,7 @@ msgstr "Nivх:"
#: gui/fluidsynth-dialog.cpp:101
msgid "Chorus"
-msgstr ""
+msgstr "Chorus"
#: gui/fluidsynth-dialog.cpp:105
msgid "N:"
@@ -1836,7 +1836,7 @@ msgstr "~T~ilbake til oppstarter"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1857,7 +1857,7 @@ msgstr "Lagret spill:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1977,20 +1977,28 @@ msgstr "Start allikevel"
#: audio/adlib.cpp:2290
msgid "AdLib Emulator"
-msgstr "AdLib Emulator"
+msgstr "AdLib emulator"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL emulator"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulator"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL emulator"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2784,7 +2792,7 @@ msgstr "Sjekk for oppdateringer..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2792,7 +2800,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2836,6 +2844,7 @@ msgstr "Bruk originale lagre/laste-skjermer"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
#, fuzzy
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr "Bruk de originale lagre/laste-skjermene, istedenfor ScummVM-variantene"
@@ -2883,7 +2892,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2897,7 +2906,7 @@ msgstr "Gjennopprett spill:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4424,13 +4433,13 @@ msgstr "Diskett-intro"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Bruk diskettversjonens intro (Kun for CD-versjon)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4571,20 +4580,23 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Bruk de originale lagre/laste-skjermene istedenfor ScummVM-grensesnittet"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4620,13 +4632,17 @@ msgstr ""
"Bruk MPEG-video fra DVD-versjonen istedenfor AVI-versjonen med lavere "
"opplјsning"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
"%d. You will need an updated version of the engine to use this saved game."
msgstr ""
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Bruk de originale lagre/laste-skjermene istedenfor ScummVM-grensesnittet"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(Du kan alltids aktivere dette i valgdialogen i Diverse-fanen)"
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 8c8338e108..209af181af 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.9.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2018-03-08 09:03+0000\n"
-"Last-Translator: Ben Castricum <github@bencastricum.nl>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 09:57+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Dutch <https://translations.scummvm.org/projects/scummvm/"
"scummvm/nl/>\n"
"Language: nl_NL\n"
@@ -168,7 +168,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1841,7 +1841,7 @@ msgstr "S~t~artmenu"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1862,7 +1862,7 @@ msgstr "Spel opslaan:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1985,20 +1985,28 @@ msgstr "Evengoed starten"
#: audio/adlib.cpp:2290
msgid "AdLib Emulator"
-msgstr "AdLib Emulator"
+msgstr "AdLib emulator"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL emulator"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulator"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL emulator"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2793,7 +2801,7 @@ msgstr "Controleren op updates..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2801,7 +2809,7 @@ msgstr "Kon de '%s' engine data file niet vinden."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2847,6 +2855,7 @@ msgstr "Gebruik originele opslaan/laad schermen"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Gebruik de originele opslaan/laden schermen in plaats van die van ScummVM"
@@ -2899,7 +2908,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2913,7 +2922,7 @@ msgstr "Laad opgeslagen spel:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4489,7 +4498,7 @@ msgstr "Floppy intro"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Gebruik de floppy versie van de intro (alleen voor de CD versie)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
@@ -4497,7 +4506,7 @@ msgstr ""
"Verkeerde versie van de '%s' engine data file gevonden. Verwacht werd %d "
"maar vond %d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4635,21 +4644,27 @@ msgstr "Sprite bilineair filteren (langzaam)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Pas bilineair filteren toe op individuele sprites"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
-msgstr ""
+msgstr "Toon voorwerp kosten in standaard inventaris mode"
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
+"Toont kosten van voorwerpen in standaard inventaris mode, om de waarden van "
+"voorwerpen te kunnen vergelijken"
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr "Duurzamere harnas"
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Gebruik de originele opslaan/laden schermen, in plaats van die van de "
-"ScummVM interface"
+"Harnas zal niet breken voordat de personage op -80HP staat, in plaats van "
+"slechts -10HP"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4684,7 +4699,7 @@ msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr ""
"Gebruik de MPEG video van de DVD versie in plaats van de lagere resolutie AVI"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4694,6 +4709,11 @@ msgstr ""
"tot versie %d. U heeft een nieuwere versie van deze engine nodig om dit "
"opgeslagen te gebruiken."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Gebruik de originele opslaan/laden schermen, in plaats van die van de "
+#~ "ScummVM interface"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr ""
#~ "(U kunt dit altijd inschakelen in de opties dialoog van de Misc tab)"
diff --git a/po/nn_NO.po b/po/nn_NO.po
index 58177ce2ab..d2824513cd 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2016-12-18 18:23+0000\n"
-"Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:13+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Norwegian Nynorsk <https://translations.scummvm.org/projects/"
"scummvm/scummvm/nn/>\n"
"Language: nn_NO\n"
@@ -89,7 +89,7 @@ msgstr "Vel mappe med speldata"
#: gui/downloaddialog.cpp:52 gui/downloaddialog.cpp:264
msgid "From: "
-msgstr ""
+msgstr "Frх: "
#: gui/downloaddialog.cpp:53 gui/downloaddialog.cpp:265
msgid "To: "
@@ -167,7 +167,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -469,7 +469,7 @@ msgstr "Nivх:"
#: gui/fluidsynth-dialog.cpp:101
msgid "Chorus"
-msgstr ""
+msgstr "Chorus"
#: gui/fluidsynth-dialog.cpp:105
msgid "N:"
@@ -1830,7 +1830,7 @@ msgstr "Tilbake til Oppsta~r~tar"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1851,7 +1851,7 @@ msgstr "Lagra spel:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1969,20 +1969,28 @@ msgstr "Start allikevel"
#: audio/adlib.cpp:2290
msgid "AdLib Emulator"
-msgstr "AdLib Emulator"
+msgstr "AdLib emulator"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL emulator"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL emulator"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL emulator"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2775,7 +2783,7 @@ msgstr "SJх etter oppdateringar..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2783,7 +2791,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2829,6 +2837,7 @@ msgstr "Nytt opprinnelege skjermar for lagring/lasting"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
#, fuzzy
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
@@ -2876,7 +2885,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2890,7 +2899,7 @@ msgstr "Gjenopprett spel:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4384,13 +4393,13 @@ msgstr "Diskettintro"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Nytt diskettversjonens хpning (Kun CD-versjon)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4531,21 +4540,23 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Nytt opprinnelege skjermar for lagring/lasting istadenfor ScummVM "
-"grensesnittet"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4582,13 +4593,18 @@ msgstr ""
"Nytt MPEG video frх DVD-versjonen, framfor AVI-versjonen med lхgare "
"opplјysning"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
"%d. You will need an updated version of the engine to use this saved game."
msgstr ""
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Nytt opprinnelege skjermar for lagring/lasting istadenfor ScummVM "
+#~ "grensesnittet"
+
#, fuzzy
#~ msgid "Check for updates automatically"
#~ msgstr "SJх etter oppdateringar..."
diff --git a/po/pl_PL.po b/po/pl_PL.po
index 72fe57274a..8a53a0b4a0 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-01-25 12:49+0000\n"
-"Last-Translator: RafaГ Rzepecki <divided.mind@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:13+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Polish <https://translations.scummvm.org/projects/scummvm/"
"scummvm/pl/>\n"
"Language: pl_PL\n"
@@ -174,7 +174,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1842,7 +1842,7 @@ msgstr "~P~owrѓt do launchera"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1863,7 +1863,7 @@ msgstr "Zapis:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1981,18 +1981,26 @@ msgstr "WГБcz mimo tego"
msgid "AdLib Emulator"
msgstr "Emulator AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Emulator OPL MAME"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Emulator OPL DOSBox"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Emulator OPL Nuked"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "BezpoЖrednie FM Alsa"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2785,7 +2793,7 @@ msgstr "SprawdМ aktualizacjъ..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2793,7 +2801,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2839,6 +2847,7 @@ msgstr "UПyj oryginalnych ekranѓw odczytu/zapisu"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
#, fuzzy
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr "UПyj oryginalnych ekranѓw odczytu/zapisu zamiast tych ze ScummVM"
@@ -2888,7 +2897,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2902,7 +2911,7 @@ msgstr "Wznѓw grъ:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4433,13 +4442,13 @@ msgstr "Intro z wersji dyskietkowej"
msgid "Use the floppy version's intro (CD version only)"
msgstr "UПyj intra z wersji dyskietkowej (tylko dla wersji CD)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4586,19 +4595,23 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
-msgstr "UПyj oryginalnych ekranѓw odczytu/zapisu zamiast interfejsu ScummVM"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
+msgstr ""
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4633,13 +4646,16 @@ msgstr "UПyj wideo MPEG w wysokiej rozdzielczoЖci"
msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr "UПyj wideo MPEG z wersji DVD zamiast AVI niПszej rozdzielczoЖci"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
"%d. You will need an updated version of the engine to use this saved game."
msgstr ""
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr "UПyj oryginalnych ekranѓw odczytu/zapisu zamiast interfejsu ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(MoПna jБ wГБczyц pѓМniej w opcjach, w zakГadce \"RѓПne\".)"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index dd892a3d49..5c8c14aa73 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.3.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-03-03 22:26+0000\n"
-"Last-Translator: rafaelmessias <rmmartins@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:13+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Portuguese (Brazil) <https://translations.scummvm.org/"
"projects/scummvm/scummvm/pt_BR/>\n"
"Language: pt_BR\n"
@@ -171,7 +171,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -476,7 +476,7 @@ msgstr ""
#: gui/fluidsynth-dialog.cpp:101
msgid "Chorus"
-msgstr ""
+msgstr "Chorus"
#: gui/fluidsynth-dialog.cpp:105
msgid "N:"
@@ -509,7 +509,7 @@ msgstr "Outros"
#: gui/fluidsynth-dialog.cpp:141
msgid "Interpolation:"
-msgstr ""
+msgstr "Interpolaчуo:"
#: gui/fluidsynth-dialog.cpp:144
msgid "None (fastest)"
@@ -1867,7 +1867,7 @@ msgstr "~V~oltar ao menu"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1888,7 +1888,7 @@ msgstr "Salvar jogo:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -2013,18 +2013,26 @@ msgstr "Iniciar de qualquer maneira"
msgid "AdLib Emulator"
msgstr "Emulador AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Emulador MAME OPL"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Emulador DOSBox OPL"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Emulador Nuked OPL"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr ""
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2827,7 +2835,7 @@ msgstr "Procurar por Atualizaчѕes..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2835,7 +2843,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2879,6 +2887,7 @@ msgstr ""
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
@@ -2923,7 +2932,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2937,7 +2946,7 @@ msgstr "Restaurar jogo:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4473,13 +4482,13 @@ msgstr ""
msgid "Use the floppy version's intro (CD version only)"
msgstr ""
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4624,18 +4633,22 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
#: engines/zvision/detection_tables.h:61
@@ -4672,7 +4685,7 @@ msgstr "Usar vэdeos MPEG de alta resoluчуo"
msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr "Usar vэdeo MPEG da versуo em DVD em vez do AVi de resoluчуo mais baixa"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
diff --git a/po/pt_PT.po b/po/pt_PT.po
index 95ffc6babc..fc70183e1b 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.10.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-01-30 14:50+0000\n"
-"Last-Translator: Vitor Santos <vitorhgsantos90@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 14:10+0000\n"
+"Last-Translator: Fred Almeida <fred_pj@hotmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translations.scummvm.org/"
"projects/scummvm/scummvm/pt_PT/>\n"
"Language: pt_PT\n"
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -980,7 +980,7 @@ msgstr ""
#: gui/options.cpp:1109
msgid "SoundFont:"
-msgstr ""
+msgstr "SoundFont:"
#: gui/options.cpp:1109 gui/options.cpp:1111 gui/options.cpp:1112
msgid "SoundFont is supported by some audio cards, FluidSynth and Timidity"
@@ -989,11 +989,11 @@ msgstr ""
#: gui/options.cpp:1111
msgctxt "lowres"
msgid "SoundFont:"
-msgstr ""
+msgstr "SoundFont:"
#: gui/options.cpp:1117
msgid "Mixed AdLib/MIDI mode"
-msgstr ""
+msgstr "Modo misturado AdLib/MIDI"
#: gui/options.cpp:1117
msgid "Use both MIDI and AdLib sound generation"
@@ -1046,7 +1046,7 @@ msgstr ""
#: gui/options.cpp:1180 gui/options.cpp:1190
msgid "Speech"
-msgstr ""
+msgstr "Diсlogo"
#: gui/options.cpp:1181 gui/options.cpp:1191
msgid "Subtitles"
@@ -1827,7 +1827,7 @@ msgstr ""
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1848,7 +1848,7 @@ msgstr ""
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1950,18 +1950,26 @@ msgstr ""
msgid "AdLib Emulator"
msgstr ""
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr ""
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr ""
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr ""
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr ""
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr ""
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2738,7 +2746,7 @@ msgstr ""
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2746,7 +2754,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2790,6 +2798,7 @@ msgstr ""
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
@@ -2833,7 +2842,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2847,7 +2856,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4294,13 +4303,13 @@ msgstr ""
msgid "Use the floppy version's intro (CD version only)"
msgstr ""
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4423,18 +4432,22 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
#: engines/zvision/detection_tables.h:61
@@ -4469,7 +4482,7 @@ msgstr ""
msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr ""
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 4f1f1000c0..ff2f869f48 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -6,9 +6,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.8.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-11-28 17:59+0300\n"
-"Last-Translator: Ivan Lukyanov <greencis@mail.ru>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:17+0000\n"
+"Last-Translator: Adrian Fruehwirth <bonki@scummvm.org>\n"
"Language-Team: Russian <https://translations.scummvm.org/projects/scummvm/"
"scummvm/ru/>\n"
"Language: ru_RU\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Poedit 2.0.4\n"
+"X-Generator: Weblate 2.9\n"
"X-Language-name: Russian\n"
#: gui/about.cpp:94
@@ -169,7 +169,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1840,7 +1840,7 @@ msgstr "~В~ главное меню"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1861,7 +1861,7 @@ msgstr "Сохранить игру:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1984,18 +1984,26 @@ msgstr "Всё равно запустить"
msgid "AdLib Emulator"
msgstr "Эмулятор AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Эмулятор MAME OPL"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Эмулятор DOSBox OPL"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Эмулятор Nuked OPL"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "Прямой FM ALSA"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2789,7 +2797,7 @@ msgstr "Проверить обновления..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2797,7 +2805,7 @@ msgstr "Не удалось найти файл движка %s."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2841,6 +2849,7 @@ msgstr "Использовать оригинальные экраны записи/чтения игры"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Использовать оригинальные экраны чтения и сохранения игры вместо сделанных в "
@@ -2892,7 +2901,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2906,7 +2915,7 @@ msgstr "Восстановить игру:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4473,13 +4482,13 @@ msgstr "Вступление с дискет"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Использовать вступление с гибких дисков (только для CD-версии игры)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, fuzzy, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr "Неверная версия файла движка %s. Ожидается %d.%d, а найдена %d.%d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, fuzzy, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "Не удалось найти файл движка %s."
@@ -4619,21 +4628,23 @@ msgstr "Билинейная фильтрация спрайтов (медленно)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Применить билинейную фильтрацию для индивидуальных спрайтов"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Использовать оригинальные экраны записи и сохранения игры вместо сделанных в "
-"ScummVM"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4669,7 +4680,7 @@ msgstr ""
"Использовать MPEG-видео из DVD-версии вместо видео низкого разрешения в "
"формате AVI"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4679,6 +4690,11 @@ msgstr ""
"версии не выше %d. Для использования этого файла необходима свежая версия "
"движка."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Использовать оригинальные экраны записи и сохранения игры вместо "
+#~ "сделанных в ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(Вы всегда можете включить её в настройках на закладке \"Разное\")"
diff --git a/po/scummvm.pot b/po/scummvm.pot
index 60e9a14e67..1e105ec1f6 100644
--- a/po/scummvm.pot
+++ b/po/scummvm.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 2.1.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -162,7 +162,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr ""
@@ -1792,7 +1792,7 @@ msgstr ""
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1813,7 +1813,7 @@ msgstr ""
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1915,18 +1915,26 @@ msgstr ""
msgid "AdLib Emulator"
msgstr ""
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr ""
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr ""
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr ""
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr ""
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr ""
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2703,7 +2711,7 @@ msgstr ""
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2711,7 +2719,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2755,6 +2763,7 @@ msgstr ""
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
@@ -2798,7 +2807,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2812,7 +2821,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4258,13 +4267,13 @@ msgstr ""
msgid "Use the floppy version's intro (CD version only)"
msgstr ""
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4387,18 +4396,22 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
#: engines/zvision/detection_tables.h:61
@@ -4433,7 +4446,7 @@ msgstr ""
msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr ""
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
diff --git a/po/sv_SE.po b/po/sv_SE.po
index 090029627a..ea69a5dcf7 100644
--- a/po/sv_SE.po
+++ b/po/sv_SE.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.5.0svn\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-12-01 10:54+0000\n"
-"Last-Translator: hampusf <hampus.flink@gmail.com>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-14 20:40+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Swedish <https://translations.scummvm.org/projects/scummvm/"
"scummvm/sv/>\n"
"Language: sv_SE\n"
@@ -170,7 +170,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -186,7 +186,7 @@ msgstr ""
#: gui/downloaddialog.cpp:252
#, c-format
msgid "Downloaded %s %s / %s %s"
-msgstr "Laddar ner %s %s / %s %s"
+msgstr "Laddade ner %s %s / %s %s"
#: gui/downloaddialog.cpp:259
#, c-format
@@ -239,7 +239,7 @@ msgid ""
"English"
msgstr ""
"Spelets sprхk. Den hфr instфllningen omvandlar inte din spanska spelversion "
-"till en engelsk"
+"till en svensk"
#: gui/editgamedialog.cpp:152 gui/editgamedialog.cpp:166 gui/options.cpp:995
#: gui/options.cpp:1008 gui/options.cpp:1573 audio/null.cpp:41
@@ -464,7 +464,7 @@ msgstr "Rum:"
#: gui/fluidsynth-dialog.cpp:80
msgid "Damp:"
-msgstr "Dфmpa:"
+msgstr "Dфmpning:"
#: gui/fluidsynth-dialog.cpp:87
msgid "Width:"
@@ -915,7 +915,7 @@ msgstr "Korrektion av bildfіrhхllande"
#: gui/options.cpp:1024
msgid "Correct aspect ratio for 320x200 games"
-msgstr "Korrigera bildfіrhхllandet fіr 320 x 200-spel"
+msgstr "Korrigera bildfіrhхllandet fіr 320x200-spel"
#: gui/options.cpp:1032
msgid "Preferred Device:"
@@ -1557,7 +1557,7 @@ msgstr "Du kommer att fіras till ScummVM:s sida"
#: gui/storagewizarddialog.cpp:79
msgid "you should allow it to access your storage."
-msgstr "dфr du borde kunna komma хt ditt lager."
+msgstr "dфr du borde tillхta хtkomst till ditt lager."
#: gui/storagewizarddialog.cpp:112
msgid "Another Storage is active. Do you want to interrupt it?"
@@ -1840,7 +1840,7 @@ msgstr "Хte~r~vфnd till launcher"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1861,7 +1861,7 @@ msgstr "Spara spelet:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1983,18 +1983,26 @@ msgstr "Starta фndх"
msgid "AdLib Emulator"
msgstr "AdLib-emulator"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL-emulator"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "DOSBox OPL-emulator"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL-emulator"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2101,7 +2109,9 @@ msgstr ""
msgid ""
"Download complete.\n"
"Failed to download %u files."
-msgstr "Nedladdningen фr fфrdig. Kunde inte ladda ner %u filer."
+msgstr ""
+"Nedladdningen фr fфrdig.\n"
+"Kunde inte ladda ner %u filer."
#: backends/cloud/storage.cpp:330
msgid "Download complete."
@@ -2239,12 +2249,12 @@ msgstr "Korrektion av bildfіrhхllande av"
#: backends/graphics/openglsdl/openglsdl-graphics.cpp:747
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2477
msgid "Filtering enabled"
-msgstr "Filtrering aktiverat"
+msgstr "Filtrering aktiverad"
#: backends/graphics/openglsdl/openglsdl-graphics.cpp:749
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:2479
msgid "Filtering disabled"
-msgstr "Filtrering фr inaktiverat"
+msgstr "Filtrering inaktiverad"
#: backends/graphics/surfacesdl/surfacesdl-graphics.cpp:55
#: backends/graphics/wincesdl/wincesdl-graphics.cpp:88
@@ -2364,7 +2374,7 @@ msgstr "Hіg ljudkvalitet (lхngsammare) (omstart)"
#: backends/platform/ds/arm9/source/dsoptions.cpp:122
msgid "Disable power off"
-msgstr "Inaktivera strіmsparning"
+msgstr "Inaktivera strіmsparlфge"
#: backends/platform/ios7/ios7_osys_events.cpp:309
#: backends/platform/ios7/ios7_osys_events.cpp:519
@@ -2559,7 +2569,7 @@ msgstr "Lodrфt underskanning:"
#: backends/platform/wii/options.cpp:71
msgid "Input"
-msgstr "Ingхng"
+msgstr "Inmatning"
#: backends/platform/wii/options.cpp:74
msgid "GC Pad sensitivity:"
@@ -2599,7 +2609,7 @@ msgstr "Server:"
#: backends/platform/wii/options.cpp:110
msgid "Share:"
-msgstr "Delad:"
+msgstr "Utdelning:"
#: backends/platform/wii/options.cpp:118
msgid "Password:"
@@ -2786,7 +2796,7 @@ msgstr "Sіk efter uppdateringar..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2794,7 +2804,7 @@ msgstr "Kunde inte hitta spelmotorns datafil '%s'."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2840,6 +2850,7 @@ msgstr "Anvфnd originalskфrmar fіr spara/ladda"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Anvфnd originalskфrmarna fіr ladda och spara istфllet fіr ScummVM:s egna"
@@ -2854,7 +2865,7 @@ msgid ""
"behavior"
msgstr ""
"Anvфnd en alternativ fфrgkarta typisk fіr alla Amiga-spel. Det hфr фr det "
-"mala beteendet"
+"gamla beteendet"
#: engines/agi/detection.cpp:167
msgid "Mouse support"
@@ -2890,7 +2901,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2904,7 +2915,7 @@ msgstr "Ladda sparfil:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -3038,7 +3049,7 @@ msgstr "Skipp-stіd"
#: engines/kyra/detection.cpp:74
msgid "Allow text and cutscenes to be skipped"
-msgstr "Tillхter skippning av text och filmscener"
+msgstr "Tillхt skippning av text och filmscener"
#. I18N: Helium mode makes people sound like they've inhaled Helium.
#: engines/kyra/detection.cpp:84
@@ -3053,7 +3064,7 @@ msgstr "Aktivera heliumlфge"
#. changing from one screen to another.
#: engines/kyra/detection.cpp:99
msgid "Smooth scrolling"
-msgstr "Mjuk rullning"
+msgstr "Mjuk skфrmrullning"
#: engines/kyra/detection.cpp:100
msgid "Enable smooth scrolling when walking"
@@ -3526,7 +3537,7 @@ msgid ""
"Use an IBM Music Feature card or a Yamaha FB-01 FM synth module for MIDI "
"output"
msgstr ""
-"Anvфnd ett IMB Music Feature-kort eller en Yamaha FB-01 FM synthmodul fіr "
+"Anvфnd ett IBM Music Feature-kort eller en Yamaha FB-01 FM synthmodul fіr "
"MIDI-uppspelning"
#: engines/sci/detection.cpp:473
@@ -3753,7 +3764,7 @@ msgstr "Du mхste ange ett namn"
#: engines/scumm/dialogs.cpp:192
msgid "The game was NOT saved (disk full?)"
-msgstr "Spelet sprades EJ (skivan full?)"
+msgstr "Spelet sparades EJ (skivan full?)"
#: engines/scumm/dialogs.cpp:193
msgid "The game was NOT loaded"
@@ -3928,7 +3939,7 @@ msgstr "Musrestriktion av/pх"
#: engines/scumm/help.cpp:101
msgid "Switch between graphics filters"
-msgstr "Vфxla grafikfilter"
+msgstr "Vфxla mellan grafikfilter"
#: engines/scumm/help.cpp:102
msgid "Increase / Decrease scale factor"
@@ -4190,7 +4201,7 @@ msgstr "Comm"
#: engines/scumm/help.cpp:247
msgid "Save / Load / Options"
-msgstr "Spara / Ladda / Inst"
+msgstr "Spara / Ladda / Instфllningar"
#: engines/scumm/help.cpp:256
msgid "Other game controls:"
@@ -4466,18 +4477,17 @@ msgstr "Diskettintro"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Anvфnd diskettversionens intro (endast CD-version)"
-#: engines/supernova/supernova.cpp:308
-#, fuzzy, c-format
+#: engines/supernova/supernova.cpp:193
+#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-"Felaktig version av datafilen '%s' hittades. Version %d.%d krфvs, hittade %d."
-"%d."
+"Felaktig version av datafilen '%s' hittades. Version %d krфvs, hittade %d."
-#: engines/supernova/supernova.cpp:335
-#, fuzzy, c-format
+#: engines/supernova/supernova.cpp:220
+#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
-msgstr "Kunde inte hitta spelmotorns datafil '%s'."
+msgstr "Kunde inte hitta sprхk %s i spelmotorns datafil '%s'."
#: engines/sword1/animation.cpp:524
#, c-format
@@ -4609,23 +4619,29 @@ msgstr "Bilinjфr filtrering av rіrliga figurer (LХNGSAM)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Tillфmpa bilinjфr filtrering pх enskilda rіrliga figurer"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
-msgstr ""
+msgstr "Visa kostnader fіr fіremхl i standardlфge fіr inventariet"
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
+"Visar kostnader fіr fіremхl i standardlфge fіr inventariet i syfte att "
+"mіjliggіra jфmfіrbarhet mellan olika fіremхl"
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
-msgstr "Anvфnd originalskфrmarna fіr spara/ladda istфllet fіr ScummVM:s"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
+msgstr ""
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
-msgstr "Dubbel FPS"
+msgstr "Dubbla FPS"
#: engines/zvision/detection_tables.h:62
msgid "Increase framerate from 30 to 60 FPS"
@@ -4655,7 +4671,7 @@ msgstr "Anvфnd hіgupplіst MPEG-video"
msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr "Anvфnd MPEG-video frхn DVD-versionen istфllet fіr lхgupplіst AVI"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4665,6 +4681,9 @@ msgstr ""
"till version %d. Det krфvs en uppdaterad version av spelmotorn fіr att "
"anvфnda den hфr sparfilen."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr "Anvфnd originalskфrmarna fіr spara/ladda istфllet fіr ScummVM:s"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr ""
#~ "(Du kan alltid aktivera den under \"Diverse\"-fliken i instфllningarna)"
diff --git a/po/uk_UA.po b/po/uk_UA.po
index 7281cfa74b..4d63cfb738 100644
--- a/po/uk_UA.po
+++ b/po/uk_UA.po
@@ -8,9 +8,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.9.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2017-06-14 14:55+0000\n"
-"Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:18+0000\n"
+"Last-Translator: Adrian Fruehwirth <bonki@scummvm.org>\n"
"Language-Team: Ukrainian <https://translations.scummvm.org/projects/scummvm/"
"scummvm/uk/>\n"
"Language: uk_UA\n"
@@ -171,7 +171,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "OK"
@@ -1842,7 +1842,7 @@ msgstr "~П~овер.в головне меню"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1863,7 +1863,7 @@ msgstr "Зберегти гру:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1985,18 +1985,26 @@ msgstr "Все одно запустити"
msgid "AdLib Emulator"
msgstr "Емулятор AdLib"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "Емулятор MAME OPL"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
msgstr "Емулятор DOSBox OPL"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Емулятор Nuked OPL"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "Безпосередній ALSA FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2789,7 +2797,7 @@ msgstr "Перевірити оновлення..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2797,7 +2805,7 @@ msgstr "Не вдалося знайти файл даних движка %s."
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2842,6 +2850,7 @@ msgstr "Використовувати ориг. екрани збереження/завантаження"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr ""
"Використовувати оригінальні екрани збереження/завантаження замість ScummVM"
@@ -2894,7 +2903,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2908,7 +2917,7 @@ msgstr "Відновити гру:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4450,14 +4459,14 @@ msgstr "Вступ з флоппі-версії"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Використовувати введення з флоппі-версії (тільки для CD версії гри)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, fuzzy, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
"Знайдено невірну версію даних движка %s. Очікувана %d.%d, але знайдено %d.%d."
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, fuzzy, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr "Не вдалося знайти файл даних движка %s."
@@ -4594,21 +4603,23 @@ msgstr "Білінійна фільтрація спрайтів (повільно)"
msgid "Apply bilinear filtering to individual sprites"
msgstr "Застосувати білінійну фільтрацію до окремих спрайтів"
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
msgstr ""
-"Використовувати оригінальні екрани збереження/завантаження замість екранів "
-"зі ScummVM"
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4644,7 +4655,7 @@ msgstr ""
"Використовувати відео MPEG з DVD-версії замість файлів AVI з ніжчою "
"роздільною здатністю"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
@@ -4654,6 +4665,11 @@ msgstr ""
"версію до %d. Вам потрібна поновлена версія ScummVM для завантаження цього "
"файлу."
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr ""
+#~ "Використовувати оригінальні екрани збереження/завантаження замість "
+#~ "екранів зі ScummVM"
+
#~ msgid "(You can always enable it in the options dialog on the Misc tab)"
#~ msgstr "(Ви завжди можете включити її у Налаштуваннях на закладці Інше)"
diff --git a/po/zh-Latn_CN.po b/po/zh-Latn_CN.po
index 4d7eef451f..c4f7fd4395 100644
--- a/po/zh-Latn_CN.po
+++ b/po/zh-Latn_CN.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ScummVM 1.9.0git\n"
"Report-Msgid-Bugs-To: scummvm-devel@lists.scummvm.org\n"
-"POT-Creation-Date: 2018-03-30 09:53+0200\n"
-"PO-Revision-Date: 2016-12-26 19:38+0000\n"
-"Last-Translator: Eugene Sandulenko <sev@scummvm.org>\n"
+"POT-Creation-Date: 2018-04-18 20:19+0200\n"
+"PO-Revision-Date: 2018-04-18 10:18+0000\n"
+"Last-Translator: Adrian Frќhwirth <bonki@scummvm.org>\n"
"Language-Team: Chinese <https://translations.scummvm.org/projects/scummvm/"
"scummvm/zh_LATN@cn/>\n"
"Language: zh-Latn_CN\n"
@@ -166,7 +166,7 @@ msgstr ""
#: engines/sword1/control.cpp:887 engines/sword1/logic.cpp:1633
#: engines/sword2/animation.cpp:425 engines/sword2/animation.cpp:445
#: engines/sword2/animation.cpp:461 engines/sword2/animation.cpp:471
-#: engines/zvision/file/save_manager.cpp:224
+#: engines/zvision/file/save_manager.cpp:225
msgid "OK"
msgstr "Queding"
@@ -1830,7 +1830,7 @@ msgstr "~R~Fanhui Qidongqi"
#: engines/dialogs.cpp:116 engines/agi/saveload.cpp:761
#: engines/avalanche/parser.cpp:1900 engines/cge/events.cpp:72
#: engines/cge2/events.cpp:65 engines/cine/various.cpp:348
-#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:196
+#: engines/cruise/menu.cpp:212 engines/dm/loadsave.cpp:199
#: engines/drascula/saveload.cpp:383 engines/dreamweb/saveload.cpp:262
#: engines/gnap/menu.cpp:464 engines/hugo/file.cpp:298
#: engines/mads/nebular/dialogs_nebular.cpp:350 engines/mohawk/dialogs.cpp:106
@@ -1851,7 +1851,7 @@ msgstr "Baocun Youxi:"
#: engines/agi/saveload.cpp:761 engines/avalanche/parser.cpp:1900
#: engines/cge/events.cpp:72 engines/cge2/events.cpp:65
#: engines/cine/various.cpp:348 engines/cruise/menu.cpp:212
-#: engines/dm/loadsave.cpp:196 engines/drascula/saveload.cpp:383
+#: engines/dm/loadsave.cpp:199 engines/drascula/saveload.cpp:383
#: engines/dreamweb/saveload.cpp:262 engines/gnap/menu.cpp:464
#: engines/hugo/file.cpp:298 engines/mads/nebular/dialogs_nebular.cpp:350
#: engines/mohawk/dialogs.cpp:106 engines/mohawk/riven.cpp:545
@@ -1973,18 +1973,26 @@ msgstr "Qiangzhi Qidong"
msgid "AdLib Emulator"
msgstr "AdLib Moniqi"
-#: audio/fmopl.cpp:62
+#: audio/fmopl.cpp:71
msgid "MAME OPL emulator"
msgstr "MAME OPL Moniqi"
-#: audio/fmopl.cpp:64
+#: audio/fmopl.cpp:73
msgid "DOSBox OPL emulator"
-msgstr "DosBox OPL Moniqi"
+msgstr "DOSBox OPL Moniqi"
-#: audio/fmopl.cpp:67
+#: audio/fmopl.cpp:76
+msgid "Nuked OPL emulator"
+msgstr "Nuked OPL Moniqi"
+
+#: audio/fmopl.cpp:79
msgid "ALSA Direct FM"
msgstr "ALSA Direct FM"
+#: audio/fmopl.cpp:82
+msgid "OPL2LPT"
+msgstr "OPL2LPT"
+
#: audio/mididrv.cpp:209
#, c-format
msgid ""
@@ -2776,7 +2784,7 @@ msgstr "Jiancha Gengxin..."
#: engines/access/resources.cpp:44 engines/drascula/drascula.cpp:966
#: engines/hugo/hugo.cpp:437 engines/lure/lure.cpp:64
#: engines/mortevielle/mortevielle.cpp:306 engines/sky/compact.cpp:131
-#: engines/supernova/supernova.cpp:290 engines/teenagent/resources.cpp:97
+#: engines/supernova/supernova.cpp:175 engines/teenagent/resources.cpp:97
#: engines/tony/tony.cpp:198 engines/toon/toon.cpp:4918
#, c-format
msgid "Unable to locate the '%s' engine data file."
@@ -2784,7 +2792,7 @@ msgstr ""
#: engines/access/resources.cpp:52 engines/drascula/drascula.cpp:980
#: engines/hugo/hugo.cpp:448 engines/lure/lure.cpp:73
-#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:300
+#: engines/mortevielle/mortevielle.cpp:315 engines/supernova/supernova.cpp:185
#: engines/tony/tony.cpp:210 engines/toon/toon.cpp:4930
#, c-format
msgid "The '%s' engine data file is corrupt."
@@ -2830,6 +2838,7 @@ msgstr "Shiyong Yuanshi Baocun/Zairu Pingmu"
#: engines/drascula/detection.cpp:332 engines/dreamweb/detection.cpp:49
#: engines/neverhood/detection.cpp:178 engines/sci/detection.cpp:453
#: engines/sherlock/detection.cpp:72 engines/toltecs/detection.cpp:201
+#: engines/zvision/detection_tables.h:52
#, fuzzy
msgid "Use the original save/load screens instead of the ScummVM ones"
msgstr "Shiyong Yuanshi Baocun/Zairu Pingmu, Bu Shiyong ScummVM de"
@@ -2877,7 +2886,7 @@ msgstr ""
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -2891,7 +2900,7 @@ msgstr "Huifu Youxi:"
#: engines/agi/saveload.cpp:774 engines/avalanche/parser.cpp:1888
#: engines/cge/events.cpp:83 engines/cge2/events.cpp:76
#: engines/cine/various.cpp:359 engines/dm/dm.cpp:276
-#: engines/dm/loadsave.cpp:184 engines/drascula/saveload.cpp:396
+#: engines/dm/loadsave.cpp:187 engines/drascula/saveload.cpp:396
#: engines/dreamweb/saveload.cpp:170 engines/gnap/menu.cpp:473
#: engines/hugo/file.cpp:400 engines/mads/nebular/dialogs_nebular.cpp:377
#: engines/neverhood/menumodule.cpp:893
@@ -4416,13 +4425,13 @@ msgstr "Ruanpan Jieshao"
msgid "Use the floppy version's intro (CD version only)"
msgstr "Shiyong Ruanpan Banben JIeshao (jin CD banben)"
-#: engines/supernova/supernova.cpp:308
+#: engines/supernova/supernova.cpp:193
#, c-format
msgid ""
"Incorrect version of the '%s' engine data file found. Expected %d but got %d."
msgstr ""
-#: engines/supernova/supernova.cpp:335
+#: engines/supernova/supernova.cpp:220
#, c-format
msgid "Unable to locate the text for %s language in '%s' engine data file."
msgstr ""
@@ -4560,19 +4569,23 @@ msgstr ""
msgid "Apply bilinear filtering to individual sprites"
msgstr ""
-#: engines/xeen/detection.cpp:84
+#: engines/xeen/detection.cpp:85
msgid "Show item costs in standard inventory mode"
msgstr ""
-#: engines/xeen/detection.cpp:85
+#: engines/xeen/detection.cpp:86
msgid ""
"Shows item costs in standard inventory mode, allowing the value of items to "
"be compared"
msgstr ""
-#: engines/zvision/detection_tables.h:52
-msgid "Use the original save/load screens instead of the ScummVM interface"
-msgstr "Shiyong Yuanshi baocun/zairu Pingmu Erfei ScummVM jiemian"
+#: engines/xeen/detection.cpp:95
+msgid "More durable armor"
+msgstr ""
+
+#: engines/xeen/detection.cpp:96
+msgid "Armor won't break until character is at -80HP, rather than merely -10HP"
+msgstr ""
#: engines/zvision/detection_tables.h:61
msgid "Double FPS"
@@ -4607,13 +4620,16 @@ msgstr "Shiyong Gaofenbianlv MPEG shipin"
msgid "Use MPEG video from the DVD version instead of lower resolution AVI"
msgstr "Cong DVD Banben Zhong shiyong MPEG shipin, erfei Difenbianlv AVI"
-#: engines/zvision/file/save_manager.cpp:220
+#: engines/zvision/file/save_manager.cpp:221
#, c-format
msgid ""
"This saved game uses version %u, but this engine only supports up to version "
"%d. You will need an updated version of the engine to use this saved game."
msgstr ""
+#~ msgid "Use the original save/load screens instead of the ScummVM interface"
+#~ msgstr "Shiyong Yuanshi baocun/zairu Pingmu Erfei ScummVM jiemian"
+
#, fuzzy
#~ msgid "Check for updates automatically"
#~ msgstr "Jiancha Gengxin..."
diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp
index fbf75b48ee..6fca2c11c8 100644
--- a/video/bink_decoder.cpp
+++ b/video/bink_decoder.cpp
@@ -559,7 +559,7 @@ void BinkDecoder::BinkVideoTrack::mergeHuffmanSymbols(VideoFrame &video, byte *d
}
void BinkDecoder::BinkVideoTrack::initBundles() {
- uint32 bw = (_surface.w + 7) >> 3;
+ uint32 bw = (_surface.w + 7) >> 3;
uint32 bh = (_surface.h + 7) >> 3;
uint32 blocks = bw * bh;